Unity--PropertyAttribute和PropertyDrawer結合進行配置引用
阿新 • • 發佈:2018-12-12
應用場景,類中引用配置表中的技能id,程式碼如下圖
public class PropertyTest : MonoBehaviour
{
public string prefabPath = "";
//配置表中的技能id
public int skillId = 0;
}
Inspector中的顯示如下圖
技能配置表如下圖
id為技能id,prefabPath為技能的特效路徑,以英雄名為字首,description為技能描述
Inspector中的SkillId的值為技能表中的id,需要手動填,不直觀,容易填錯,
下面的實現方式會去掉手動填id,而且顯示上更清晰直觀
先看下最終Inspector中顯示的效果,顯示的是英雄名稱/技能描述,操作流程是從列表中點選就好
具體實現程式碼如下
using System; using UnityEngine; public enum ReferenceType : int { Prefab, SkillId } [AttributeUsage(AttributeTargets.Enum | AttributeTargets.Field)] public sealed class Reference : PropertyAttribute { public ReferenceType RefType { get; private set; } public Reference(ReferenceType refType) { RefType = refType; } } public class PropertyTest : MonoBehaviour { public string prefabPath = ""; //配置表中的技能id [Reference(ReferenceType.SkillId)] public int skillId = 0; }
using System; using System.Collections.Generic; using UnityEditor; using UnityEngine; public class SkillData { public int id; public string prefabPath = ""; public string description = ""; } [CustomPropertyDrawer(typeof(Reference))] public class ResReferenceDrawer : PropertyDrawer { private static List<SkillData> skillConfigList = new List<SkillData>(); private static List<int> ids = new List<int>();//id列表 private static List<string> descriptions = new List<string>();//描述列表,Inspector顯示用 [InitializeOnLoadMethod] //初始化測試資料 static void InitTestData() { //測試資料begin skillConfigList.Clear(); skillConfigList.Add(new SkillData{ id = 100, prefabPath = "xiaoqiao/a.prefab", description = "綻放之舞" }); skillConfigList.Add(new SkillData{ id = 101, prefabPath = "xiaoqiao/b.prefab", description = "甜蜜戀風" }); skillConfigList.Add(new SkillData { id = 102, prefabPath = "xiaoqiao/c.prefab", description = "星華繚亂" }); skillConfigList.Add(new SkillData { id = 200, prefabPath = "houyi/a.prefab", description = "炙熱之風" }); skillConfigList.Add(new SkillData { id = 201, prefabPath = "houyi/b.prefab", description = "燎原箭雨" }); skillConfigList.Add(new SkillData { id = 202, prefabPath = "houyi/c.prefab", description = "懲戒射擊" }); //測試資料end //一個id對應一個描述 ids.Clear(); descriptions.Clear(); var em = skillConfigList.GetEnumerator(); SkillData sc = null; while (em.MoveNext()) { sc = em.Current; ids.Add(sc.id); var strs = sc.prefabPath.Split('/'); //以英雄名稱為字首進行分類,EditorGUI.Popup為以斜槓符號/進行分層級顯示,有多少個斜槓就分多少層級 var des = strs[0] + "/" + sc.description; descriptions.Add(des); } } public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { var reference = (Reference)attribute; switch (reference.RefType) { case ReferenceType.Prefab: HandlePrefabReference(position, property, label); break; case ReferenceType.SkillId: HandleSkillIdReference(position, property, label); break; } } private void HandleSkillIdReference (Rect position, SerializedProperty property, GUIContent label) { if (SerializedPropertyType.Integer != property.propertyType) { EditorGUI.PropertyField(position, property); return; } EditorGUI.BeginChangeCheck(); //得到描述在列表中的下標 var value = EditorGUI.Popup(position, property.displayName, Math.Max(0, ids.IndexOf(property.intValue)), descriptions.ToArray()); if (EditorGUI.EndChangeCheck()) { //根據下標從id列表中找出技能id進行賦值 property.intValue = ids[value]; Debug.Log(ids[value]); } } private void HandlePrefabReference (Rect position, SerializedProperty property, GUIContent label) { if (SerializedPropertyType.String != property.propertyType) { EditorGUI.PropertyField(position, property); return; } //根據路徑得到一個型別為GameObject的物件 var prefab = (GameObject)AssetDatabase.LoadAssetAtPath(property.stringValue, typeof(GameObject)); //ObjectField會在Inspector面板中顯示一個框,後面帶一個小按鈕,點選後彈出面板選擇prefab var obj = (GameObject)EditorGUI.ObjectField(position, property.displayName, prefab, typeof(GameObject), false); //得到prefab的路徑 string newPath = AssetDatabase.GetAssetPath(obj); //設定路徑 property.stringValue = newPath; Debug.Log(newPath); } }