Asset Storeの為のUnity拡張入門

Preview:

Citation preview

Asset Storeに出す為のUnity拡張入門

Tech Buzz Unity勉強会(2013/01/31)

三上 浩平

自己紹介• 三上 浩平(@mi_kami)

• 自分のWebサイト(MK Games) : http://mkgames.me

• 会社ではeclipseのツール開発(エディタプラグイン開発)をしています

• 家でUnity使って個人でゲームを作っています

Flockey THE 破壊(Unity製) SimpleData

ギークハウス武蔵小杉

• 神奈川県川崎市にあるシェアハウスに住んでイベント開いてます

• Unity勉強会 in ギークハウス武蔵小杉(第2回 : 2/17)

• http://atnd.org/events/36103 

• ミニ四駆のコース借りて走らせるイベント(2月予定)

global game jam 2013

• global game jam 2013の会場を主催しました

• 参加者は僕を含めて8名(2チーム)

ワンコとおさんぽ

• 僕のチームがggj2013作ったゲーム

• 犬との愛情度を深めていく• GPSを使っていて、実際に歩いて自分の心臓を動かして親密度を上げる

• http://globalgamejam.org/2013/ワンコとおさんぽ

1 Min Life

• もう1つのチームのggj2013作品(おすすめ)

• マウスクリックで主人公の血液を循環させていくゲーム

• http://globalgamejam.org/2013/1minlife

Unityを拡張しよう!

何故Unityの拡張をするのか?

• ほとんどの人は開発環境に合わせて自分を対応させている• PositionやRotationの値を手でコピー

• 1つのPrefabから複数のGameObjectを作るのをドラッグ&ドロップ or 何回もコピペ

• 開発環境を自分に対応させよう• PositionやRotationをコピーするスクリプトを書く

• Prefabから複数のGameObjectを並べるスクリプトを書く

複数人でゲームを作る為のUnity拡張

• 例: カードゲームを作るエディタが欲しい

• ルールを変更する為のエディタ• カードのバランスを調整する為のエディタ

• プログラマは変更する為の仕組みを提供する

• 規模が大きくなると、作りたいゲームに合わせて自身でツール(Editor)も開発する必要がある

本日の発表で伝えたい事

• 自分が何に困っていて、他の人をどう便利にできるか考えよう

• まずは自分が困っていることを簡単なUnityの拡張で解決して、それをより良くしてAsset Storeに申請してみよう

• そのために必要なUnity拡張の基本

今日の目次

1.自分用にUnityを拡張する

2. UnityのEditorを拡張する

3.高機能なEditorを作ってみる

4. AssetStoreの申請

僕の作ったUnity拡張例(SimpleData)

• クラス図を描いてコードを生成する• Unity版Core Dataみたいなもの

• Managerクラスへの参照を設定した状態でGameObjectを生成したり... (予定)

第1章自分用にUnityを拡張する

簡単なスクリプトを書こう

• よく使う操作をスクリプトに書いて、いつでも呼び出せるようにしてみる

• GameObjectを別のGameObjectの位置に移動

• GameObjectのPositionを(0, 0, 0)に移動する

• 複数のGameObjectをまとめて配置する...etc

• メニューに追加することでいつでも呼び出し可能(ショートカットも設定できる)

• Editorフォルダ配下にスクリプトを配置する

拡張可能なメニューの一覧

1. メインメニュー

2. HierarchyビューのCreateボタン

4. ProjectビューのCreateボタン

3. Inspectorのスクリプトの設定メニュー

メインメニューを拡張する

[MenuItem ("MyTools/Edit/LineUp %g")]static void CreateWizard (){ Object obj = Selection.activeObject; if(PrefabUtility.GetPrefabType(obj) == PrefabType.Prefab) { .... }}

1. MenuItem属性を追加する 2. ショートカットは”%(文字)”

それ以外のメニュー拡張方法

• HierarchyビューのCreateメニュー

• [MenuItem “GameObject/Create Other/...”]にメニューを追加すると反映される

• Inspectorビューの設定メニュー

• MonoBehaviourを継承したクラスに[Context Menu “Do Something”]属性を追加

• ProjectビューのCreateメニュー

• [MenuItem “Assets/Create/...”]にメニューを追加すると反映される

選択要素を取得する

• Selectionクラスを使う

• 単数選択の場合はactiveObject、複数選択はobjectsを使う

• Unity上で選択されたオブジェクトなら、なんでも取得可能

• GameObject / Prefab / スクリプト / 画像...

• すべてObject型として取得されるので、is演算子を使って型をチェックする

オブジェクトの選択

GameObjectの状態を変更する

• Selection.gameObjectsを使うと、選択されているGameObjectだけを取得出来る

• ゲーム内と同じように、transformの値を変更したりコンポーネントの追加/削除ができる

[MenuItem ("MyTools/Edit/Position/Move To (0,0,0) %u")]public static void Clear() { Vector3 v = new Vector3(0, 0, 0); GameObject[] objs = Selection.gameObjects; foreach(GameObject go in objs) { ((GameObject)go).transform.position = v; }}

PrefabからGameObjectを作る

• PrefabからGameObjectを生成したい

• Selection.activeObjectの型をチェックして、Prefabであればそれを生成すれば良い(?)

• Prefab自体を表すクラスは存在しない為、ただのObjectとしてしか扱えない

• PrefabUtilityを使おう!

PrefabUtilityでPrefabをチェック

• Prefabの新規作成・置換・接続の切断などのPrefab関連の関数をまとめたクラス

• PrefabUtility.GetPrefabType()関数で取得したPrefabTypeをチェックする

