Unity 3D 编辑器模式下 资源的加载与优化

注意,编辑器模式下可使用的大量代码在运行时无法使用。

//--加载资源

在编辑器模式下,Unity提供了一个标志性的类AssetDatabase,它专门负责读取工程内的资源。

必须保证资源放在项目的Assets目录下,不然AssetDatabase是无法读取的,只能使用File类或者第三方工具类来读取。

using UnityEditor;
using UnityEngine;

public class EditorModeAssetLoadMyTools
{
    [MenuItem("Assets/My Tools/Load", false)]
    static void MyLoad()
    {
        if (Selection.activeTransform)
        {
            GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/MyCube.prefab");
            GameObject go = Object.Instantiate(prefab);
            go.transform.SetParent(Selection.activeTransform);
        }
    }
}

 提供一个Assets内的相对路径,使用AssetDatabase.LoadAssetAtPath()方法即可读取任意对象。

MyCube预制体被实例化到Root节点下。

可以看见它不是“蓝色”的,坐标没有归原点。

因为Object.Instantiate()只能创建新对象,这样将丢失Prefab的引用。

因为transform.SetParent()会继承世界坐标。

//--实例化Prefab

using UnityEditor;
using UnityEngine;

public class EditorModePrefabUtilityMyTools
{
    [MenuItem("Assets/My Tools/LoadPrefab", false)]
    static void MyLoadPrefab()
    {
        if (Selection.activeTransform)
        {
            GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/MyCube.prefab");
            GameObject go = PrefabUtility.InstantiatePrefab(prefab) as GameObject;
            go.transform.SetParent(Selection.activeTransform, false);
        }
    }
}

“蓝色” 

坐标归原点。 

在编辑器模式下,实例化Prefab需要使用PrefabUtility.InstantiatePrefab()方法。实例化的Prefab是“蓝色”的。

除了Prefab以外,FBX也属于一种特殊的引用关系的资源,也可以使用这种方法实例化,也会保持它的一些引用关系。

transform.SetParent()第二个参数传false表示不被它的父坐标影响,就会归远点。

//--创建Prefab

using UnityEditor;
using UnityEngine;

public class EditorModeCreatePrefabMyTools
{
    [MenuItem("Assets/My Tools/Create Prefab", false)]
    static void MyCreatePrefab()
    {
        if (Selection.activeTransform)
        {
            string path = "Assets/Prefab.prefab";
            if (AssetDatabase.LoadAssetAtPath<GameObject>(path))
            {
                AssetDatabase.DeleteAsset(path);
            }

            PrefabUtility.CreatePrefab(path, Selection.activeGameObject, ReplacePrefabOptions.ConnectToPrefab);

            AssetDatabase.Refresh();
        }
    }
}

PrefabUtility.CreatePrefab()方法可以创建Prefab,此时需要提供保存的目录以及当前的游戏对象。

ReplacePrefabOptions.ConnectToPrefab表示创建Prefab的同时自动关联创建它的这个游戏对象。

//--更新/保存Prefab

using UnityEditor;
using UnityEngine;

public class EditorModeApplyPrefabMyTools
{
    [MenuItem("Assets/My Tools/Apply Prefab", false)]
    static void MyApplyPrefab()
    {
        if (Selection.activeTransform)
        {
            Object prefab = PrefabUtility.GetCorrespondingObjectFromSource(Selection.activeGameObject);
            if (prefab)
            {
                PrefabUtility.ReplacePrefab(Selection.activeGameObject, prefab, ReplacePrefabOptions.ConnectToPrefab);
            }
            AssetDatabase.Refresh();
        }
    }
}

注意,要选中预制体的根节点。(要是选中子节点,子节点会代替整个预制体)。

//--卸载资源

using UnityEditor;
using UnityEngine;

public class EditorModeDeleteMyTools
{
    [MenuItem("Assets/My Tools/Delete", false)]
    static void MyDelete()
    {
        if (Selection.activeTransform)
        {
            Object.DestroyImmediate(Selection.activeGameObject, true);
        }
    }
}

在编辑器模式下只能使用Object.DestroyImmediate()方法来卸载游戏对象。

如果要卸载游戏对象引用的资源,第二个参数用true,默认是false。

//--游戏对象与资源的关系

游戏对象与资源是一种引用关系。

例如,一个模型是由贴图和Mesh组成,将它拖入场景中时,生成的游戏对象就会引用这两种资源。当程序调用GameObject.Destroy()或者GameObject.DestroyImmediate()方法时,只会卸载掉它的对象,它身上引用的贴图和Mesh还在内存中。

Unity这么做是有原因的:很多游戏对象的加载与卸载是很频繁的,如果每次卸载都将引用的资源清理掉,无疑会造成IO的阻塞。但是如果长时间不卸载这些资源,那么内存必然涨上去。

所以Unity又提供了一个方法来自动卸载无用资源。其中,无用资源表示没有被别的对象或代码引用的资源。

EditorUtility.UnloadUnusedAssetsImmediate()方法即可卸载编辑器下无用资源了。

using UnityEditor;

public class EditorModeUnloadUnusedMyTools
{
    [MenuItem("Assets/My Tools/UnloadUnusedAssetsImmediate", false)]
    static void MyUnloadUnused()
    {
        EditorUtility.UnloadUnusedAssetsImmediate();
    }
}

 

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值