テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

Inspectorを手軽にスッキリさせる

Unityはコンポーネント同士の接続を自動もしくは手動で行う事になると思う。

それが自動で行う場合はソースコードで行う形になると思う。FindやSingletonを駆使してオブジェクト同士のカップリングを作り形だ。しかし正直面倒臭い時がある。インスタンス複数あったら探すのは面倒だし、初期化のタイミングで上手く動かなかったりする。

そこで手動でカカっと接続してしまうと手軽でラクチンなのだが、もう一つ問題が出てくる。Inspectorが汚くなるのだ。

もちろん一人で触る場合は概ね問題はない。しかし他人がプレハブを触る場合、どこを触って良いか迷ってしまうと思う。特に「プレハブ作りデザイナーも巻き込んでみんなで作る」スタンスでやる場合は危険だ。そして、一週間前の自分は他人ということも忘れてはならない。

「一週間前の自分に質問したいぞ・・・」は名台詞



■SerializableAttribute

Inspectorのプロパティを隠蔽する方法としては、System.SerializableとScriptableObjectがある。ただScriptableObjectは使い方が今ひとつわからないので(便利とは思えない)、ScriptableObjectを紹介。

スクリーンショット 2012-11-26 23.54.13

[Unity][Unity3d]C#で構造体をInspectorで使える様にする方法(強火で進め)
http://d.hatena.ne.jp/nakamura001/20110805/1312563959

使い方は非常に簡単で、使っているプロパティを別クラスに分割し、クラスの頭に[System.SerializableAttribute]を書くだけ。具体的にはこんな感じ。

public class Test : MonoBehaviour {
[SerializeField] int speed = 4;
[SerializeField] int hp = 30;

public GameObject objectA;
public GameObject objectB;
public GameObject objectC;
public GameObject objectD;
public GameObject objectE;
public GameObject objectF;
}
public class Test : MonoBehaviour {
[SerializeField] int speed = 4;
[SerializeField] int hp = 30;
[SerializeField] Param param;

[System.SerializableAttribute]
class Param
{

public GameObject objectA;
public GameObject objectB;
public GameObject objectC;
public GameObject objectD;
public GameObject objectE;
public GameObject objectF;
}
}

クラスの中でクラスを宣言しているのは、単純に名前が被らないようにしている為。参照できる場所で記述しているなら呼び出せるし、こいつはmonoBehaviourを継承していないのでnamespaceだって使える。



■SerializableAttributeのコンストラクタ

蛇足だが、SerializableAttributeの動作について。
というか、Inspectorの動作。

こいつは処理が始まる際にインスタンスを勝手に生成するらしく、引数無しのコンストラクタを呼んでくれる。
ただこの呼ぶタイミングが微妙に曲者で、「ビルド完了時」や「シーン実行時」「シーン終了時」と何かと呼び出してくれる。

もしクラスに初期化が必要な場合、SerializableAttributeを設定したクラスにコンストラクタに処理を書くのを止めて、Init等の初期化メソッドを設定したほうが良さそうな気がする。



これを使うよりも別のコンポーネントに分けてしまったほうが使い勝手が良い場合もあるので、そこはケースバイケースで。