介绍
在平时开发的时候经常会用到预制体
,还会结合Resources
在运行时加载预制体,不过使用Resources
的方式会把所有放在Resources目录下的东西都打包到build的程序包中,这样就会把测试的内容也打包进去,而且Resources文件夹可以在Assets的任意子目录中不方便管理,这并不是我们想要的。当当当主角登场~预制体库
。
预制体库继承自ScriptableObject
,按本人理解ScriptableObject
就像个配置文件,可以被脚本引用使用。它可以替代Resources
达到相同的目的。
功能实现
using System.Collections.Generic;
using UnityEngine;
using Sirenix.OdinInspector;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace ZYF
{
/*[TypeInfoBox("<color=#4F9F93><size=18>ଘ(੭ˊ꒳ˋ)੭✧ 预制体库\n" +
"<color=#FE856F><size=13>ଘ(੭ˊ꒳ˋ)੭✧ 避免放到Resources</size></color>" +
"</size></color>")]*/
public class ZYF_PrefabDictionary : ScriptableObject
{
[System.Serializable]
public class PrefabInfo
{
public string key;
public GameObject prefab;
}
[SerializeField, Header("预制体列表")]
private List<PrefabInfo> prefabList = new List<PrefabInfo>();
private Dictionary<string, PrefabInfo> _dic;
public Dictionary<string, PrefabInfo> Dic
{
get
{
if (_dic == null)
{
_dic = new Dictionary<string, PrefabInfo>();
foreach (var item in prefabList)
{
_dic.Add(item.key, item);
}
}
return _dic;
}
}
/// <summary>
/// 获得对应key的预制体
/// </summary>
/// <param name="key"></param>
public T GetPrefab<T>(string key) where T : Object
{
if (Dic.ContainsKey(key))
{
var info = Dic[key];
if (info.prefab != null)
{
T prefab = info.prefab.GetComponent<T>();
if (prefab != null)
{
return prefab;
}
else
{
Debug.LogError($"预制体 {key} 的期望类型为:({typeof(T).Name}),但找到的预制体不匹配", info.prefab);
}
}
else
{
Debug.LogError($"预制体{key}丢失", this);
}
}
else
{
Debug.LogError($"没有找到预制体:{key}", this);
}
return null;
}
#if UNITY_EDITOR
[MenuItem("ZYF/ScriptableObjects/PrefabDic")]
public static void AddMenu()
{
SpawnScriptableObject2Project<ZYF_PrefabDictionary>(rename: "预制体库");
}
#endif
/// <summary>
/// 实例化scriptableObject到Project中
/// </summary>
/// <param name="sbo"></param>
public static void SpawnScriptableObject2Project<T>(string rename) where T : ScriptableObject
{
#if UNITY_EDITOR
var config = ScriptableObject.CreateInstance<T>();
string name = string.IsNullOrEmpty(rename) == true ? typeof(T).Name : rename;
string path = $"Assets/{name}.asset";
UnityEditor.AssetDatabase.CreateAsset(config, path);
UnityEditor.Selection.activeObject = config;
#endif
}
}
}
食用方法
1.生成配置
AddMenu()
会自动在菜单栏添加一个按钮用来生成一个新的配置到Assets
文件夹中。
2.引用生成的配置调用GetPrefab
即可。