static void replaceInstances(SearchJob parentJob, SearchItem item, GameObject oldValue, GameObject newValue)
        {
            SearchItemSet searchSet = new SearchItemSet();

            searchSet.OnDeserialization();
            searchSet.AddNew(Keys.Global, false);
            SearchItemGlobal searchItem = (SearchItemGlobal)searchSet.items[0];

            searchItem.SetType("Object");
            DynamicTypeObject dto = (DynamicTypeObject)searchItem.GetDTDFor(typeof(UnityEngine.Object));

            dto.SearchSubObjects = true;
            dto.SetObject(oldValue);
            ReplaceItemObject replaceItem = (ReplaceItemObject)dto.ReplaceItem;

            replaceItem.SetObject(newValue);

            SearchOptions options = new SearchOptions();

            options.searchType = SearchType.SearchAndReplace;

            // does this matter anymore since asset scope is now essentially defined by what assets are passed in?
            SearchScopeData searchScope = new SearchScopeData(ProjectScope.SpecificLocation, AssetScope.Prefabs, new ObjectID(AssetDatabase.LoadAssetAtPath <UnityEngine.Object>(parentJob.assetData.assetPath)), false, parentJob.scope.loadPrefab);
            SearchJob       subJob      = new SearchJob(searchSet, options, searchScope);
            SearchAssetData assetData   = parentJob.assetData.Clone();

            subJob.AddAsset(assetData);
            subJob.Execute();

            // Now that we've executed the job we have to save a list of all objects from search results, because as soon as
            // we swap out the new object, the old object's position may shift in the hierarchy, making the PathInfo stale.
            SearchResultGroup         group         = subJob.resultSet.results[searchItem.sortIndex];
            List <UnityEngine.Object> resultObjects = new List <Object>();

            foreach (SearchResult result in group.results)
            {
                UnityEngine.Object resultObj = EditorUtility.InstanceIDToObject(result.pathInfo.objectID);
                resultObjects.Add(resultObj);
            }
            UnityEngine.Object.DestroyImmediate(oldValue);

            // now that we've deleted the object, let's rebuild the objects.
            for (int i = 0; i < resultObjects.Count; i++)
            {
                SearchResult result = group.results[i];
                result.pathInfo = PathInfo.GetPathInfo(resultObjects[i], assetData);
            }

            parentJob.AddResultsFromSubsearch(item, subJob.resultSet.results[searchItem.sortIndex]);
        }
Exemple #2
0
        public override void Draw(SearchOptions options)
        {
            drawControlStart();
            UnityEngine.Object newValue = EditorGUILayout.ObjectField(searchValue.obj, parent.type, true);
            drawControlEnd();
            if (newValue != null && !parent.type.IsAssignableFrom(newValue.GetType()))
            {
                newValue = null;
            }
            if (newValue != searchValue.obj)
            {
                SetObject(newValue);
                SRWindow.Instance.PersistCurrentSearch();
            }
            if (shouldSearchSubObjects && hasSubObjects())
            {
                bool newSearchSubObjects = EditorGUILayout.Toggle("Search for " + subObjectsType() + "?", searchSubObjects);
                if (newSearchSubObjects != searchSubObjects)
                {
                    searchSubObjects = newSearchSubObjects;
                    hashSubObjects();
                    SRWindow.Instance.PersistCurrentSearch();
                }
            }

            if (searchValue.obj is Material && Application.isPlaying)
            {
                EditorGUILayout.HelpBox("Searching materials while the game is playing may not return results due to Unity copying the material under the hood. It is still possible to search inside materials for textures, colors, and other data.", MessageType.Warning);
            }

            if (searchValue.isSceneObject && !SRWindow.Instance.isSearchingInScene())
            {
                if (SRWindow.Instance.getCurrentScope() == ProjectScope.CurrentSelection)
                {
                    // We've got a correct scope, but the selection is not a
                    // scene object! Try to help by informing the user that they have to
                    // select something in the scene first.
                    EditorGUILayout.HelpBox("Cannot search the current selection because scene objects can only be searched for inside scenes.", MessageType.Warning);
                    searchScopeOK = false;
                }
                else
                {
                    // We've got an incorrect scope for the scene object! Try to help by
                    // informing the user this is an invalid search and give them an
                    // option out of it.
                    EditorGUILayout.HelpBox("The current selection is a scene object and you aren't searching the current scene.", MessageType.Warning);
                    searchScopeOK = false;

                    GUILayout.BeginHorizontal();
                    if (GUILayout.Button("Set Scope to the Scene View"))
                    {
                        SRWindow.Instance.changeScopeTo(ProjectScope.SceneView);
                        searchScopeOK = true;
                    }
                    GUILayout.EndHorizontal();
                }
                // Debug.Log("[Search & Replace] Objects within a scene cannot be searched for outside of a scene. ");
            }
            else
            {
                searchScopeOK = true;
            }

            drawReplaceItem(options);
            if (replaceItem is ReplaceItemObject)
            {
                ReplaceItemObject  rio = (ReplaceItemObject)replaceItem;
                UnityEngine.Object ro  = rio.replaceValue.obj;
                if (ro != null &&
                    searchValue.obj != null &&
                    !searchValue.obj.GetType().IsAssignableFrom(ro.GetType()) &&
                    options.searchType == SearchType.SearchAndReplace
                    )
                {
                    EditorGUILayout.HelpBox("The objects you're trying to search and replace are incompatible.", MessageType.Warning);
                    searchTypesOK = false;
                }
                else
                {
                    searchTypesOK = true;
                }
            }
            else
            {
                searchTypesOK = true;
            }
            if (!searchTypesOK)
            {
                // It is possible that users may want to search for disparate object which
                // is highly unsafe. For example an interface may change from a scriptable
                // object to a monobehaviour or vice versa.
                bool newOverride = EditorGUILayout.Toggle("Allow Unsafe Search", overrideSafeSearch);
                if (newOverride != overrideSafeSearch)
                {
                    overrideSafeSearch = newOverride;
                    SRWindow.Instance.PersistCurrentSearch();
                }
            }
        }