• ゲームを作る際と同様、Instantiate(prefab)関数を使ってGameObjectとしてシーンに配置

[MenuItem ("MyTools/Edit/CreateObject %g")]static void CreateObject (){ Object obj = Selection.activeObject; if (PrefabUtility.GetPrefabType (obj) == PrefabType.Prefab) { GameObject go = (GameObject) Instantiate(selectedPrefab); go.transform.position = new Vector3(0, 0, 0); }}

第2章UnityのEditorを拡張する

最初のEditorを実装する

• ユーザーは自由にEditorに対してGUIパーツを配置したり、描画できる

• EditorWindowを継承したクラスを作る

• Init()でEditorWindow.GetWindow()を呼ぶ

public class TestWindow : EditorWindow{ [MenuItem ("Window/Test Window %v")] static void Init () { TestWindow window = (TestWindow)EditorWindow.GetWindow (typeof(TestWindow)); }}

EditorWindowの重要な関数

• public void OnSelectionChange()

• ProjectビューやHierarchyビューで要素が選択された時に呼ばれる

• public void OnGUI()

• 描画のタイミングで呼ばれる• ユーザからの入力/各種描画処理

Editor上にGUIパーツを配置する

• GUIを配置する為の3つのクラス

• GUI : 好きな座標・大きさで配置可能なUI

• GUILayout : 自動でレイアウトされるUI

• EditorGUILayout : Editor用のラベルとセットになったUI(Inspectorで主に使用される)

GUILayout GUI EditorGUILayout

GUIの実装方法

• EditorGUILayout.TextField(“Object Name”, variable);

• 返却値を変数に格納• その変数をTextFieldの引数として渡す

• 他のGUIの実装方法も同様public class TestWindow : EditorWindow{ public string hoge; static void OnGUI () { hoge = EditorGUILayout.TextField(“Object Name”, hoge); }}

Editor上のキー入力の実装

• ショートカット等を作るだけでEditorがより使いやすくなる

• Projectビューのように、上下キーでのカーソル移動などを実装する場合にも使用する

• OnGUI()でキー入力イベントを処理する

• Event.current.keyCodeで入力されたキーを取得可能

マウス入力の実装

• OnGUI()でマウスイベントを処理する

• Event.current.mousePositionで座標を取得

• Event.current.typeでイベントの種類を取得

• EventType.ContextClick : 右クリック

• EventType.MouseDown : 左クリック

第3章高機能なEditorを作ってみる

こんなEditorを作ってみる

1. 矩形の描画

2. 矢印の描画

3. テクスチャの描画

4. データの保持5. Undo/Redo

Asset例 : CutScene Editor

タイムラインエディタも矩形の描画の連続で実装されている

矩形の描画

• OnGUI()でGUI.Box関数を呼ぶ

• GUI.Box(new Rect(px, py, width, height), " ");

• リサイズ可能とする場合、シリアライズ可能な値を使用するなどして外部から変更できるようにする

• 背景色を変更する場合、GUI.Boxを実行する前にGUI.colorの値を変更する

• 描画する矩形の前後関係はListや配列に格納されている順番を変更する

テクスチャの張り方

• OnGUI()内でGUI.DrawTexture

(new Rect (px, py, width, height), texTriangle);を呼ぶ

• SimpleDataの各種UIもこのDrawTextureを使用している

線の描画

• 実は線の描画もテクスチャの描画

• GUI.DrawLineは無い

• 一本線を引いたテクスチャを回転させ、座標を計算して引き延ばす

• 矢印は矩形との交点を計算して、回転させて適切な位置に描画

SimpleDataのデータ

• スクリプトでシリアライズされるデータを設計情報として使用する

• 描画されている矩形/矢印/文字はすべてこの情報を使用する

シリアライズとは

• シリアライズ = 永続化(データが保存される)

• UnityのInspector上で編集出来る値は、すべてシリアライズ可能な値

• Sceneに追加されたGameObjectの値は.sceneファイルに、Prefabの値は対応する.prefabファイルに保存される

シリアライズする

• シリアライズする2種類の方法1. MonoBehaviourを継承したクラスで、public変数を追加する

2. 通常のクラスに[System.Serializable]属性追加し、public変数を追加する

• SimpleDataでは、上記の2の方法を使って必要な情報が1つのPrefabに収まるようにした

Undoクラス

• Asset Storeに出す場合、正しくUndoできないと審査に通らない

• コード上でオブジェクトの値を変更する場合、Undo/Redoを自分で考慮する必要がある

• 一番簡単な方法はRegisterUndoを使うこと

• その関数内での変更をまとめて1回でUndo可[MenuItem ("Edit/Transform/Same Position %#x")]static void Same (){    Transform act = Selection.activeTransform;    foreach (Transform t in Selection.transforms) {            Undo.RegisterUndo (t, act.name + " same position");        t.position = act.position;    }    Debug.Log (" move to " + act);}

複数回の関数呼び出しを跨ぐ変更

• 矩形をドラッグ&ドロップする場合等に使う

• Undo.SetSnapShotTargetでオブジェクトをUndoの対象とする

• Undo.CreateSnapShotでスナップショットを作成する(変更の開始)

• Undo.RestoreSnapShotでCreateSnapShotの時点の状態に戻す(キャンセル処理)

• Undo.RegisterSnapshotでスナップショットをUndoバッファに登録する(変更の確定)

第4章AssetStoreの申請

Asset Storeの申請

• Asset StoreからAsset Store ToolsをDL

• Asset Storeに掲載する情報の記載+ロゴ画像等を登録してSubmit

• 審査に通ればAsset Storeに出る(らしい)

Recommended