AddObjectToAsset [u3d-api]

正如果標題所示,本文的思路異常簡單,就是應用這個方法,已表達官方api學習重要性.

在不會這個方法的時候,想要在一個ScriptObject中嵌套一個ScriptObject,結果場景一切換,資源就不見了.原來內嵌的那個ScriptObject實際上記錄在場景中.而這個方法就實際上就可以在一個Object中嵌套其他Object.下面詳細說明

一.在初始化時創建的資源會隨場景關閉而丟失

public class Obj : ScriptableObject {
    public int b;
}
[CreateAssetMenu(menuName = "create/rootObj")]
public class RootObj : ScriptableObject
{
    public ScriptableObject obj;

    private void OnEnable()
    {
        if(obj == null)
        {
            obj = CreateInstance<Obj>();
        }
    }
}
如以上兩ScriptObject所展示的demo一個,初始化的時候就不會有一個正常的obj,顯示如下:

如果利用編輯器擴展方法重繪製:

            EditorGUILayout.ObjectField(mo.obj, mo.obj.GetType(), true); 
原來這個對象還在,只不過是場景中的對象而已!

二.利用標題所示方法實現對象本地記錄


 public RootObj root;
    private void OnEnable()
    {
        root = target as RootObj;
    }
    public override void OnInspectorGUI()
    {
        if (root.obj == null)
        {
            root.obj = ScriptableObject.CreateInstance<Obj>();
            UnityEditor.AssetDatabase.AddObjectToAsset(root.obj, root);

            EditorUtility.SetDirty(root);

            Debug.Log(UnityEditor.AssetDatabase.GetAssetPath(root.obj));
            Debug.Log(UnityEditor.EditorUtility.IsPersistent(root.obj));
        }
        else
        {
            EditorGUILayout.ObjectField("Obj:", root.obj, root.obj.GetType(), false);
        }
    }
此時會在初始化的時候將對象記錄到本地,也就是會讓以下方法的返回值爲true,從而和場景沒有關係

UnityEditor.EditorUtility.IsPersistent()

三.關於重複性的解決方法

    已經可以向一個Object附加Object了,但需要注意的的,直接看不到這些SubObject,所以在添加的時候最好要清空一些用不到的對象,防止資源會變的大而無用,可以參照如下方法

  /// <summary>
        /// Adds the specified hidden subAssets to the mainAsset
        /// </summary>
        public static void SetSubAssets(ScriptableObject[] subAssets, ScriptableObject mainAsset)
        {
            var path = AssetDatabase.GetAssetPath(mainAsset);
            var oldAssets = AssetDatabase.LoadAllAssetsAtPath(path);

            foreach (ScriptableObject subAsset in subAssets)
            {
                if (subAsset == mainAsset) continue;

                if (System.Array.Find(oldAssets, x => x == subAsset) == null)
                {

             UnityEditor.AssetDatabase.AddObjectToAsset(subAsset, mainAsset);
          }

}
 foreach (var item in oldAssets) {
 if (item == mainAsset) continue; 
if(System.Array.Find(subAssets,x=>x==item) == null)
 { 
Object.DestroyImmediate(item, true);
 } 
}
 }




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章