예제 #1
0
        // ----------------------------------------------------------------------
        void CreateGameObjectNode(GameObject go, iCS_EditorObject parent, Vector2 graphMousePosition)
        {
            var instance = iCS_UserCommands.CreateGameObject(go, parent, graphMousePosition);

            if (PrefabUtility.GetPrefabType(IStorage.HostGameObject) == PrefabType.Prefab)
            {
                var isSceneObject = UnityUtility.IsSceneGameObject(go);
                if (isSceneObject == true)
                {
                    ShowNotification(new GUIContent("Unity does not allow binding a Scene object to a Prefab."));
                    var thisPort = IStorage.PropertiesWizardGetInputThisPort(instance);
                    if (thisPort != null)
                    {
                        thisPort.Value = null;
                    }
                }
            }
        }
예제 #2
0
        // =================================================================================
        /// Returns the project associated with a Unity Object.
        ///
        /// @param iStorage The visual script storage.
        /// @return The project info assicated with the Unity Object.
        ///
        public static PackageInfo GetProjectFor(iCS_IStorage iStorage)
        {
            var go = iStorage.HostGameObject;

            if (go == null)
            {
                Debug.LogWarning("iCanScript: Internal Error: Unable to find Game Object of visual script");
                return(null);
            }
            string path = null;

            // -- Search for scene path if GO is in the a scene. --
            if (UnityUtility.IsSceneGameObject(go))
            {
                path = EditorApplication.currentScene;
            }
            // -- Search for asset path if GO is a prefab. --
            else
            {
                path = AssetDatabase.GetAssetPath(go);
            }
            path = Folder.AssetToAbsolutePath(path);
            return(GetProjectFor(path));
        }
