示例#1
0
        ///----------------------------------------------------------------------------------------------
        ///---------------------------------------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);
        }