In a pursuit to create a find and replace wizard, we happened uppon one in the unityGUI, which is a wizard. Standard extension of the editor dosen’t seem to work (maybe it’s been depricated), or we were doing it wrong, because it’s poorly documented.
In any event the wizard has been programmed extended by us to optionally look in the scene only, however there is still the replace function. Wizards seem to operate as a single window, and we are unfamiliar with C#, please help us with the following:
-Create a new dialog using either a replace button as the second button, or a replace checkbox.
-Get the objects in allObjects[ ] and list them as unity does when importing a package(allow some to be unticked).
-Cause only ticked items in the “replace dialog” to be replaced by a given prefab.
So far We have:
using UnityEngine;
using UnityEditor;
using System.Collections;
public class FindObjects : ScriptableWizard {
//search types
public enum SearchType {
Name,
Component
}
//query parameters
public string searchFor = "";
public SearchType searchBy = SearchType.Name;
public bool caseSensitive = false;
public bool wholeWord = false;
public bool inSelectionOnly = false;
public bool inScene = false;
public bool replace = false;
//stored parameters and results for Find Next
static string lastSearch = "";
static SearchType lastSearchType = SearchType.Name;
static bool lastSearchWhole = false;
static ArrayList foundItems;
static int foundIndex = -1;
static Object[] allObjects;
//Menu item starts wizard
[MenuItem ("GameObject/Find... %&f")]
static void FindMenuItem() {
ScriptableWizard.DisplayWizard("Find", typeof(FindObjects), "Find","");
}
//Main function
void OnWizardCreate() {
//set static records
lastSearch = searchFor;
lastSearchType = searchBy;
lastSearchWhole = wholeWord;
//search space and results
foundItems = new ArrayList();
if (inScene)
{
if (inSelectionOnly)
allObjects = Selection.objects;
else
allObjects = FindObjectsOfType(typeof(GameObject));
}
else
{
if (inSelectionOnly)
allObjects = Selection.objects;
else
allObjects = FindObjectsOfTypeAll(typeof(GameObject));
}
if (searchBy == SearchType.Name) {//name comparison
if (wholeWord) {
if (caseSensitive) {
foreach (GameObject anObject in allObjects)
if (anObject.name.ToLower().Equals(lastSearch.ToLower()))
foundItems.Add(anObject);
} else {
foreach (GameObject anObject in allObjects)
if (anObject.name.Equals(lastSearch))
foundItems.Add(anObject);
}
if (foundItems.Count == 0) {
Debug.Log("No active objects were found with the name \"" + lastSearch + "\"");
foundIndex = -1;
} else {
foundIndex = 0;
SelectObject(0);
AnnounceResult();
}
} else {
if (caseSensitive) {
foreach (GameObject anObject in allObjects)
if (anObject.name.IndexOf(lastSearch) > -1)
foundItems.Add(anObject);
} else {
foreach (GameObject anObject in allObjects)
if (anObject.name.ToLower().IndexOf(lastSearch.ToLower()) > -1)
foundItems.Add(anObject);
}
if (foundItems.Count == 0) {
Debug.Log("No active objects were found with names containing \"" + lastSearch + "\"");
foundIndex = -1;
} else {
foundIndex = 0;
SelectObject(0);
AnnounceResult();
}
}
} else { //component comparison
foreach (GameObject objectByType in allObjects)
if (objectByType.GetComponent(lastSearch))
foundItems.Add(objectByType);
if (foundItems.Count == 0) {
Debug.Log( "No active objects were found with attached " +
"component \"" + lastSearch + "\"");
foundIndex = -1;
} else {
foundIndex = 0;
SelectObject(0);
AnnounceResult();
}
}
}
void OnWizardUpdate() {
//Make sure there is a search string
if (searchFor.Equals("")) {
errorString = "Enter a search and push enter";
isValid = false;
} else {
errorString = "";
isValid = true;
}
//make it obvious that you need an exact match for a Component search
if (searchBy == SearchType.Name) {
helpString = "";
} else {
if (!caseSensitive || !wholeWord) {
caseSensitive = wholeWord = true;
}
helpString = "Component searches always require an exact match";
}
}
//Next Result menu item
[MenuItem ("GameObject/Next Result %g")]
static void NextResultMenuItem() {
if (++foundIndex >= foundItems.Count)
foundIndex = 0;
SelectObject(foundIndex);
AnnounceResult();
}
//Next is only available if there was a previous successful search
[MenuItem ("GameObject/Next Result %g", true)]
static bool ValidateNextResult() {
return foundIndex > -1;
}
//Previous Result menu item
[MenuItem ("GameObject/Previous Result #%g")]
static void PreviousResultMenuItem() {
if (--foundIndex < 0)
foundIndex = foundItems.Count-1;
SelectObject(foundIndex);
AnnounceResult();
}
//Find Next is only available if there was a previous successful search
[MenuItem ("GameObject/Previous Result #%g", true)]
static bool ValidatePreviousResult() {
return foundIndex > -1;
}
//tool for setting the selection by index in search results
static void SelectObject(int newSelection) {
Object[] newSelectionArray = {foundItems[newSelection] as Object};
Selection.objects = newSelectionArray;
}
//Identifies the current search result
static void AnnounceResult() {
if (lastSearchType == SearchType.Component)
Debug.Log( "Object " + (foundIndex+1) + " of " + foundItems.Count +
" with attached component \"" + lastSearch + "\"");
else if (lastSearchWhole)
Debug.Log( "Object " + (foundIndex+1) + " of " + foundItems.Count +
" with the name \"" + lastSearch + "\"");
else
Debug.Log( "Object " + (foundIndex+1) + " of " + foundItems.Count +
" with name containing \"" + lastSearch + "\"");
}
static void Replace()
{
//Create the new Replace dialog
ScriptableWizard.DisplayWizard("Replace", typeof(FindObjects), "Replace","");
foreach (GameObject anObject in allObjects)
{
Debug.Log(anObject);
}
}
}