AddObjectToAsset [u3d-api]

本文介绍了一种在Unity中管理嵌套ScriptableObject的方法,解决了场景切换导致资源丢失的问题,并提供了对象本地记录及避免重复性的解决方案。

正如果标题所示,本文的思路异常简单,就是应用这个方法,已表达官方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);
 } 
}
 }




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值