예제 #3
0
        // ----------------------------------------------------------------------
        void DragAndDropPerformed()
        {
            UnityEngine.Object draggedObject = GetDraggedObject();
            if (draggedObject == null)
            {
                return;
            }

            // Copy/Paste library from prefab
            var library = GetDraggedLibrary(draggedObject);

            if (library != null)
            {
                if (library.EngineObjects.Count == 0)
                {
                    Debug.LogWarning("iCanScript: Storage of pasted object is empty !!!");
                }
                PasteIntoGraph(GraphMousePosition, library, library.EngineObjects[0]);
                // Remove data so that we don't get called multiple times (Unity bug !!!).
                DragAndDrop.AcceptDrag();
                return;
            }

            iCS_EditorObject eObj = GetObjectAtMousePosition();

            if (eObj != null)
            {
                if (eObj.IsInputPort)
                {
                    Type portType    = eObj.RuntimeType;
                    Type dragObjType = draggedObject.GetType();
                    if (iCS_Types.IsA <GameObject>(dragObjType) && PrefabUtility.GetPrefabType(IStorage.HostGameObject) == PrefabType.Prefab)
                    {
                        var isSceneObject = UnityUtility.IsSceneGameObject(draggedObject as GameObject);
                        if (isSceneObject == true)
                        {
                            ShowNotification(new GUIContent("Unity does not allow binding a Scene object to a Prefab."));
                            return;
                        }
                    }
                    if (iCS_Types.IsA(portType, dragObjType))
                    {
                        iCS_UserCommands.DragAndDropSetPortValue(eObj, draggedObject);
                        // Remove data so that we don't get called multiple times (Unity bug !!!).
                        DragAndDrop.AcceptDrag();
                        return;
                    }
                    // Special case for game object
                    if (iCS_Types.IsA <GameObject>(dragObjType) && iCS_Types.IsA <Component>(portType))
                    {
                        var go = draggedObject as GameObject;
                        foreach (var component in go.GetComponents <Component>())
                        {
                            if (iCS_Types.IsA(portType, component.GetType()))
                            {
                                iCS_UserCommands.DragAndDropSetPortValue(eObj, component);
                                // Remove data so that we don't get called multiple times (Unity bug !!!).
                                DragAndDrop.AcceptDrag();
                                return;
                            }
                        }
                    }
                }
                if (eObj.IsNode && !eObj.IsBehaviour)
                {
                    // Don't accept to drag object outside the root node.
                    if (eObj == DisplayRoot && IStorage.ShowDisplayRootNode)
                    {
                        if (!DisplayRoot.GlobalRect.Contains(GraphMousePosition))
                        {
                            return;
                        }
                    }
                    // Allow change of icon on minimized nodes.
                    if (draggedObject is Texture && eObj.IsIconizedOnDisplay)
                    {
                        Texture newTexture = draggedObject as Texture;
                        iCS_UserCommands.ChangeIcon(eObj, newTexture);
                        // Remove data so that we don't get called multiple times (Unity bug !!!).
                        DragAndDrop.AcceptDrag();
                        return;
                    }
                    // Allow dropping Unity object in modules.
                    if (eObj.IsKindOfPackage && draggedObject is GameObject)
                    {
                        GameObject gameObject = draggedObject as GameObject;
                        // Determine if game object contains a visual script.
                        var vs = gameObject.GetComponent <iCS_VisualScriptImp>();
                        if (vs == null)
                        {
                            CreateGameObjectNode(gameObject, eObj, GraphMousePosition);
                        }
                        // Remove data so that we don't get called multiple times (Unity bug !!!).
                        DragAndDrop.AcceptDrag();
                        return;
                    }

                    /*
                     *  FEATURE: Should support resource drag&drop.
                     */
                }
            }
        }
        // -----------------------------------------------------------------------
        public static object ShowInInspector(string name, bool isReadOnly, bool hasSource, string compositeParent,
                                             Type baseType, object currentValue,
                                             int indentLevel, Dictionary <string, object> foldoutDB, ref bool isDirty,
                                             iCS_IStorage iStorage)
        {
            // Extract type information.
            Type valueType = currentValue != null?currentValue.GetType() : baseType;

            Type baseElementType  = iCS_Types.GetElementType(baseType);
            Type valueElementType = iCS_Types.GetElementType(valueType);

            EditorGUI.indentLevel = indentLevel;
            // Make nice name for field to edit.
            string niceName = name == null || name == "" ? "(Unamed)" : ObjectNames.NicifyVariableName(name);

            if (baseType.IsArray)
            {
                niceName = "[" + niceName + "]";
            }
            // Special case for readonly & null value.
            if (isReadOnly && currentValue == null)
            {
                EditorGUILayout.LabelField(niceName, hasSource ? "(see connection)":"(not available)");
                return(currentValue);
            }
            // Special case for arrays
            if (baseType.IsArray)
            {
                if (currentValue == null)
                {
                    currentValue = Array.CreateInstance(baseElementType, 0);
                    isDirty      = true;
                    return(currentValue);
                }
                string compositeArrayName = compositeParent + "." + name;
                if (!foldoutDB.ContainsKey(compositeArrayName))
                {
                    AddFoldout(foldoutDB, compositeArrayName, false);
                }
                bool showArray = Foldout(foldoutDB, compositeArrayName);
                showArray = EditorGUILayout.Foldout(showArray, niceName);
                Foldout(foldoutDB, compositeArrayName, showArray);
                if (!showArray)
                {
                    return(currentValue);
                }
                EditorGUI.indentLevel = indentLevel + 1;
                Array array   = currentValue as Array;
                int   newSize = array.Length;
                if (ModalEdit("Length", "Length", ref newSize, compositeArrayName, (n, v) => EditorGUILayout.IntField(n, v), foldoutDB))
                {
                    if (newSize != array.Length)
                    {
                        if (newSize < 100 || EditorUtility.DisplayDialog("Resizing array", "The new size of the array is > 100.  Are you sure you want your new array to be resized to " + newSize + ".", "Resize", "Cancel"))
                        {
                            Array newArray = Array.CreateInstance(baseElementType, newSize);
                            Array.Copy(array, newArray, Mathf.Min(newSize, array.Length));
                            array   = newArray;
                            isDirty = true;
                        }
                    }
                }
                for (int i = 0; i < array.Length; ++i)
                {
                    bool   elemDirty = false;
                    object newValue  = ShowInInspector("[" + i + "]", isReadOnly, hasSource, compositeArrayName, baseElementType, array.GetValue(i), indentLevel + 1, foldoutDB, ref elemDirty, iStorage);
                    isDirty |= elemDirty;
                    if (elemDirty)
                    {
                        array.SetValue(newValue, i);
                    }
                }
                return(array);
            }
            // Support all UnityEngine objects.
            if (iCS_Types.IsA <UnityEngine.Object>(baseElementType))
            {
                UnityEngine.Object value    = currentValue != null ? currentValue as UnityEngine.Object: null;
                UnityEngine.Object newValue = EditorGUILayout.ObjectField(niceName, value, baseElementType, true);
                if (value == null && newValue == null)
                {
                    return(newValue);
                }
                if (value != newValue)
                {
                    // Do not allow GameObject binding in Prefabs.
                    if (PrefabUtility.GetPrefabType(iStorage.HostGameObject) == PrefabType.Prefab)
                    {
                        if (newValue != null && iCS_Types.IsA <GameObject>(newValue.GetType()))
                        {
                            var isSceneObject = UnityUtility.IsSceneGameObject(newValue as GameObject);
                            if (isSceneObject == true)
                            {
                                iCS_EditorController.ShowNotificationOnVisualEditor(new GUIContent("Unity does not allow binding a Scene object to a Prefab."));
                                iCS_EditorController.RepaintVisualEditor();
                                return(currentValue);
                            }
                        }
                    }
                    isDirty = true;
                }
                return(newValue);
            }
            // Support Type type.
            if (valueElementType == typeof(Type) || currentValue is Type)
            {
                string typeName = currentValue != null?iCS_Types.ToTypeString(currentValue as Type) : "";

                if (ModalEdit(niceName, name, ref typeName, compositeParent, (n, v) => EditorGUILayout.TextField(n, v), foldoutDB))
                {
                    Type newType = iCS_Types.GetTypeFromTypeString(typeName);
                    if (newType != null)
                    {
                        isDirty = true;
                        return(newType);
                    }
                    else
                    {
                        Debug.LogWarning("Type: " + typeName + " was not found.");
                    }
                }
                return(currentValue);
            }
            // Determine if we should create a value if the current value is null.
            if (currentValue == null)
            {
                // Automatically create value types.
                if (baseElementType.IsValueType || baseElementType.IsEnum)
                {
                    currentValue = iCS_Types.CreateInstance(baseElementType);
                    isDirty      = true;
                    return(currentValue);
                }
                else
                {
                    // -- Create reference types with a default constructor --
                    var derivedTypes = P.fold(
                        (lst, t) => {
                        // -- Append types with default constructor --
                        foreach (var constructor in t.GetConstructors(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static))
                        {
                            if (constructor.GetParameters().Length == 0)
                            {
                                lst.Add(t);
                            }
                        }
                        return(lst);
                    },
                        new List <Type>(),
                        iCS_Types.GetAllTypesThatDeriveFrom(baseElementType)
                        );
                    if (derivedTypes.Count <= 1)
                    {
                        isDirty = true;
                        return(iCS_Types.CreateInstance(baseType));
                    }
                    string[] typeNames = new string[derivedTypes.Count + 1];
                    typeNames[0] = "None";
                    if (baseType.IsArray)
                    {
                        for (int i = 0; i < derivedTypes.Count; ++i)
                        {
                            typeNames[i + 1] = iCS_Types.GetName(derivedTypes[i]) + "[]";
                        }
                    }
                    else
                    {
                        for (int i = 0; i < derivedTypes.Count; ++i)
                        {
                            typeNames[i + 1] = iCS_Types.GetName(derivedTypes[i]);
                        }
                    }
                    int idx = EditorGUILayout.Popup(niceName, 0, typeNames);
                    if (idx == 0)
                    {
                        return(null);
                    }
                    isDirty = true;
                    if (baseType.IsArray)
                    {
                        return(Array.CreateInstance(derivedTypes[idx - 1], 0));
                    }
                    return(iCS_Types.CreateInstance(derivedTypes[idx - 1]));
                }
            }
            // Special case for enumerations
            if (valueElementType.IsEnum)
            {
                if (currentValue == null)
                {
                    return(currentValue);
                }
                System.Enum value    = currentValue as System.Enum;
                System.Enum newValue = EditorGUILayout.EnumPopup(niceName, value);
                if (newValue.ToString().CompareTo(value.ToString()) != 0)
                {
                    isDirty = true;
                }
                return(newValue);
            }
            // C# data types.
            if (valueElementType == typeof(byte))
            {
                byte value    = (byte)currentValue;
                byte newValue = value;
                if (ModalEdit(niceName, name, ref newValue, compositeParent, (n, v) => (byte)EditorGUILayout.IntField(n, (int)v), foldoutDB, true))
                {
                    if (value != newValue)
                    {
                        isDirty = true;
                    }
                }
                return(newValue);
            }
            if (valueElementType == typeof(sbyte))
            {
                sbyte value    = (sbyte)currentValue;
                sbyte newValue = value;
                if (ModalEdit(niceName, name, ref newValue, compositeParent, (n, v) => (sbyte)EditorGUILayout.IntField(n, (int)v), foldoutDB, true))
                {
                    if (value != newValue)
                    {
                        isDirty = true;
                    }
                }
                return(newValue);
            }
            if (valueElementType == typeof(bool))
            {
                bool value    = (bool)currentValue;
                bool newValue = EditorGUILayout.Toggle(niceName, value);
                if (newValue != value)
                {
                    isDirty = true;
                }
                return(newValue);
            }
            if (valueElementType == typeof(int))
            {
                int value    = (int)currentValue;
                int newValue = value;
                if (ModalEdit(niceName, name, ref newValue, compositeParent, (n, v) => EditorGUILayout.IntField(n, v), foldoutDB, true))
                {
                    if (value != newValue)
                    {
                        isDirty = true;
                    }
                }
                return(newValue);
            }
            if (valueElementType == typeof(uint))
            {
                string uintAsString = (string)Convert.ChangeType((uint)currentValue, typeof(string));
                string newValue     = uintAsString;
                if (ModalEdit(niceName, name, ref newValue, compositeParent, (n, v) => EditorGUILayout.TextField(n, v), foldoutDB, true))
                {
                    if (uintAsString.CompareTo(newValue) != 0)
                    {
                        isDirty = true;
                    }
                }
                return(Convert.ChangeType(newValue, typeof(uint)));
            }
            if (valueElementType == typeof(short))
            {
                short value    = (short)currentValue;
                short newValue = value;
                if (ModalEdit(niceName, name, ref newValue, compositeParent, (n, v) => (short)EditorGUILayout.IntField(n, (int)v), foldoutDB, true))
                {
                    if (value != newValue)
                    {
                        isDirty = true;
                    }
                }
                return(newValue);
            }
            if (valueElementType == typeof(ushort))
            {
                int value    = (ushort)currentValue;
                int newValue = value;
                if (ModalEdit(niceName, name, ref newValue, compositeParent, (n, v) => (ushort)EditorGUILayout.IntField(n, (int)v), foldoutDB, true))
                {
                    if (value != newValue)
                    {
                        isDirty = true;
                    }
                }
                return(newValue);
            }
            if (valueElementType == typeof(long))
            {
                string longAsString = (string)Convert.ChangeType((long)currentValue, typeof(string));
                string newValue     = longAsString;
                if (ModalEdit(niceName, name, ref newValue, compositeParent, (n, v) => EditorGUILayout.TextField(n, v), foldoutDB, true))
                {
                    if (longAsString.CompareTo(newValue) != 0)
                    {
                        isDirty = true;
                    }
                }
                return(Convert.ChangeType(newValue, typeof(long)));
            }
            if (valueElementType == typeof(ulong))
            {
                string ulongAsString = (string)Convert.ChangeType((ulong)currentValue, typeof(string));
                string newValue      = ulongAsString;
                if (ModalEdit(niceName, name, ref newValue, compositeParent, (n, v) => EditorGUILayout.TextField(n, v), foldoutDB, true))
                {
                    if (ulongAsString.CompareTo(newValue) != 0)
                    {
                        isDirty = true;
                    }
                }
                return(Convert.ChangeType(newValue, typeof(ulong)));
            }
            if (valueElementType == typeof(float))
            {
                float value    = (float)currentValue;
                float newValue = value;
                if (ModalEdit(niceName, name, ref newValue, compositeParent, (n, v) => EditorGUILayout.FloatField(n, v), foldoutDB, true))
                {
                    if (value != newValue)
                    {
                        isDirty = true;
                    }
                }
                return(newValue);
            }
            if (valueElementType == typeof(double))
            {
                string value    = (string)Convert.ChangeType((double)currentValue, typeof(string));
                string newValue = value;
                if (ModalEdit(niceName, name, ref newValue, compositeParent, (n, v) => EditorGUILayout.TextField(n, v), foldoutDB, true))
                {
                    if (value != newValue)
                    {
                        isDirty = true;
                    }
                }
                return(Convert.ChangeType(newValue, typeof(double)));
            }
            if (valueElementType == typeof(decimal))
            {
                float value    = (float)((decimal)currentValue);
                float newValue = value;
                if (ModalEdit(niceName, name, ref newValue, compositeParent, (n, v) => EditorGUILayout.FloatField(n, v), foldoutDB, true))
                {
                    if (value != newValue)
                    {
                        isDirty = true;
                    }
                }
                return((decimal)newValue);
            }
            if (valueElementType == typeof(char))
            {
                string value    = "" + ((char)currentValue);
                string newValue = value;
                if (ModalEdit(niceName, name, ref newValue, compositeParent, (n, v) => EditorGUILayout.TextField(n, v), foldoutDB, true))
                {
                    if (newValue == null || newValue == "" || newValue[0] == 0)
                    {
                        newValue = " ";
                    }
                    if (value != newValue)
                    {
                        isDirty = true;
                    }
                }
                return((newValue != null && newValue.Length >= 1) ? newValue[0] : default(char));
            }
            if (valueElementType == typeof(string))
            {
                string value    = ((string)currentValue) ?? "";
                string newValue = value;
                if (ModalEdit(niceName, name, ref newValue, compositeParent, (n, v) => EditorGUILayout.TextField(n, v), foldoutDB, true))
                {
                    newValue = newValue ?? "";
                    if (string.Compare(value, newValue) != 0)
                    {
                        isDirty = true;
                    }
                }
                return(newValue);
            }
            // Unity data types.
            if (valueElementType == typeof(Vector2))
            {
                Vector2 value    = (Vector2)currentValue;
                Vector2 newValue = value;
                if (ModalEdit(niceName, name, ref value, compositeParent, (n, v) => EditorGUILayout.Vector2Field(n, v), foldoutDB, true))
                {
                    if (Math3D.IsNotEqual(value, newValue))
                    {
                        isDirty = true;
                    }
                }
                return(value);
            }
            if (valueElementType == typeof(Vector3))
            {
                Vector3 value    = (Vector3)currentValue;
                Vector3 newValue = value;
                if (ModalEdit(niceName, name, ref value, compositeParent, (n, v) => EditorGUILayout.Vector3Field(n, v), foldoutDB, true))
                {
                    if (Math3D.IsNotEqual(value, newValue))
                    {
                        isDirty = true;
                    }
                }
                return(value);
            }
            if (valueElementType == typeof(Vector4))
            {
                Vector4 value    = (Vector4)currentValue;
                Vector4 newValue = value;
                if (ModalEdit(niceName, name, ref newValue, compositeParent, (n, v) => EditorGUILayout.Vector4Field(n, v), foldoutDB, true))
                {
                    if (Math3D.IsNotEqual(value, newValue))
                    {
                        isDirty = true;
                    }
                }
                return(newValue);
            }
            if (valueElementType == typeof(Color))
            {
                Color value    = (Color)currentValue;
                Color newValue = value;
                if (ModalEdit(niceName, name, ref newValue, compositeParent, (n, v) => EditorGUILayout.ColorField(n, v), foldoutDB, true))
                {
                    if (Math3D.IsNotEqual(newValue.r, value.r) ||
                        Math3D.IsNotEqual(newValue.g, value.g) ||
                        Math3D.IsNotEqual(newValue.b, value.b) ||
                        Math3D.IsNotEqual(newValue.a, value.a))
                    {
                        isDirty = true;
                    }
                }
                return(newValue);
            }
            // All other types.
            string compositeName = compositeParent + "." + name;

            if (!foldoutDB.ContainsKey(compositeName))
            {
                AddFoldout(foldoutDB, compositeName, false);
            }
            bool showCompositeObject = Foldout(foldoutDB, compositeName);

            showCompositeObject = EditorGUILayout.Foldout(showCompositeObject, niceName);
            Foldout(foldoutDB, compositeName, showCompositeObject);
            if (showCompositeObject)
            {
                foreach (var field in valueElementType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
                {
                    bool shouldInspect = true;
                    if (field.IsPublic)
                    {
                        foreach (var attribute in field.GetCustomAttributes(true))
                        {
                            if (attribute is System.NonSerializedAttribute)
                            {
                                shouldInspect = false; break;
                            }
                            if (attribute is HideInInspector)
                            {
                                shouldInspect = false; break;
                            }
                        }
                    }
                    else
                    {
                        shouldInspect = false;
                        foreach (var attribute in field.GetCustomAttributes(true))
                        {
                            if (attribute is SerializeField)
                            {
                                shouldInspect = true;
                            }
                            if (attribute is HideInInspector)
                            {
                                shouldInspect = false; break;
                            }
                        }
                    }
                    if (shouldInspect)
                    {
                        object currentFieldValue = field.GetValue(currentValue);
                        bool   isFieldDirty      = false;
                        object newFieldValue     = ShowInInspector(field.Name, isReadOnly, hasSource, compositeName, field.FieldType, currentFieldValue, indentLevel + 1, foldoutDB, ref isFieldDirty, iStorage);
                        isDirty |= isFieldDirty;
                        if (!isReadOnly && isFieldDirty)
                        {
                            field.SetValue(currentValue, newFieldValue);
                        }
                    }
                }
            }
            return(currentValue);
        }