Hello ,I am KitStar
1. 自定义Unity,Inspector界面中的展示方式。為每一個對象添加狀態以及持續時間
延时对对象的状态进行改变。比如激活,隐藏,删除,等等…
由于比较简单,所以直接老规矩上脚本吧。
1using System; 2using System.Collections; 3using UnityEngine; 4using UnityEngine.SceneManagement; 5#if UNITY_EDITOR 6using UnityEditor; 7#endif 8 9 public class TimedObjectActivator : MonoBehaviour 10 { 11 public enum Action 12 { 13 Activate, 14 Deactivate, 15 Destroy, 16 ReloadLevel, 17 Call, 18 } 19 20 21 [Serializable] 22 public class Entry 23 { 24 public GameObject target; 25 public Action action; 26 public float delay; 27 } 28 29 30 [Serializable] 31 public class Entries 32 { 33 public Entry[] entries; 34 } 35 36 37 public Entries entries = new Entries(); 38 39 40 private void Awake() 41 { 42 foreach (Entry entry in entries.entries) 43 { 44 switch (entry.action) 45 { 46 case Action.Activate: 47 StartCoroutine(Activate(entry)); 48 break; 49 case Action.Deactivate: 50 StartCoroutine(Deactivate(entry)); 51 break; 52 case Action.Destroy: 53 Destroy(entry.target, entry.delay); 54 break; 55 56 case Action.ReloadLevel: 57 StartCoroutine(ReloadLevel(entry)); 58 break; 59 } 60 } 61 } 62 63 64 private IEnumerator Activate(Entry entry) 65 { 66 yield return new WaitForSeconds(entry.delay); 67 entry.target.SetActive(true); 68 } 69 70 71 private IEnumerator Deactivate(Entry entry) 72 { 73 yield return new WaitForSeconds(entry.delay); 74 entry.target.SetActive(false); 75 } 76 77 78 private IEnumerator ReloadLevel(Entry entry) 79 { 80 yield return new WaitForSeconds(entry.delay); 81 SceneManager.LoadScene(SceneManager.GetSceneAt(0).name); 82 } 83 } 84 85 86 87#if UNITY_EDITOR 88 [CustomPropertyDrawer(typeof (TimedObjectActivator.Entries))] 89 public class EntriesDrawer : PropertyDrawer 90 { 91 private const float k_LineHeight = 18; 92 private const float k_Spacing = 4; 93 94 95 public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 96 { 97 EditorGUI.BeginProperty(position, label, property); 98 99 float x = position.x; 100 float y = position.y; 101 float width = position.width; 102 103 // Draw label 104 EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label); 105 106 // Don't make child fields be indented 107 var indent = EditorGUI.indentLevel; 108 EditorGUI.indentLevel = 0; 109 110 var entries = property.FindPropertyRelative("entries"); 111 112 if (entries.arraySize > 0) 113 { 114 float actionWidth = .25f*width; 115 float targetWidth = .6f*width; 116 float delayWidth = .1f*width; 117 float buttonWidth = .05f*width; 118 119 for (int i = 0; i < entries.arraySize; ++i) 120 { 121 y += k_LineHeight + k_Spacing; 122 123 var entry = entries.GetArrayElementAtIndex(i); 124 125 float rowX = x; 126 127 // Calculate rects 128 Rect actionRect = new Rect(rowX, y, actionWidth, k_LineHeight); 129 rowX += actionWidth; 130 131 Rect targetRect = new Rect(rowX, y, targetWidth, k_LineHeight); 132 rowX += targetWidth; 133 134 Rect delayRect = new Rect(rowX, y, delayWidth, k_LineHeight); 135 rowX += delayWidth; 136 137 Rect buttonRect = new Rect(rowX, y, buttonWidth, k_LineHeight); 138 rowX += buttonWidth; 139 140 // Draw fields - passs GUIContent.none to each so they are drawn without labels 141 142 if (entry.FindPropertyRelative("action").enumValueIndex != 143 (int) TimedObjectActivator.Action.ReloadLevel) 144 { 145 EditorGUI.PropertyField(actionRect, entry.FindPropertyRelative("action"), GUIContent.none); 146 EditorGUI.PropertyField(targetRect, entry.FindPropertyRelative("target"), GUIContent.none); 147 } 148 else 149 { 150 actionRect.width = actionRect.width + targetRect.width; 151 EditorGUI.PropertyField(actionRect, entry.FindPropertyRelative("action"), GUIContent.none); 152 } 153 154 EditorGUI.PropertyField(delayRect, entry.FindPropertyRelative("delay"), GUIContent.none); 155 if (GUI.Button(buttonRect, "-")) 156 { 157 entries.DeleteArrayElementAtIndex(i); 158 break; 159 } 160 } 161 } 162 163 // add & sort buttons 164 y += k_LineHeight + k_Spacing; 165 166 var addButtonRect = new Rect(position.x + position.width - 120, y, 60, k_LineHeight); 167 if (GUI.Button(addButtonRect, "Add")) 168 { 169 entries.InsertArrayElementAtIndex(entries.arraySize); 170 } 171 172 var sortButtonRect = new Rect(position.x + position.width - 60, y, 60, k_LineHeight); 173 if (GUI.Button(sortButtonRect, "Sort")) 174 { 175 bool changed = true; 176 while (entries.arraySize > 1 && changed) 177 { 178 changed = false; 179 for (int i = 0; i < entries.arraySize - 1; ++i) 180 { 181 var e1 = entries.GetArrayElementAtIndex(i); 182 var e2 = entries.GetArrayElementAtIndex(i + 1); 183 184 if (e1.FindPropertyRelative("delay").floatValue > e2.FindPropertyRelative("delay").floatValue) 185 { 186 entries.MoveArrayElement(i + 1, i); 187 changed = true; 188 break; 189 } 190 } 191 } 192 } 193 194 195 // Set indent back to what it was 196 EditorGUI.indentLevel = indent; 197 // 198 199 200 EditorGUI.EndProperty(); 201 } 202 203 204 public override float GetPropertyHeight(SerializedProperty property, GUIContent label) 205 { 206 SerializedProperty entries = property.FindPropertyRelative("entries"); 207 float lineAndSpace = k_LineHeight + k_Spacing; 208 return 40 + (entries.arraySize*lineAndSpace) + lineAndSpace; 209 } 210 } 211#endif