Example #1
0
        /// <summary>
        /// Returns all instances matching pathName
        /// </summary>
        /// <param name="pathName">is interpreted as either a path or a name</param>
        /// <returns></returns>
        /// <remarks>
        /// Counterpart to GameObject.Find(string) this returns all matching instances, instead of one.
        /// Names beginning with '/' indicate objects at the root of the scene.
        /// Names including '/' will be traversed as a path beginning from the first matched object.
        /// </remarks>
        public static GameObject[] FindAll(string pathName)
        {
            // PROBLEM: Actually, empty names are allowed...
            // Empty object names are not allowed
            if (pathName.Length == 0)
            {
                return(new GameObject[0]);
            }

            // This behavior is consistent with GameObject.Find()
            if (pathName[0] != '/')
            {
                return(NameFind(pathName));
            }

            // Search by path
            // IMPORTANT: PathName names begin with the name of a GameObject, so "/" is dropped
            var path = new PathName(pathName.Substring(1), PathName.PathStep.Step.Path);

            var transformList  = path.Find();
            var gameObjectList = new List <GameObject>();

            foreach (var transform in transformList)
            {
                gameObjectList.Add(transform.gameObject);
            }
            return(gameObjectList.ToArray());
        }
Example #2
0
            public EditGameObject(GameObject gameObject)
            {
                if (useEditorAction)
                {
#if UNITY_EDITOR
                    editObjectType = GetGameObjectType(gameObject);
                    switch (editObjectType)
                    {
                    case GameObjectType.Persistent: {
                        // Load as PreviewScene Object
                        editAssetPath = AssetDatabase.GetAssetPath(gameObject);
                        editPrefab    = PrefabUtility.LoadPrefabContents(editAssetPath);
                        editObject    = editPrefab;
                        break;
                    }

                    case GameObjectType.Connected: {
                        // Path to gameObject relative to prefab
                        // NOTE: EditorSceneManager.IsPreviewSceneObject(editPrefab) == true
                        var prefab = PrefabUtility.GetNearestPrefabInstanceRoot(gameObject);
                        var path   = new PathName(gameObject, prefab);

                        // Instantiate a copy of prefab and locate copy of gameObject
                        var asset = PrefabUtility.GetCorrespondingObjectFromSource(prefab);
                        editAssetPath = AssetDatabase.GetAssetPath(asset);
                        editPrefab    = PrefabUtility.InstantiatePrefab(asset) as GameObject;
                        var editObjectList = path.Find(editPrefab.transform);
                        if (editObjectList.Length == 1)
                        {
                            editObject = editObjectList[0].gameObject;
                        }
                        break;
                    }

                    case GameObjectType.Instance:
                        editObject = gameObject;
                        break;
                    }

                    if (Application.isBatchMode)
                    {
                        EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
                    }
                    else
                    {
                        // QUESTION: Does this work for prefabs?
                        Undo.RecordObject(gameObject, $"Edit {gameObject.name}");
                    }
#endif
                }
                else
                {
                    editObject = gameObject;
                }
            }
Example #3
0
        /// <returns>an array of all GameObjects identified by path from parent</returns>
        /// <remarks>
        /// When parent = null the search begins with the scene root.
        /// </remarks>
        public static GameObject[] PathFind(PathName path, Transform parent = null)
        {
            var transformList  = path.Find(parent);
            var gameObjectList = new List <GameObject>();

            foreach (var transform in transformList)
            {
                gameObjectList.Add(transform.gameObject);
            }
            return(gameObjectList.ToArray());
        }
Example #4
0
        // WARNING: If there is a name override, PathName will not resolve!

        // TODO: Find a way to clone prefab with overrides intact.
        // QUESTION: Is there a way to accomplish instatiation using object serializations?
        // Ideally, this would handle the connection and override persistence.
        // https://docs.unity3d.com/ScriptReference/SerializedObject.html
        // Construct, then iterate & copy?

        static GameObject InstantiateChild(GameObject original, GameObject parent)
        {
            GameObject child = null;
            // IMPORTANT: PrefabUtility.InstantiatePrefab applies only to assets, not to instances
            // IMPORTANT: PrefabUtility.GetCorrespondingObjectFromSource applies only to instances, not to assets
            var        asset      = PrefabUtility.GetCorrespondingObjectFromSource(parent);
            GameObject copy_asset = null;

            if (asset)
            {
                copy_asset = asset;
            }
            else
            {
                copy_asset = original;
            }
            var copy = PrefabUtility.InstantiatePrefab(copy_asset) as GameObject;

            if (parent != original)
            {
                var path = new PathName(original, parent);
                var find = path.Find(copy.transform);
                if (find.Length == 1)
                {
                    child = find[0].gameObject;
                    // Unpack to enable orphaning, only once since nearest root was instantiated
                    var unpack = PrefabUtility.GetOutermostPrefabInstanceRoot(child);
                    while (unpack)
                    {
                        PrefabUtility.UnpackPrefabInstance(unpack, PrefabUnpackMode.OutermostRoot, InteractionMode.AutomatedAction);
                        unpack = PrefabUtility.GetOutermostPrefabInstanceRoot(child);
                    }
                    child.transform.SetParent(null);
                }
                EP.Destroy(copy);
            }
            else
            {
                child = copy;
            }
            return(child);
        }