IsPersistent() private method

private IsPersistent ( Object target ) : bool
target Object
return bool
        static bool CreatePrefabVariantValidation()
        {
            var go = Selection.activeGameObject;

            return(go != null && EditorUtility.IsPersistent(go));
        }
        internal static IEnumerable <Object> DuplicateAssets(IEnumerable <Object> assets)
        {
            AssetDatabase.Refresh();

            var    copiedPaths = new List <string>();
            Object firstDuplicatedObjectToFail = null;

            foreach (var asset in assets)
            {
                var assetPath = AssetDatabase.GetAssetPath(asset);

                // if duplicating a sub-asset, then create a copy next to the main asset file
                if (!String.IsNullOrEmpty(assetPath) && AssetDatabase.IsSubAsset(asset))
                {
                    if (asset is ISubAssetNotDuplicatable)
                    {
                        firstDuplicatedObjectToFail = firstDuplicatedObjectToFail ? firstDuplicatedObjectToFail : asset;
                        continue;
                    }

                    var extension = NativeFormatImporterUtility.GetExtensionForAsset(asset);

                    // We dot sanitize or block unclean the asset filename (asset.name)
                    // since the assertdb will do it for us and has a whole tailored logic for that.

                    // It feels wrong that the asset name (that can apparently contain any char)
                    // is conflated with the orthogonal notion of filename. From the user's POV
                    // it will force an asset dup but with mangled names if the original name contained
                    // "invalid chars" for filenames.
                    // Path.Combine is not used here to avoid blocking asset names that might
                    // contain chars not allowed in filenames.
                    if ((new HashSet <char>(Path.GetInvalidFileNameChars())).Intersect(asset.name).Count() != 0)
                    {
                        Debug.LogWarning(string.Format("Duplicated asset name '{0}' contains invalid characters. Those will be replaced in the duplicated asset name.", asset.name));
                    }

                    var newPath = AssetDatabase.GenerateUniqueAssetPath(
                        string.Format("{0}{1}{2}.{3}",
                                      Path.GetDirectoryName(assetPath),
                                      Path.DirectorySeparatorChar,
                                      asset.name,
                                      extension)
                        );
                    AssetDatabase.CreateAsset(Object.Instantiate(asset), newPath);
                    copiedPaths.Add(newPath);
                }
                // otherwise duplicate the main asset file
                else if (EditorUtility.IsPersistent(asset))
                {
                    var newPath = AssetDatabase.GenerateUniqueAssetPath(assetPath);
                    if (newPath.Length > 0 && AssetDatabase.CopyAsset(assetPath, newPath))
                    {
                        copiedPaths.Add(newPath);
                    }
                }
            }

            if (firstDuplicatedObjectToFail != null)
            {
                var errString = string.Format(
                    "Duplication error: One or more sub assets (with types of {0}) can not be duplicated directly, use the appropriate editor instead",
                    firstDuplicatedObjectToFail.GetType().Name
                    );

                Debug.LogError(errString, firstDuplicatedObjectToFail);
            }

            AssetDatabase.Refresh();

            return(copiedPaths.Select(AssetDatabase.LoadMainAssetAtPath));
        }
示例#3
0
        internal static Object DoDropField(Rect position, int id, System.Type objType, ObjectFieldValidator validator, bool allowSceneObjects, GUIStyle style)
        {
            if (validator == null)
            {
                validator = ValidateObjectFieldAssignment;
            }
            Event     evt       = Event.current;
            EventType eventType = evt.type;

            // special case test, so we continue to ping/select objects with the object field disabled
            if (!GUI.enabled && GUIClip.enabled && (Event.current.rawType == EventType.MouseDown))
            {
                eventType = Event.current.rawType;
            }

            switch (eventType)
            {
            case EventType.DragExited:
                if (GUI.enabled)
                {
                    HandleUtility.Repaint();
                }
                break;

            case EventType.DragUpdated:
            case EventType.DragPerform:

                if (position.Contains(Event.current.mousePosition) && GUI.enabled)
                {
                    Object[] references      = DragAndDrop.objectReferences;
                    Object   validatedObject = validator(references, objType, null, ObjectFieldValidatorOptions.None);

                    if (validatedObject != null)
                    {
                        // If scene objects are not allowed and object is a scene object then clear
                        if (!allowSceneObjects && !EditorUtility.IsPersistent(validatedObject))
                        {
                            validatedObject = null;
                        }
                    }

                    if (validatedObject != null)
                    {
                        DragAndDrop.visualMode = DragAndDropVisualMode.Generic;
                        if (eventType == EventType.DragPerform)
                        {
                            GUI.changed = true;
                            DragAndDrop.AcceptDrag();
                            DragAndDrop.activeControlID = 0;
                            Event.current.Use();
                            return(validatedObject);
                        }
                        else
                        {
                            DragAndDrop.activeControlID = id;
                            Event.current.Use();
                        }
                    }
                }
                break;

            case EventType.Repaint:
                style.Draw(position, GUIContent.none, id, DragAndDrop.activeControlID == id);
                break;
            }
            return(null);
        }
