summaryrefslogtreecommitdiff
path: root/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/ExampleScenes/ExampleScripts/Editor/InteractableEditor.cs
blob: 321b8abb1f31d09e1478525291764897ec632be7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
using UnityEngine;
using UnityEditor;
using UnityEditorInternal;
using Pathfinding.Examples;
using System.Collections.Generic;
using UnityEngine.AI;

namespace Pathfinding.Examples {
	[CustomEditor(typeof(Interactable))]
	[CanEditMultipleObjects]
	public class InteractableEditor : EditorBase {
		ReorderableList actions;

		static Rect SliceRow (ref Rect rect, float height) {
			return GUIUtilityx.SliceRow(ref rect, height);
		}

		protected override void OnEnable () {
			base.OnEnable();
			actions = new ReorderableList(serializedObject, serializedObject.FindProperty("actions"), true, true, true, true);
			actions.drawElementCallback = (Rect rect, int index, bool active, bool isFocused) => {
				var item = actions.serializedProperty.GetArrayElementAtIndex(index);
				var ob = item.managedReferenceValue as Interactable.InteractableAction;
				if (ob == null) {
					EditorGUI.LabelField(rect, "Null");
					return;
				}
				var tp = ob.GetType();

				var lineHeight = EditorGUIUtility.singleLineHeight;
				if (tp == typeof(Interactable.AnimatorSetBoolAction)) {
					EditorGUI.LabelField(SliceRow(ref rect, lineHeight), "Set Animator Property", EditorStyles.boldLabel);
					EditorGUI.PropertyField(SliceRow(ref rect, lineHeight), item.FindPropertyRelative("animator"));
					EditorGUI.PropertyField(SliceRow(ref rect, lineHeight), item.FindPropertyRelative("propertyName"));
					EditorGUI.PropertyField(SliceRow(ref rect, lineHeight), item.FindPropertyRelative("value"));
				} else if (tp == typeof(Interactable.AnimatorPlay)) {
					EditorGUI.LabelField(SliceRow(ref rect, lineHeight), "Play Animator State", EditorStyles.boldLabel);
					EditorGUI.PropertyField(SliceRow(ref rect, lineHeight), item.FindPropertyRelative("animator"));
					EditorGUI.PropertyField(SliceRow(ref rect, lineHeight), item.FindPropertyRelative("stateName"));
					EditorGUI.PropertyField(SliceRow(ref rect, lineHeight), item.FindPropertyRelative("normalizedTime"));
				} else if (tp == typeof(Interactable.ActivateParticleSystem)) {
					EditorGUI.LabelField(SliceRow(ref rect, lineHeight), "Activate Particle System", EditorStyles.boldLabel);
					EditorGUI.PropertyField(SliceRow(ref rect, lineHeight), item.FindPropertyRelative("particleSystem"));
				} else if (tp == typeof(Interactable.DelayAction)) {
					EditorGUI.LabelField(SliceRow(ref rect, lineHeight), "Delay", EditorStyles.boldLabel);
					EditorGUI.PropertyField(SliceRow(ref rect, lineHeight), item.FindPropertyRelative("delay"));
				} else if (tp == typeof(Interactable.SetObjectActiveAction)) {
					EditorGUI.LabelField(SliceRow(ref rect, lineHeight), "Set Object Active", EditorStyles.boldLabel);
					EditorGUI.PropertyField(SliceRow(ref rect, lineHeight), item.FindPropertyRelative("target"));
					EditorGUI.PropertyField(SliceRow(ref rect, lineHeight), item.FindPropertyRelative("active"));
				} else if (tp == typeof(Interactable.TeleportAgentAction)) {
					EditorGUI.LabelField(SliceRow(ref rect, lineHeight), "Teleport Agent", EditorStyles.boldLabel);
					EditorGUI.PropertyField(SliceRow(ref rect, lineHeight), item.FindPropertyRelative("destination"));
				} else if (tp == typeof(Interactable.TeleportAgentOnLinkAction)) {
					EditorGUI.LabelField(SliceRow(ref rect, lineHeight), "Teleport Agent on Off-Mesh Link", EditorStyles.boldLabel);
					EditorGUI.PropertyField(SliceRow(ref rect, lineHeight), item.FindPropertyRelative("destination"));
				} else if (tp == typeof(Interactable.SetTransformAction)) {
					EditorGUI.LabelField(SliceRow(ref rect, lineHeight), "Set Transform", EditorStyles.boldLabel);
					EditorGUI.PropertyField(SliceRow(ref rect, lineHeight), item.FindPropertyRelative("transform"));
					EditorGUI.PropertyField(SliceRow(ref rect, lineHeight), item.FindPropertyRelative("source"));
					EditorGUI.PropertyField(SliceRow(ref rect, lineHeight), item.FindPropertyRelative("setPosition"));
					EditorGUI.PropertyField(SliceRow(ref rect, lineHeight), item.FindPropertyRelative("setRotation"));
					EditorGUI.PropertyField(SliceRow(ref rect, lineHeight), item.FindPropertyRelative("setScale"));
				} else if (tp == typeof(Interactable.MoveToAction)) {
					EditorGUI.LabelField(SliceRow(ref rect, lineHeight), "Move To", EditorStyles.boldLabel);
					EditorGUI.PropertyField(SliceRow(ref rect, lineHeight), item.FindPropertyRelative("destination"));
					EditorGUI.PropertyField(SliceRow(ref rect, lineHeight), item.FindPropertyRelative("useRotation"));
					EditorGUI.PropertyField(SliceRow(ref rect, lineHeight), item.FindPropertyRelative("waitUntilReached"));
				} else if (tp == typeof(Interactable.InstantiatePrefab)) {
					EditorGUI.LabelField(SliceRow(ref rect, lineHeight), "Instantiate Prefab", EditorStyles.boldLabel);
					EditorGUI.PropertyField(SliceRow(ref rect, lineHeight), item.FindPropertyRelative("prefab"));
					EditorGUI.PropertyField(SliceRow(ref rect, lineHeight), item.FindPropertyRelative("position"));
				} else if (tp == typeof(Interactable.CallFunction)) {
					EditorGUI.LabelField(SliceRow(ref rect, lineHeight), "Call Function", EditorStyles.boldLabel);
					EditorGUI.PropertyField(SliceRow(ref rect, lineHeight), item.FindPropertyRelative("function"));
				} else if (tp == typeof(Interactable.InteractAction)) {
					EditorGUI.LabelField(SliceRow(ref rect, lineHeight), "Interact", EditorStyles.boldLabel);
					EditorGUI.PropertyField(SliceRow(ref rect, lineHeight), item.FindPropertyRelative("interactable"));
				}
			};
			actions.elementHeightCallback = (int index) => {
				var actions = (target as Interactable).actions;
				var tp = index < actions.Count ? actions[index]?.GetType() : null;
				var h = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
				if (tp == null) return h;
				else if (tp == typeof(Interactable.AnimatorSetBoolAction)) return 4*h;
				else if (tp == typeof(Interactable.AnimatorPlay)) return 4*h;
				else if (tp == typeof(Interactable.ActivateParticleSystem)) return 2*h;
				else if (tp == typeof(Interactable.DelayAction)) return 2*h;
				else if (tp == typeof(Interactable.SetObjectActiveAction)) return 3*h;
				else if (tp == typeof(Interactable.TeleportAgentAction)) return 2*h;
				else if (tp == typeof(Interactable.TeleportAgentOnLinkAction)) return 2*h;
				else if (tp == typeof(Interactable.SetTransformAction)) return 6*h;
				else if (tp == typeof(Interactable.MoveToAction)) return 4*h;
				else if (tp == typeof(Interactable.InstantiatePrefab)) return 3*h;
				else if (tp == typeof(Interactable.InteractAction)) return 2*h;
				else if (tp == typeof(Interactable.CallFunction)) {
					return (3.5f + Mathf.Max(1, (actions[index] as Interactable.CallFunction).function.GetPersistentEventCount())*2.5f) * h;
				} else throw new System.Exception("Unexpected type " + tp);
			};
			actions.drawHeaderCallback = (Rect rect) => {
				EditorGUI.LabelField(rect, "Actions");
			};
			actions.onAddDropdownCallback = (rect, _) => {
				GenericMenu menu = new GenericMenu();
				var interactable = target as Interactable;
				menu.AddItem(new GUIContent("AnimatorSetBool"), false, () => interactable.actions.Add(new Interactable.AnimatorSetBoolAction()));
				menu.AddItem(new GUIContent("AnimatorPlay"), false, () => interactable.actions.Add(new Interactable.AnimatorPlay()));
				menu.AddItem(new GUIContent("ActivateParticleSystem"), false, () => interactable.actions.Add(new Interactable.ActivateParticleSystem()));
				menu.AddItem(new GUIContent("Delay"), false, () => interactable.actions.Add(new Interactable.DelayAction()));
				menu.AddItem(new GUIContent("SetObjectActive"), false, () => interactable.actions.Add(new Interactable.SetObjectActiveAction()));
				menu.AddItem(new GUIContent("TeleportAgent"), false, () => interactable.actions.Add(new Interactable.TeleportAgentAction()));
				if (interactable.TryGetComponent<NodeLink2>(out var _)) {
					menu.AddItem(new GUIContent("Teleport Agent on Off-Mesh Link"), false, () => interactable.actions.Add(new Interactable.TeleportAgentOnLinkAction()));
				}
				menu.AddItem(new GUIContent("SetTransform"), false, () => interactable.actions.Add(new Interactable.SetTransformAction()));
				menu.AddItem(new GUIContent("MoveTo"), false, () => interactable.actions.Add(new Interactable.MoveToAction()));
				menu.AddItem(new GUIContent("InstantiatePrefab"), false, () => interactable.actions.Add(new Interactable.InstantiatePrefab()));
				menu.AddItem(new GUIContent("CallFunction"), false, () => interactable.actions.Add(new Interactable.CallFunction()));
				menu.AddItem(new GUIContent("Interact with other interactable"), false, () => interactable.actions.Add(new Interactable.InteractAction()));
				menu.DropDown(rect);
			};
		}

		protected override void Inspector () {
			var script = target as Interactable;

			script.actions = script.actions ?? new List<Interactable.InteractableAction>();
			actions.DoLayoutList();
		}
	}
}