Asset Storeの為のUnity拡張入門

42
Asset Storeに出す為 Unity拡張入門 Tech Buzz Unity勉強会(2013/01/31) 三上 浩平

Transcript of Asset Storeの為のUnity拡張入門

Page 1: Asset Storeの為のUnity拡張入門

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

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

三上 浩平

Page 2: Asset Storeの為のUnity拡張入門

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

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

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

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

Flockey THE 破壊(Unity製) SimpleData

Page 3: Asset Storeの為のUnity拡張入門

ギークハウス武蔵小杉

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

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

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

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

Page 4: Asset Storeの為のUnity拡張入門

global game jam 2013

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

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

Page 5: Asset Storeの為のUnity拡張入門

ワンコとおさんぽ

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

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

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

Page 6: Asset Storeの為のUnity拡張入門

1 Min Life

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

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

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

Page 7: Asset Storeの為のUnity拡張入門

Unityを拡張しよう!

Page 8: Asset Storeの為のUnity拡張入門

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

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

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

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

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

Page 9: Asset Storeの為のUnity拡張入門

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

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

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

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

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

Page 10: Asset Storeの為のUnity拡張入門

本日の発表で伝えたい事

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

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

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

Page 11: Asset Storeの為のUnity拡張入門

今日の目次

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

2. UnityのEditorを拡張する

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

4. AssetStoreの申請

Page 12: Asset Storeの為のUnity拡張入門

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

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

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

Page 13: Asset Storeの為のUnity拡張入門

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

Page 14: Asset Storeの為のUnity拡張入門

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

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

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

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

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

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

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

Page 15: Asset Storeの為のUnity拡張入門

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

1. メインメニュー

2. HierarchyビューのCreateボタン

4. ProjectビューのCreateボタン

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

Page 16: Asset Storeの為のUnity拡張入門

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

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

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

Page 17: Asset Storeの為のUnity拡張入門

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

• HierarchyビューのCreateメニュー

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

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

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

• ProjectビューのCreateメニュー

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

Page 18: Asset Storeの為のUnity拡張入門

選択要素を取得する

• Selectionクラスを使う

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

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

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

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

オブジェクトの選択

Page 19: Asset Storeの為のUnity拡張入門

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; }}

Page 20: Asset Storeの為のUnity拡張入門

PrefabからGameObjectを作る

• PrefabからGameObjectを生成したい

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

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

• PrefabUtilityを使おう!

Page 21: Asset Storeの為のUnity拡張入門

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); }}

Page 22: Asset Storeの為のUnity拡張入門

第2章UnityのEditorを拡張する

Page 23: Asset Storeの為のUnity拡張入門

最初の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)); }}

Page 24: Asset Storeの為のUnity拡張入門

EditorWindowの重要な関数

• public void OnSelectionChange()

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

• public void OnGUI()

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

Page 25: Asset Storeの為のUnity拡張入門

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

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

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

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

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

GUILayout GUI EditorGUILayout

Page 26: Asset Storeの為のUnity拡張入門

GUIの実装方法

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

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

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

Page 27: Asset Storeの為のUnity拡張入門

Editor上のキー入力の実装

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

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

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

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

Page 28: Asset Storeの為のUnity拡張入門

マウス入力の実装

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

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

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

• EventType.ContextClick : 右クリック

• EventType.MouseDown : 左クリック

Page 29: Asset Storeの為のUnity拡張入門

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

Page 30: Asset Storeの為のUnity拡張入門

こんなEditorを作ってみる

1. 矩形の描画

2. 矢印の描画

3. テクスチャの描画

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

Page 31: Asset Storeの為のUnity拡張入門

Asset例 : CutScene Editor

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

Page 32: Asset Storeの為のUnity拡張入門

矩形の描画

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

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

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

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

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

Page 33: Asset Storeの為のUnity拡張入門

テクスチャの張り方

• OnGUI()内でGUI.DrawTexture

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

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

Page 34: Asset Storeの為のUnity拡張入門

線の描画

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

• GUI.DrawLineは無い

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

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

Page 35: Asset Storeの為のUnity拡張入門

SimpleDataのデータ

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

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

Page 36: Asset Storeの為のUnity拡張入門

シリアライズとは

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

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

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

Page 37: Asset Storeの為のUnity拡張入門

シリアライズする

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

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

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

Page 38: Asset Storeの為のUnity拡張入門

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);}

Page 39: Asset Storeの為のUnity拡張入門

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

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

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

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

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

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

Page 40: Asset Storeの為のUnity拡張入門

第4章AssetStoreの申請

Page 42: Asset Storeの為のUnity拡張入門

Asset Storeの申請

• Asset StoreからAsset Store ToolsをDL

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

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