正如果標題所示,本文的思路異常簡單,就是應用這個方法,已表達官方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);
}
}
}