///---------------------------------------------------------------------------------------------- ///---------------------------------------UNITY EDITOR------------------------------------------- #if UNITY_EDITOR protected override void OnTaskInspectorGUI() { if (!Application.isPlaying && GUILayout.Button("Select Method")) { var menu = new UnityEditor.GenericMenu(); if (agent != null) { foreach (var comp in agent.GetComponents(typeof(Component)).Where(c => c.hideFlags != HideFlags.HideInInspector)) { menu = EditorUtils.GetInstanceMethodSelectionMenu(comp.GetType(), typeof(object), typeof(object), SetMethod, 6, false, false, menu); } menu.AddSeparator("/"); } foreach (var t in TypePrefs.GetPreferedTypesList(typeof(object))) { menu = EditorUtils.GetStaticMethodSelectionMenu(t, typeof(object), typeof(object), SetMethod, 6, false, false, menu); if (typeof(UnityEngine.Component).IsAssignableFrom(t)) { menu = EditorUtils.GetInstanceMethodSelectionMenu(t, typeof(object), typeof(object), SetMethod, 6, false, false, menu); } } menu.ShowAsBrowser("Select Method", this.GetType()); Event.current.Use(); } var m = targetMethod; if (m != null) { GUILayout.BeginVertical("box"); UnityEditor.EditorGUILayout.LabelField("Type", targetMethod.RTReflectedType().FriendlyName()); UnityEditor.EditorGUILayout.LabelField("Method", m.Name); UnityEditor.EditorGUILayout.LabelField("Returns", m.ReturnType.FriendlyName()); UnityEditor.EditorGUILayout.HelpBox(DocsByReflection.GetMemberSummary(targetMethod), UnityEditor.MessageType.None); if (m.ReturnType == typeof(IEnumerator)) { GUILayout.Label("<b>This will execute as a Coroutine!</b>"); } GUILayout.EndVertical(); var paramNames = m.GetParameters().Select(p => p.Name.SplitCamelCase()).ToArray(); var variables = functionWrapper.GetVariables(); if (m.ReturnType == typeof(void)) { for (var i = 0; i < paramNames.Length; i++) { NodeCanvas.Editor.BBParameterEditor.ParameterField(paramNames[i], variables[i]); } } else { for (var i = 0; i < paramNames.Length; i++) { NodeCanvas.Editor.BBParameterEditor.ParameterField(paramNames[i], variables[i + 1]); } if (m.ReturnType != typeof(IEnumerator)) { NodeCanvas.Editor.BBParameterEditor.ParameterField("Save Return Value", variables[0], true); } } } }
///Get a menu for variable GenericMenu GetVariableMenu(Variable data, int index) { var menu = new GenericMenu(); if (data.varType == typeof(VariableSeperator)) { menu.AddItem(new GUIContent("Rename"), false, () => { (data.value as VariableSeperator).isEditingName = true; }); menu.AddItem(new GUIContent("Remove"), false, () => { UndoUtility.RecordObject(contextObject, "Remove Variable"); bb.RemoveVariable(data.name); UndoUtility.SetDirty(contextObject); }); return(menu); } System.Action <PropertyInfo> BindProp = (p) => { UndoUtility.RecordObject(contextObject, "Bind Variable"); data.BindProperty(p); UndoUtility.SetDirty(contextObject); }; System.Action <FieldInfo> BindField = (f) => { UndoUtility.RecordObject(contextObject, "Bind Variable"); data.BindProperty(f); UndoUtility.SetDirty(contextObject); }; menu.AddDisabledItem(new GUIContent(string.Format("Type: {0}", data.varType.FriendlyName()))); if (bb.propertiesBindTarget != null) { foreach (var comp in bb.propertiesBindTarget.GetComponents(typeof(Component)).Where(c => c != null)) { menu = EditorUtils.GetInstanceFieldSelectionMenu(comp.GetType(), data.varType, BindField, menu, "Bind (Self)"); menu = EditorUtils.GetInstancePropertySelectionMenu(comp.GetType(), data.varType, BindProp, false, false, menu, "Bind (Self)"); } menu.AddSeparator("Bind (Self)/"); } foreach (var type in TypePrefs.GetPreferedTypesList()) { if (bb.propertiesBindTarget != null && typeof(UnityEngine.Component).RTIsAssignableFrom(type)) { menu = EditorUtils.GetInstanceFieldSelectionMenu(type, typeof(object), BindField, menu, "Bind (Self)"); menu = EditorUtils.GetInstancePropertySelectionMenu(type, typeof(object), BindProp, false, false, menu, "Bind (Self)"); } menu = EditorUtils.GetStaticFieldSelectionMenu(type, data.varType, BindField, menu, "Bind (Static)"); menu = EditorUtils.GetStaticPropertySelectionMenu(type, data.varType, BindProp, false, false, menu, "Bind (Static)"); } menu.AddItem(new GUIContent("Duplicate"), false, () => { UndoUtility.RecordObject(contextObject, "Duplicate Variable"); data.Duplicate(bb); UndoUtility.SetDirty(contextObject); }); if (bb is BlackboardSource) //TODO: avoid this check (but Im too tired now) { if (!data.isPropertyBound) { menu.AddItem(new GUIContent("Exposed Public"), data.isExposedPublic, () => { UndoUtility.RecordObject(contextObject, "Modify Variable"); data.isExposedPublic = !data.isExposedPublic; UndoUtility.SetDirty(contextObject); }); } else { menu.AddDisabledItem(new GUIContent("Bound Variables Can't Be Exposed")); } } menu.AddSeparator("/"); if (data.isPropertyBound) { menu.AddItem(new GUIContent("UnBind"), false, () => { UndoUtility.RecordObject(contextObject, "UnBind Variable"); data.UnBind(); UndoUtility.SetDirty(contextObject); }); } else { menu.AddDisabledItem(new GUIContent("UnBind")); } var serProp = variablesProperty?.GetArrayElementAtIndex(index); if (serProp != null && serProp.prefabOverride) { var prefabAssetPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(contextObject); var asset = AssetDatabase.LoadAssetAtPath <UnityEngine.Object>(prefabAssetPath); menu.AddItem(new GUIContent("Apply Prefab Modification To '" + asset.name + "'"), false, () => { UndoUtility.RecordObject(asset, "Apply Variable To Prefab"); UndoUtility.RecordObject(contextObject, "Apply Variable To Prefab"); PrefabUtility.ApplyPropertyOverride(serProp, prefabAssetPath, InteractionMode.UserAction); UndoUtility.SetDirty(contextObject); UndoUtility.SetDirty(asset); }); menu.AddItem(new GUIContent("Revert Prefab Modification"), false, () => { UndoUtility.RecordObject(contextObject, "Revert Variable From Prefab"); PrefabUtility.RevertPropertyOverride(serProp, InteractionMode.UserAction); UndoUtility.SetDirty(contextObject); }); } System.Action <System.Type> ChangeType = (t) => { UndoUtility.RecordObject(contextObject, "Change Variable Type"); bb.ChangeVariableType(data, t); UndoUtility.SetDirty(contextObject); }; menu = EditorUtils.GetPreferedTypesSelectionMenu(typeof(object), ChangeType, menu, "Change Type"); menu.AddItem(new GUIContent("Delete Variable"), false, () => { if (EditorUtility.DisplayDialog("Delete Variable '" + data.name + "'", "Are you sure?", "Yes", "No")) { UndoUtility.RecordObject(contextObject, "Delete Variable"); bb.RemoveVariable(data.name); GUIUtility.hotControl = 0; GUIUtility.keyboardControl = 0; UndoUtility.SetDirty(contextObject); } }); return(menu); }
//While there is a similar method in EditorUtils, due to layouting and especialy no prefix name, this has to be redone a bit differently static object VariableField(Variable data, UnityEngine.Object context, GUILayoutOption[] layoutOptions) { var o = data.value; var t = data.varType; if (t == typeof(VariableSeperator)) { GUILayout.Space(0); return(o); } //Check scene object type for UnityObjects. Consider Interfaces as scene object type. Assume that user uses interfaces with UnityObjects if (typeof(UnityEngine.Object).IsAssignableFrom(t) || t.IsInterface) { var isSceneObjectType = (typeof(Component).IsAssignableFrom(t) || t == typeof(GameObject) || t.IsInterface); return(EditorGUILayout.ObjectField((UnityEngine.Object)o, t, isSceneObjectType, layoutOptions)); } //Check Type second if (t == typeof(System.Type)) { return(EditorUtils.Popup <System.Type>(string.Empty, (System.Type)o, TypePrefs.GetPreferedTypesList(true), layoutOptions)); } t = o != null?o.GetType() : t; if (t.IsAbstract) { GUILayout.Label(string.Format("({0})", t.FriendlyName()), layoutOptions); return(o); } if (o == null && !t.IsAbstract && !t.IsInterface && (t.GetConstructor(System.Type.EmptyTypes) != null || t.IsArray)) { if (GUILayout.Button("(null) Create", layoutOptions)) { if (t.IsArray) { return(System.Array.CreateInstance(t.GetElementType(), 0)); } return(System.Activator.CreateInstance(t)); } return(o); } if (t == typeof(bool)) { return(EditorGUILayout.Toggle((bool)o, layoutOptions)); } if (t == typeof(Color)) { return(EditorGUILayout.ColorField((Color)o, layoutOptions)); } if (t == typeof(AnimationCurve)) { return(EditorGUILayout.CurveField((AnimationCurve)o, layoutOptions)); } if (t.IsSubclassOf(typeof(System.Enum))) { if (t.IsDefined(typeof(System.FlagsAttribute), true)) { #if UNITY_2017_3_OR_NEWER return(EditorGUILayout.EnumFlagsField(GUIContent.none, (System.Enum)o, layoutOptions)); #else return(EditorGUILayout.EnumMaskPopup(GUIContent.none, (System.Enum)o, layoutOptions)); #endif } return(EditorGUILayout.EnumPopup((System.Enum)o, layoutOptions)); } if (t == typeof(float)) { GUI.backgroundColor = TypePrefs.GetTypeColor(t); return(EditorGUILayout.FloatField((float)o, layoutOptions)); } if (t == typeof(int)) { GUI.backgroundColor = TypePrefs.GetTypeColor(t); return(EditorGUILayout.IntField((int)o, layoutOptions)); } if (t == typeof(string)) { GUI.backgroundColor = TypePrefs.GetTypeColor(t); return(EditorGUILayout.TextField((string)o, layoutOptions)); } if (t == typeof(long)) { GUI.backgroundColor = TypePrefs.GetTypeColor(t); return(EditorGUILayout.LongField((long)o, layoutOptions)); } if (t == typeof(double)) { GUI.backgroundColor = TypePrefs.GetTypeColor(t); return(EditorGUILayout.DoubleField((double)o, layoutOptions)); } if (t == typeof(Vector2)) { return(EditorGUILayout.Vector2Field(string.Empty, (Vector2)o, layoutOptions)); } if (t == typeof(Vector3)) { return(EditorGUILayout.Vector3Field(string.Empty, (Vector3)o, layoutOptions)); } if (t == typeof(Vector4)) { return(EditorGUILayout.Vector4Field(string.Empty, (Vector4)o, layoutOptions)); } if (t == typeof(Quaternion)) { var q = (Quaternion)o; var v = new Vector4(q.x, q.y, q.z, q.w); v = EditorGUILayout.Vector4Field(string.Empty, v, layoutOptions); return(new Quaternion(v.x, v.y, v.z, v.w)); } if (t == typeof(LayerMask)) { return(EditorUtils.LayerMaskField(string.Empty, (LayerMask)o, layoutOptions)); } //If some other type, show it in the generic object editor window if (GUILayout.Button(string.Format("{0} {1}", t.FriendlyName(), (o is IList) ? ((IList)o).Count.ToString() : string.Empty), layoutOptions)) { GenericInspectorWindow.Show(data.ID, o, t, context); } //if we are externaly inspecting value and it's this one, get value from the external editor. This is basicaly done for structs if (GenericInspectorWindow.current != null && GenericInspectorWindow.current.inspectedID == data.ID) { return(GenericInspectorWindow.current.value); } return(o); }
///Return get add variable menu GenericMenu GetAddVariableMenu(IBlackboard bb, UnityEngine.Object contextParent) { System.Action <System.Type> AddNewVariable = (t) => { UndoUtility.RecordObject(contextParent, "Variable Added"); var name = "my" + t.FriendlyName(); while (bb.GetVariable(name) != null) { name += "."; } bb.AddVariable(name, t); UndoUtility.SetDirty(contextParent); }; System.Action <PropertyInfo> AddBoundProp = (p) => { UndoUtility.RecordObject(contextParent, "Variable Added"); var newVar = bb.AddVariable(p.Name, p.PropertyType); newVar.BindProperty(p); UndoUtility.SetDirty(contextParent); }; System.Action <FieldInfo> AddBoundField = (f) => { UndoUtility.RecordObject(contextParent, "Variable Added"); var newVar = bb.AddVariable(f.Name, f.FieldType); newVar.BindProperty(f); UndoUtility.SetDirty(contextParent); }; System.Action AddSeparator = () => { UndoUtility.RecordObject(contextParent, "Separator Added"); bb.AddVariable("Separator (Double Click To Rename)", new VariableSeperator()); UndoUtility.SetDirty(contextParent); }; var menu = new GenericMenu(); menu = EditorUtils.GetPreferedTypesSelectionMenu(typeof(object), AddNewVariable, menu, "New", true); if (bb.propertiesBindTarget != null) { foreach (var comp in bb.propertiesBindTarget.GetComponents(typeof(Component)).Where(c => c.hideFlags == 0)) { menu = EditorUtils.GetInstanceFieldSelectionMenu(comp.GetType(), typeof(object), AddBoundField, menu, "Bound (Self)"); menu = EditorUtils.GetInstancePropertySelectionMenu(comp.GetType(), typeof(object), AddBoundProp, false, false, menu, "Bound (Self)"); } menu.AddSeparator("Bound (Self)/"); } foreach (var type in TypePrefs.GetPreferedTypesList()) { if (bb.propertiesBindTarget != null && typeof(UnityEngine.Component).RTIsAssignableFrom(type)) { menu = EditorUtils.GetInstanceFieldSelectionMenu(type, typeof(object), AddBoundField, menu, "Bound (Self)"); menu = EditorUtils.GetInstancePropertySelectionMenu(type, typeof(object), AddBoundProp, false, false, menu, "Bound (Self)"); } menu = EditorUtils.GetStaticFieldSelectionMenu(type, typeof(object), AddBoundField, menu, "Bound (Static)"); menu = EditorUtils.GetStaticPropertySelectionMenu(type, typeof(object), AddBoundProp, false, false, menu, "Bound (Static)"); } menu.AddSeparator("/"); menu.AddItem(new GUIContent("Add Header Separator"), false, () => { AddSeparator(); }); return(menu); }