示例#4
0
        public static void DoFixerUI(GameObject gameObject)
        {
            if (s_Styles == null)
            {
                s_Styles = new Styles();
            }

            var srpAsset = GraphicsSettings.currentRenderPipeline;

            var defaultSpeedTree8Shader = srpAsset != null ? srpAsset.defaultSpeedTree8Shader : null;

            if (defaultSpeedTree8Shader == null)
            {
                defaultSpeedTree8Shader = Shader.Find("Nature/SpeedTree8");
            }

            var defaultSpeedTree7Shader = srpAsset != null ? srpAsset.defaultSpeedTree7Shader : null;

            if (defaultSpeedTree7Shader == null)
            {
                defaultSpeedTree7Shader = Shader.Find("Nature/SpeedTree");
            }

            if (defaultSpeedTree8Shader == null || defaultSpeedTree7Shader == null)
            {
                return;
            }

            HashSet <Material> materialsUsedForBothVersion = null, speedTreeV7MaterialsToFix = null, speedTreeV8MaterialsToFix = null;

            foreach (var meshRenderer in EnumerateMeshRenderers(gameObject))
            {
                var meshFilter = meshRenderer.GetComponent <MeshFilter>();
                if (meshFilter == null)
                {
                    continue;
                }

                var mesh = meshFilter.sharedMesh;
                if (mesh == null || !EditorUtility.IsPersistent(mesh))
                {
                    continue;
                }

                var assetPath         = AssetDatabase.GetAssetPath(mesh);
                var speedTreeImporter = AssetImporter.GetAtPath(assetPath) as SpeedTreeImporter;
                if (speedTreeImporter == null)
                {
                    continue;
                }

                if (materialsUsedForBothVersion == null)
                {
                    materialsUsedForBothVersion = new HashSet <Material>();
                    speedTreeV7MaterialsToFix   = new HashSet <Material>();
                    speedTreeV8MaterialsToFix   = new HashSet <Material>();
                }

                bool meshIsV8 = speedTreeImporter.isV8;
                foreach (var material in meshRenderer.sharedMaterials)
                {
                    if (material == null)
                    {
                        continue;
                    }

                    // If the material is used for both v7 & v8 mesh: ignore.
                    if (materialsUsedForBothVersion.Contains(material))
                    {
                        continue;
                    }

                    // We only fix materials with wrong speedtree shader assigned. We don't know if it's "wrong" if user uses their custom shaders.
                    var wrongShader = meshIsV8 ? defaultSpeedTree7Shader : defaultSpeedTree8Shader;
                    if (material.shader != wrongShader)
                    {
                        continue;
                    }

                    var targetMaterialSet = meshIsV8 ? speedTreeV8MaterialsToFix : speedTreeV7MaterialsToFix;
                    var otherMaterialSet  = meshIsV8 ? speedTreeV7MaterialsToFix : speedTreeV8MaterialsToFix;

                    if (otherMaterialSet.Contains(material))
                    {
                        // rare case that the same material is used both for v7 & v8 material:
                        materialsUsedForBothVersion.Add(material);
                        otherMaterialSet.Remove(material);
                    }
                    else
                    {
                        targetMaterialSet.Add(material);
                    }
                }
            }

            // No speedtree meshes.
            if (materialsUsedForBothVersion == null)
            {
                return;
            }

            if (speedTreeV7MaterialsToFix.Count > 0 || speedTreeV8MaterialsToFix.Count > 0)
            {
                EditorGUILayout.Space();
                EditorGUILayout.HelpBox(s_Styles.Message, MessageType.Error);
                GUILayout.BeginHorizontal();
                GUILayout.FlexibleSpace();
                if (GUILayout.Button(s_Styles.FixSpeedTreeShaders, GUILayout.ExpandWidth(false)))
                {
                    Undo.RecordObjects(speedTreeV7MaterialsToFix.Concat(speedTreeV8MaterialsToFix).ToArray(), "Fix SpeedTree Shaders");
                    foreach (var material in speedTreeV7MaterialsToFix)
                    {
                        material.shader = defaultSpeedTree7Shader;
                    }
                    foreach (var material in speedTreeV8MaterialsToFix)
                    {
                        material.shader = defaultSpeedTree8Shader;
                    }
                }
                GUILayout.EndHorizontal();
            }

            if (materialsUsedForBothVersion.Count != 0)
            {
                EditorGUILayout.Space();
                EditorGUILayout.HelpBox("Some of the materials are used for both SpeedTree 7 and SpeedTree 8 assets. Unity won't be able to fix that. Please create separate materials.", MessageType.Error);
            }
        }
