読者です 読者をやめる 読者になる 読者になる

n-yoda's blog

主にUnity3Dに関するあんまり技術的じゃないメモ的な何かを書いています。

UnityのObjectの中身をいろいろ見てみる(SerializedObjectとSerializedProperty)

SerializedObjectEditor.cs

中身を見てみる、と言うのは語弊があるかもしれませんが、 Unityのアセットは基本的に、SerializedObjectSerializedPropertyを通して何がどのようにシリアライズされているかを確認することが出来るようです。

そこで、選択中のオブジェクトとそのAssetImporterからSerializedObjectを生成して中身を全て列挙して編集するエディタスクリプトを書いてみました。

https://gist.github.com/n-yoda/9712492

Pro版を持っている人は、「Editor Settings/Asset Serialization/Force Text」 を設定すればアセットが全てYAMLになるのでこんなことをする必要は全く無いんですが・・・。

例えばシーンファイルも、開かなくても以下のように中身を確認することが出来ます。 (ただ、SerializedObject Editorで表示しているシーンを開こうとするとエラーが出るので、注意が必要。)

f:id:yoda_n:20140323041520p:plain

SerializedObjectの使い方

全てのプロパティにアクセスしてみる

UnityEngine.ObjectでSerializedObjectを初期化後、 GetIterator()イテレーターを取得し、Next(true)イテレーターを回すことで 子も含めて順々にPropertyにアクセスすることが出来ます。

var so = new SerializedObject(someObject);
var sp = so.GetIterator();
// 最初にNext(true)をする
while (sp.Next(true))
{
    switch (sp.propertyType)
    {
        case SerializedPropertyType.Integer:
            // TODO
            break;
        case SerializedPropertyType.Float:
            // TODO
            break;
        // ....
    }
}

Nextの引数でイテレーションで子に潜るかどうかが変わります。

f:id:yoda_n:20140323045255p:plain

特定のプロパティにアクセス

SerializedObject so = new SerializedObject(someObject);
SerializedProperty sp = so.FindProperty("hoge.foo.a");

SerializedProperty.FindPropertyRelativeはちょっとよくわからない。

SerializedPropertyの子を列挙

SerializedProperty.GetEndPropertySerializedProperty.EqualContentsを使って、以下のようにします。 https://gist.github.com/n-yoda/9712492#file-serializedobjecteditor-cs-L158

何でこんなことをしているかというと

UnityEditor.AnimationUtilityでAnimationCurveをGetしてSetしたらもとのアニメーションよりキーフレームが何倍にも増えてしまって意味がわからなかったから、また、そもそもAnimationUtilityが使いにくいから直接SerializedObjectで操作した方が簡単そうだったから、という理由でAnimationClipをSerializedObjectでいじったのがきっかけです。