示例#5
0
        static Object DoObjectField(Rect position, Rect dropRect, int id, Object obj, Object objBeingEdited, System.Type objType, System.Type additionalType, SerializedProperty property, ObjectFieldValidator validator, bool allowSceneObjects, GUIStyle style, GUIStyle buttonStyle)
        {
            if (validator == null)
            {
                validator = ValidateObjectFieldAssignment;
            }
            if (property != null)
            {
                obj = property.objectReferenceValue;
            }
            Event     evt       = Event.current;
            EventType eventType = evt.type;

            // special case test, so we continue to ping/select objects with the object field disabled
            if (!GUI.enabled && GUIClip.enabled && (Event.current.rawType == EventType.MouseDown))
            {
                eventType = Event.current.rawType;
            }

            bool hasThumbnail = EditorGUIUtility.HasObjectThumbnail(objType);

            // Determine visual type
            ObjectFieldVisualType visualType = ObjectFieldVisualType.IconAndText;

            if (hasThumbnail && position.height <= kObjectFieldMiniThumbnailHeight && position.width <= kObjectFieldMiniThumbnailWidth)
            {
                visualType = ObjectFieldVisualType.MiniPreview;
            }
            else if (hasThumbnail && position.height > kSingleLineHeight)
            {
                visualType = ObjectFieldVisualType.LargePreview;
            }

            Vector2 oldIconSize = EditorGUIUtility.GetIconSize();

            if (visualType == ObjectFieldVisualType.IconAndText)
            {
                EditorGUIUtility.SetIconSize(new Vector2(12, 12));  // Have to be this small to fit inside a single line height ObjectField
            }
            else if (visualType == ObjectFieldVisualType.LargePreview)
            {
                EditorGUIUtility.SetIconSize(new Vector2(64, 64));
            }

            if ((eventType == EventType.MouseDown && Event.current.button == 1 ||
                 (eventType == EventType.ContextClick && visualType == ObjectFieldVisualType.IconAndText)) &&
                position.Contains(Event.current.mousePosition))
            {
                var actualObject = property != null ? property.objectReferenceValue : obj;
                var contextMenu  = new GenericMenu();

                if (FillPropertyContextMenu(property, null, contextMenu) != null)
                {
                    contextMenu.AddSeparator("");
                }
                contextMenu.AddItem(GUIContent.Temp("Properties..."), false, () => PropertyEditor.OpenPropertyEditor(actualObject));
                contextMenu.DropDown(position);
                Event.current.Use();
            }

            switch (eventType)
            {
            case EventType.DragExited:
                if (GUI.enabled)
                {
                    HandleUtility.Repaint();
                }

                break;

            case EventType.DragUpdated:
            case EventType.DragPerform:

                if (eventType == EventType.DragPerform)
                {
                    string errorString;
                    if (!ValidDroppedObject(DragAndDrop.objectReferences, objType, out errorString))
                    {
                        Object reference = DragAndDrop.objectReferences[0];
                        EditorUtility.DisplayDialog("Can't assign script", errorString, "OK");
                        break;
                    }
                }

                if (dropRect.Contains(Event.current.mousePosition) && GUI.enabled)
                {
                    Object[] references      = DragAndDrop.objectReferences;
                    Object   validatedObject = validator(references, objType, property, ObjectFieldValidatorOptions.None);

                    if (validatedObject != null)
                    {
                        // If scene objects are not allowed and object is a scene object then clear
                        if (!allowSceneObjects && !EditorUtility.IsPersistent(validatedObject))
                        {
                            validatedObject = null;
                        }
                    }

                    if (validatedObject != null)
                    {
                        DragAndDrop.visualMode = DragAndDropVisualMode.Generic;
                        if (eventType == EventType.DragPerform)
                        {
                            if (property != null)
                            {
                                property.objectReferenceValue = validatedObject;
                            }
                            else
                            {
                                obj = validatedObject;
                            }

                            GUI.changed = true;
                            DragAndDrop.AcceptDrag();
                            DragAndDrop.activeControlID = 0;
                        }
                        else
                        {
                            DragAndDrop.activeControlID = id;
                        }
                        Event.current.Use();
                    }
                }
                break;

            case EventType.MouseDown:
                if (position.Contains(Event.current.mousePosition) && Event.current.button == 0)
                {
                    // Get button rect for Object Selector
                    Rect buttonRect = GetButtonRect(visualType, position);

                    EditorGUIUtility.editingTextField = false;

                    if (buttonRect.Contains(Event.current.mousePosition))
                    {
                        if (GUI.enabled)
                        {
                            GUIUtility.keyboardControl = id;
                            var types = additionalType == null ? new Type[] { objType } : new Type[] { objType, additionalType };
                            if (property != null)
                            {
                                ObjectSelector.get.Show(types, property, allowSceneObjects);
                            }
                            else
                            {
                                ObjectSelector.get.Show(obj, types, objBeingEdited, allowSceneObjects);
                            }
                            ObjectSelector.get.objectSelectorID = id;

                            evt.Use();
                            GUIUtility.ExitGUI();
                        }
                    }
                    else
                    {
                        Object    actualTargetObject = property != null ? property.objectReferenceValue : obj;
                        Component com = actualTargetObject as Component;
                        if (com)
                        {
                            actualTargetObject = com.gameObject;
                        }
                        if (showMixedValue)
                        {
                            actualTargetObject = null;
                        }

                        // One click shows where the referenced object is, or pops up a preview
                        if (Event.current.clickCount == 1)
                        {
                            GUIUtility.keyboardControl = id;

                            PingObjectOrShowPreviewOnClick(actualTargetObject, position);
                            var selectedMaterial = actualTargetObject as Material;
                            if (selectedMaterial != null)
                            {
                                PingObjectInSceneViewOnClick(selectedMaterial);
                            }
                            evt.Use();
                        }
                        // Double click opens the asset in external app or changes selection to referenced object
                        else if (Event.current.clickCount == 2)
                        {
                            if (actualTargetObject)
                            {
                                AssetDatabase.OpenAsset(actualTargetObject);
                                evt.Use();
                                GUIUtility.ExitGUI();
                            }
                        }
                    }
                }
                break;

            case EventType.ExecuteCommand:
                string commandName = evt.commandName;
                if (commandName == ObjectSelector.ObjectSelectorUpdatedCommand && ObjectSelector.get.objectSelectorID == id && GUIUtility.keyboardControl == id && (property == null || !property.isScript))
                {
                    return(AssignSelectedObject(property, validator, objType, evt));
                }
                else if (commandName == ObjectSelector.ObjectSelectorClosedCommand && ObjectSelector.get.objectSelectorID == id && GUIUtility.keyboardControl == id && property != null && property.isScript)
                {
                    if (ObjectSelector.get.GetInstanceID() == 0)
                    {
                        // User canceled object selection; don't apply
                        evt.Use();
                        break;
                    }
                    return(AssignSelectedObject(property, validator, objType, evt));
                }
                else if ((evt.commandName == EventCommandNames.Delete || evt.commandName == EventCommandNames.SoftDelete) && GUIUtility.keyboardControl == id)
                {
                    if (property != null)
                    {
                        property.objectReferenceValue = null;
                    }
                    else
                    {
                        obj = null;
                    }

                    GUI.changed = true;
                    evt.Use();
                }
                break;

            case EventType.ValidateCommand:
                if ((evt.commandName == EventCommandNames.Delete || evt.commandName == EventCommandNames.SoftDelete) && GUIUtility.keyboardControl == id)
                {
                    evt.Use();
                }
                break;

            case EventType.KeyDown:
                if (GUIUtility.keyboardControl == id)
                {
                    if (evt.keyCode == KeyCode.Backspace || (evt.keyCode == KeyCode.Delete && (evt.modifiers & EventModifiers.Shift) == 0))
                    {
                        if (property != null)
                        {
                            if (property.propertyPath.EndsWith("]"))
                            {
                                var  parentArrayPropertyPath = property.propertyPath.Substring(0, property.propertyPath.LastIndexOf(".Array.data[", StringComparison.Ordinal));
                                var  parentArrayProperty     = property.serializedObject.FindProperty(parentArrayPropertyPath);
                                bool isReorderableList       = PropertyHandler.s_reorderableLists.ContainsKey(ReorderableListWrapper.GetPropertyIdentifier(parentArrayProperty));

                                // If it's an element of an non-orderable array and it is displayed inside a list, remove that element from the array (cases 1379541 & 1335322)
                                if (!isReorderableList && GUI.isInsideList && GetInsideListDepth() == parentArrayProperty.depth)
                                {
                                    TargetChoiceHandler.DeleteArrayElement(property);
                                }
                                else
                                {
                                    property.objectReferenceValue = null;
                                }
                            }
                            else
                            {
                                property.objectReferenceValue = null;
                            }
                        }
                        else
                        {
                            obj = null;
                        }

                        GUI.changed = true;
                        evt.Use();
                    }

                    // Apparently we have to check for the character being space instead of the keyCode,
                    // otherwise the Inspector will maximize upon pressing space.
                    if (evt.MainActionKeyForControl(id))
                    {
                        var types = additionalType == null ? new Type[] { objType } : new Type[] { objType, additionalType };
                        if (property != null)
                        {
                            ObjectSelector.get.Show(types, property, allowSceneObjects);
                        }
                        else
                        {
                            ObjectSelector.get.Show(obj, types, objBeingEdited, allowSceneObjects);
                        }
                        ObjectSelector.get.objectSelectorID = id;
                        evt.Use();
                        GUIUtility.ExitGUI();
                    }
                }
                break;

            case EventType.Repaint:
                GUIContent temp;
                if (showMixedValue)
                {
                    temp = s_MixedValueContent;
                }
                else
                {
                    // If obj or objType are both null, we have to rely on
                    // property.objectReferenceStringValue to display None/Missing and the
                    // correct type. But if not, EditorGUIUtility.ObjectContent is more reliable.
                    // It can take a more specific object type specified as argument into account,
                    // and it gets the icon at the same time.
                    if (obj == null && objType == null && property != null)
                    {
                        temp = EditorGUIUtility.TempContent(property.objectReferenceStringValue);
                    }
                    else
                    {
                        // In order for ObjectContext to be able to distinguish between None/Missing,
                        // we need to supply an instanceID. For some reason, getting the instanceID
                        // from property.objectReferenceValue is not reliable, so we have to
                        // explicitly check property.objectReferenceInstanceIDValue if a property exists.
                        if (property != null)
                        {
                            temp = EditorGUIUtility.ObjectContent(obj, objType, property.objectReferenceInstanceIDValue);
                        }
                        else
                        {
                            temp = EditorGUIUtility.ObjectContent(obj, objType);
                        }
                    }

                    if (property != null)
                    {
                        if (obj != null)
                        {
                            Object[] references = { obj };
                            if (EditorSceneManager.preventCrossSceneReferences && CheckForCrossSceneReferencing(obj, property.serializedObject.targetObject))
                            {
                                if (!EditorApplication.isPlaying)
                                {
                                    temp = s_SceneMismatch;
                                }
                                else
                                {
                                    temp.text = temp.text + string.Format(" ({0})", GetGameObjectFromObject(obj).scene.name);
                                }
                            }
                            else if (validator(references, objType, property, ObjectFieldValidatorOptions.ExactObjectTypeValidation) == null)
                            {
                                temp = s_TypeMismatch;
                            }
                        }
                    }
                }

                switch (visualType)
                {
                case ObjectFieldVisualType.IconAndText:
                    BeginHandleMixedValueContentColor();
                    style.Draw(position, temp, id, DragAndDrop.activeControlID == id, position.Contains(Event.current.mousePosition));

                    Rect buttonRect = buttonStyle.margin.Remove(GetButtonRect(visualType, position));
                    buttonStyle.Draw(buttonRect, GUIContent.none, id, DragAndDrop.activeControlID == id, buttonRect.Contains(Event.current.mousePosition));
                    EndHandleMixedValueContentColor();
                    break;

                case ObjectFieldVisualType.LargePreview:
                    DrawObjectFieldLargeThumb(position, id, obj, temp);
                    break;

                case ObjectFieldVisualType.MiniPreview:
                    DrawObjectFieldMiniThumb(position, id, obj, temp);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
                break;
            }

            EditorGUIUtility.SetIconSize(oldIconSize);

            return(obj);
        }
示例#6
0
        internal static void AddGameObjectsToPrefabAndConnect(GameObject[] gameObjects, Object targetPrefab)
        {
            if (gameObjects == null)
            {
                throw new ArgumentNullException("gameObjects");
            }

            if (gameObjects.Length == 0)
            {
                throw new ArgumentException("gameObjects array is empty");
            }

            if (targetPrefab == null)
            {
                throw new ArgumentNullException("targetPrefab");
            }

            if (!PrefabUtility.IsPartOfPrefabAsset(targetPrefab))
            {
                throw new ArgumentException("Target Prefab has to be a Prefab Asset");
            }

            Object targetPrefabInstance = null;

            var targetPrefabObject = PrefabUtility.GetPrefabAssetHandle(targetPrefab);

            foreach (GameObject go in gameObjects)
            {
                if (go == null)
                {
                    throw new ArgumentException("GameObject in input 'gameObjects' array is null");
                }

                if (EditorUtility.IsPersistent(go))  // Prefab asset
                {
                    throw new ArgumentException("Game object is part of a prefab");
                }

                var parentPrefabInstance = GetParentPrefabInstance(go);
                if (parentPrefabInstance == null)
                {
                    throw new ArgumentException("GameObject is not (directly) parented under a target Prefab instance.");
                }

                if (targetPrefabInstance == null)
                {
                    targetPrefabInstance = parentPrefabInstance;
                    if (!IsPrefabInstanceObjectOf(go.transform.parent, targetPrefabObject))
                    {
                        throw new ArgumentException("GameObject is not parented under a target Prefab instance.");
                    }
                }
                else
                {
                    if (parentPrefabInstance != targetPrefabInstance)
                    {
                        throw new ArgumentException("GameObjects must be parented under the same Prefab instance.");
                    }
                }

                if (PrefabUtility.IsPartOfNonAssetPrefabInstance(go))
                {
                    var correspondingGO             = PrefabUtility.GetCorrespondingObjectFromSource(go);
                    var correspondingGOPrefabObject = PrefabUtility.GetPrefabAssetHandle(correspondingGO);
                    if (targetPrefabObject == correspondingGOPrefabObject)
                    {
                        throw new ArgumentException("GameObject is already part of target prefab");
                    }
                }
            }

            string prefabGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(targetPrefab));

            if (!VerifyNestingFromScript(gameObjects, prefabGUID, null))
            {
                throw new ArgumentException("Cyclic nesting detected");
            }

            AddGameObjectsToPrefabAndConnect_Internal(gameObjects, targetPrefab);
        }
示例#7
0
        internal static Object DoObjectField(Rect position, Rect dropRect, int id, Object obj, System.Type objType, SerializedProperty property, ObjectFieldValidator validator, bool allowSceneObjects, GUIStyle style)
        {
            if (validator == null)
            {
                validator = ValidateObjectFieldAssignment;
            }
            Event     evt       = Event.current;
            EventType eventType = evt.type;

            // special case test, so we continue to ping/select objects with the object field disabled
            if (!GUI.enabled && GUIClip.enabled && (Event.current.rawType == EventType.MouseDown))
            {
                eventType = Event.current.rawType;
            }

            bool hasThumbnail = EditorGUIUtility.HasObjectThumbnail(objType);

            // Determine visual type
            ObjectFieldVisualType visualType = ObjectFieldVisualType.IconAndText;

            if (hasThumbnail && position.height <= kObjectFieldMiniThumbnailHeight && position.width <= kObjectFieldMiniThumbnailWidth)
            {
                visualType = ObjectFieldVisualType.MiniPreview;
            }
            else if (hasThumbnail && position.height > kSingleLineHeight)
            {
                visualType = ObjectFieldVisualType.LargePreview;
            }

            Vector2 oldIconSize = EditorGUIUtility.GetIconSize();

            if (visualType == ObjectFieldVisualType.IconAndText)
            {
                EditorGUIUtility.SetIconSize(new Vector2(12, 12));  // Have to be this small to fit inside a single line height ObjectField
            }
            else if (visualType == ObjectFieldVisualType.LargePreview)
            {
                EditorGUIUtility.SetIconSize(new Vector2(64, 64));
            }

            switch (eventType)
            {
            case EventType.DragExited:
                if (GUI.enabled)
                {
                    HandleUtility.Repaint();
                }

                break;

            case EventType.DragUpdated:
            case EventType.DragPerform:

                if (dropRect.Contains(Event.current.mousePosition) && GUI.enabled)
                {
                    Object[] references      = DragAndDrop.objectReferences;
                    Object   validatedObject = validator(references, objType, property, ObjectFieldValidatorOptions.None);

                    if (validatedObject != null)
                    {
                        // If scene objects are not allowed and object is a scene object then clear
                        if (!allowSceneObjects && !EditorUtility.IsPersistent(validatedObject))
                        {
                            validatedObject = null;
                        }
                    }

                    if (validatedObject != null)
                    {
                        DragAndDrop.visualMode = DragAndDropVisualMode.Generic;
                        if (eventType == EventType.DragPerform)
                        {
                            if (property != null)
                            {
                                property.objectReferenceValue = validatedObject;
                            }
                            else
                            {
                                obj = validatedObject;
                            }

                            GUI.changed = true;
                            DragAndDrop.AcceptDrag();
                            DragAndDrop.activeControlID = 0;
                        }
                        else
                        {
                            DragAndDrop.activeControlID = id;
                        }
                        Event.current.Use();
                    }
                }
                break;

            case EventType.MouseDown:
                // Ignore right clicks
                if (Event.current.button != 0)
                {
                    break;
                }
                if (position.Contains(Event.current.mousePosition))
                {
                    // Get button rect for Object Selector
                    Rect buttonRect;
                    switch (visualType)
                    {
                    case ObjectFieldVisualType.IconAndText:
                    case ObjectFieldVisualType.MiniPreview:
                        buttonRect = new Rect(position.xMax - 15, position.y, 15, position.height);
                        break;

                    case ObjectFieldVisualType.LargePreview:
                        buttonRect = new Rect(position.xMax - 36, position.yMax - 14, 36, 14);
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }

                    EditorGUIUtility.editingTextField = false;

                    if (buttonRect.Contains(Event.current.mousePosition))
                    {
                        if (GUI.enabled)
                        {
                            GUIUtility.keyboardControl = id;
                            ObjectSelector.get.Show(obj, objType, property, allowSceneObjects);
                            ObjectSelector.get.objectSelectorID = id;

                            evt.Use();
                            GUIUtility.ExitGUI();
                        }
                    }
                    else
                    {
                        Object    actualTargetObject = property != null ? property.objectReferenceValue : obj;
                        Component com = actualTargetObject as Component;
                        if (com)
                        {
                            actualTargetObject = com.gameObject;
                        }
                        if (showMixedValue)
                        {
                            actualTargetObject = null;
                        }

                        // One click shows where the referenced object is, or pops up a preview
                        if (Event.current.clickCount == 1)
                        {
                            GUIUtility.keyboardControl = id;

                            PingObjectOrShowPreviewOnClick(actualTargetObject, position);
                            evt.Use();
                        }
                        // Double click opens the asset in external app or changes selection to referenced object
                        else if (Event.current.clickCount == 2)
                        {
                            if (actualTargetObject)
                            {
                                AssetDatabase.OpenAsset(actualTargetObject);
                                GUIUtility.ExitGUI();
                            }
                            evt.Use();
                        }
                    }
                }
                break;

            case EventType.ExecuteCommand:
                string commandName = evt.commandName;
                if (commandName == ObjectSelector.ObjectSelectorUpdatedCommand && ObjectSelector.get.objectSelectorID == id && GUIUtility.keyboardControl == id && (property == null || !property.isScript))
                {
                    return(AssignSelectedObject(property, validator, objType, evt));
                }
                else if (commandName == ObjectSelector.ObjectSelectorClosedCommand && ObjectSelector.get.objectSelectorID == id && GUIUtility.keyboardControl == id && property != null && property.isScript)
                {
                    if (ObjectSelector.get.GetInstanceID() == 0)
                    {
                        // User canceled object selection; don't apply
                        evt.Use();
                        break;
                    }
                    return(AssignSelectedObject(property, validator, objType, evt));
                }
                break;

            case EventType.KeyDown:
                if (GUIUtility.keyboardControl == id)
                {
                    if (evt.keyCode == KeyCode.Backspace || evt.keyCode == KeyCode.Delete)
                    {
                        if (property != null)
                        {
                            property.objectReferenceValue = null;
                        }
                        else
                        {
                            obj = null;
                        }

                        GUI.changed = true;
                        evt.Use();
                    }

                    // Apparently we have to check for the character being space instead of the keyCode,
                    // otherwise the Inspector will maximize upon pressing space.
                    if (evt.MainActionKeyForControl(id))
                    {
                        ObjectSelector.get.Show(obj, objType, property, allowSceneObjects);
                        ObjectSelector.get.objectSelectorID = id;
                        evt.Use();
                        GUIUtility.ExitGUI();
                    }
                }
                break;

            case EventType.Repaint:
                GUIContent temp;
                if (showMixedValue)
                {
                    temp = s_MixedValueContent;
                }
                else if (property != null)
                {
                    temp = EditorGUIUtility.TempContent(property.objectReferenceStringValue, AssetPreview.GetMiniThumbnail(property.objectReferenceValue));
                    obj  = property.objectReferenceValue;
                    if (obj != null)
                    {
                        Object[] references = { obj };
                        if (EditorSceneManager.preventCrossSceneReferences && CheckForCrossSceneReferencing(obj, property.serializedObject.targetObject))
                        {
                            if (!EditorApplication.isPlaying)
                            {
                                temp = s_SceneMismatch;
                            }
                            else
                            {
                                temp.text = temp.text + string.Format(" ({0})", GetGameObjectFromObject(obj).scene.name);
                            }
                        }
                        else if (validator(references, objType, property, ObjectFieldValidatorOptions.ExactObjectTypeValidation) == null)
                        {
                            temp = s_TypeMismatch;
                        }
                    }
                }
                else
                {
                    temp = EditorGUIUtility.ObjectContent(obj, objType);
                }

                switch (visualType)
                {
                case ObjectFieldVisualType.IconAndText:
                    BeginHandleMixedValueContentColor();
                    style.Draw(position, temp, id, DragAndDrop.activeControlID == id, position.Contains(Event.current.mousePosition));
                    EndHandleMixedValueContentColor();
                    break;

                case ObjectFieldVisualType.LargePreview:
                    DrawObjectFieldLargeThumb(position, id, obj, temp);
                    break;

                case ObjectFieldVisualType.MiniPreview:
                    DrawObjectFieldMiniThumb(position, id, obj, temp);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
                break;
            }

            EditorGUIUtility.SetIconSize(oldIconSize);

            return(obj);
        }
示例#8
0
        internal static void DisplayObjectContextMenu(Rect position, Object[] context, int contextUserData)
        {
            // Don't show context menu if we're inside the side-by-side diff comparison.
            if (EditorGUIUtility.comparisonViewMode != EditorGUIUtility.ComparisonViewMode.None)
            {
                return;
            }

            Vector2 temp = GUIUtility.GUIToScreenPoint(new Vector2(position.x, position.y));

            position.x = temp.x;
            position.y = temp.y;

            GenericMenu pm = new GenericMenu();

            if (context != null && context.Length == 1 && context[0] is Component)
            {
                Object    targetObject    = context[0];
                Component targetComponent = (Component)targetObject;

                // Do nothing if component is not on a prefab instance.
                if (PrefabUtility.GetCorrespondingConnectedObjectFromSource(targetComponent.gameObject) == null)
                {
                }
                // Handle added component.
                else if (PrefabUtility.GetCorrespondingObjectFromSource(targetObject) == null && targetComponent != null)
                {
                    GameObject instanceGo = targetComponent.gameObject;
                    PrefabUtility.HandleApplyRevertMenuItems(
                        "Added Component",
                        instanceGo,
                        (menuItemContent, sourceGo) =>
                    {
                        TargetChoiceHandler.ObjectInstanceAndSourcePathInfo info = new TargetChoiceHandler.ObjectInstanceAndSourcePathInfo();
                        info.instanceObject   = targetComponent;
                        info.assetPath        = AssetDatabase.GetAssetPath(sourceGo);
                        GameObject rootObject = PrefabUtility.GetRootGameObject(sourceGo);
                        if (!PrefabUtility.IsPartOfPrefabThatCanBeAppliedTo(rootObject) || EditorUtility.IsPersistent(instanceGo))
                        {
                            pm.AddDisabledItem(menuItemContent);
                        }
                        else
                        {
                            pm.AddItem(menuItemContent, false, TargetChoiceHandler.ApplyPrefabAddedComponent, info);
                        }
                    },
                        (menuItemContent) =>
                    {
                        pm.AddItem(menuItemContent, false, TargetChoiceHandler.RevertPrefabAddedComponent, targetComponent);
                    }
                        );
                }
                else
                {
                    SerializedObject   so       = new SerializedObject(targetObject);
                    SerializedProperty property = so.GetIterator();
                    bool hasPrefabOverride      = false;
                    while (property.Next(property.hasChildren))
                    {
                        if (property.isInstantiatedPrefab && property.prefabOverride && !property.isDefaultOverride)
                        {
                            hasPrefabOverride = true;
                            break;
                        }
                    }

                    // Handle modified component.
                    if (hasPrefabOverride)
                    {
                        bool defaultOverrides =
                            PrefabUtility.IsObjectOverrideAllDefaultOverridesComparedToAnySource(targetObject);

                        PrefabUtility.HandleApplyRevertMenuItems(
                            "Modified Component",
                            targetObject,
                            (menuItemContent, sourceObject) =>
                        {
                            TargetChoiceHandler.ObjectInstanceAndSourcePathInfo info = new TargetChoiceHandler.ObjectInstanceAndSourcePathInfo();
                            info.instanceObject   = targetObject;
                            info.assetPath        = AssetDatabase.GetAssetPath(sourceObject);
                            GameObject rootObject = PrefabUtility.GetRootGameObject(sourceObject);
                            if (!PrefabUtility.IsPartOfPrefabThatCanBeAppliedTo(rootObject) || EditorUtility.IsPersistent(targetObject))
                            {
                                pm.AddDisabledItem(menuItemContent);
                            }
                            else
                            {
                                pm.AddItem(menuItemContent, false, TargetChoiceHandler.ApplyPrefabObjectOverride, info);
                            }
                        },
                            (menuItemContent) =>
                        {
                            pm.AddItem(menuItemContent, false, TargetChoiceHandler.RevertPrefabObjectOverride, targetObject);
                        },
                            defaultOverrides
                            );
                    }
                }
            }

            pm.ObjectContextDropDown(position, context, contextUserData);

            ResetMouseDown();
        }
示例#9
0
        internal void Show(UnityObject obj, Type requiredType, SerializedProperty property, bool allowSceneObjects, List <int> allowedInstanceIDs, Action <UnityObject> onObjectSelectorClosed, Action <UnityObject> onObjectSelectedUpdated)
        {
            m_ObjectSelectorReceiver = null;
            m_AllowSceneObjects      = allowSceneObjects;
            m_IsShowingAssets        = true;
            m_AllowedIDs             = allowedInstanceIDs;

            m_OnObjectSelectorClosed  = onObjectSelectorClosed;
            m_OnObjectSelectorUpdated = onObjectSelectedUpdated;

            if (property != null)
            {
                if (requiredType == null)
                {
                    ScriptAttributeUtility.GetFieldInfoFromProperty(property, out requiredType);
                    // case 951876: built-in types do not actually have reflectable fields, so their object types must be extracted from the type string
                    // this works because built-in types will only ever have serialized references to other built-in types, which this window's filter expects as unqualified names
                    if (requiredType == null)
                    {
                        m_RequiredType = s_MatchPPtrTypeName.Match(property.type).Groups[1].Value;
                    }
                }

                obj = property.objectReferenceValue;
                m_ObjectBeingEdited = property.serializedObject.targetObject;

                // Do not allow to show scene objects if the object being edited is persistent
                if (m_ObjectBeingEdited != null && EditorUtility.IsPersistent(m_ObjectBeingEdited))
                {
                    m_AllowSceneObjects = false;
                }
            }

            // Set which tab should be visible at startup
            if (m_AllowSceneObjects)
            {
                if (obj != null)
                {
                    if (typeof(Component).IsAssignableFrom(obj.GetType()))
                    {
                        obj = ((Component)obj).gameObject;
                    }
                    // Set the right tab visible (so we can see our selection)
                    m_IsShowingAssets = EditorUtility.IsPersistent(obj);
                }
                else
                {
                    m_IsShowingAssets = (requiredType != typeof(GameObject) && !typeof(Component).IsAssignableFrom(requiredType));
                }
            }
            else
            {
                m_IsShowingAssets = true;
            }

            // Set member variables
            m_DelegateView = GUIView.current;
            // type filter requires unqualified names for built-in types, but will prioritize them over user types, so ensure user types are namespace-qualified
            if (requiredType != null)
            {
                m_RequiredType = typeof(ScriptableObject).IsAssignableFrom(requiredType) || typeof(MonoBehaviour).IsAssignableFrom(requiredType) ? requiredType.FullName : requiredType.Name;
            }
            m_SearchFilter      = "";
            m_OriginalSelection = obj;
            m_ModalUndoGroup    = Undo.GetCurrentGroup();

            // Freeze to prevent flicker on OSX.
            // Screen will be updated again when calling
            // SetFreezeDisplay(false) further down.
            ContainerWindow.SetFreezeDisplay(true);

            ShowWithMode(ShowMode.AuxWindow);
            titleContent = EditorGUIUtility.TrTextContent("Select " + (requiredType == null ? m_RequiredType : requiredType.Name));

            // Deal with window size
            Rect p = m_Parent.window.position;

            p.width  = EditorPrefs.GetFloat("ObjectSelectorWidth", 200);
            p.height = EditorPrefs.GetFloat("ObjectSelectorHeight", 390);
            position = p;
            minSize  = new Vector2(kMinWidth, kMinTopSize + kPreviewExpandedAreaHeight + 2 * kPreviewMargin);
            maxSize  = new Vector2(10000, 10000);
            SetupPreview();

            // Focus
            Focus();
            ContainerWindow.SetFreezeDisplay(false);

            m_FocusSearchFilter = true;

            // Add after unfreezing display because AuxWindowManager.cpp assumes that aux windows are added after we get 'got/lost'- focus calls.
            m_Parent.AddToAuxWindowList();

            // Initial selection
            int initialSelection = obj != null?obj.GetInstanceID() : 0;

            if (property != null && property.hasMultipleDifferentValues)
            {
                initialSelection = 0; // don't select anything on multi selection
            }
            if (ShouldTreeViewBeUsed(requiredType))
            {
                m_ObjectTreeWithSearch.Init(position, this, CreateAndSetTreeView, TreeViewSelection, ItemWasDoubleClicked, initialSelection, 0);
            }
            else
            {
                // To frame the selected item we need to wait to initialize the search until our window has been setup
                InitIfNeeded();
                m_ListArea.InitSelection(new[] { initialSelection });
                if (initialSelection != 0)
                {
                    m_ListArea.Frame(initialSelection, true, false);
                }
            }
        }