【发布时间】:2019-04-11 09:55:39
【问题描述】:
我有一个游戏对象列表,我想将每个游戏对象与列表游戏对象进行比较,如果它们不同,则将其添加为结果。名称可以相同,但如果位置或旋转等参数不相同,则添加游戏对象作为结果。
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEditor;
using UnityEngine;
namespace AutocompleteSearchField
{
public class DatabaseSearch : EditorWindow
{
[MenuItem("Window/Autocomplete Searchbar/Database Search")]
static void Init()
{
GetWindow<DatabaseSearch>("DataBse Search").Show();
}
[SerializeField]
AutocompleteSearchField autocompleteSearchField;
private static SearchableEditorWindow hierarchy { get; set; }
private static List<GameObject> allobj = new List<GameObject>();
void OnEnable()
{
if (autocompleteSearchField == null) autocompleteSearchField = new AutocompleteSearchField();
autocompleteSearchField.onInputChanged = OnInputChanged;
autocompleteSearchField.onConfirm = OnConfirm;
}
void OnGUI()
{
GUILayout.Label("Search Hierarchy", EditorStyles.boldLabel);
autocompleteSearchField.OnGUI();
}
void OnInputChanged(string searchString)
{
autocompleteSearchField.ClearResults();
if (!string.IsNullOrEmpty(searchString))
{
allobj = new List<GameObject>();
allobj.AddRange(UnityEngine.SceneManagement.SceneManager.GetActiveScene().GetRootGameObjects());
foreach (GameObject obj in allobj)
{
if (HasAllComponents(obj, typeof(MeshRenderer), typeof(BoxCollider))
&& CompareTransformsData(obj) == false)
{
autocompleteSearchField.AddResult(obj.ToString());
}
}
}
}
void OnConfirm(string result)
{
var obj = AssetDatabase.LoadMainAssetAtPath(autocompleteSearchField.searchString);
Selection.activeObject = obj;
EditorGUIUtility.PingObject(obj);
}
public static bool HasAllComponents(GameObject gameObject, params System.Type[] types)
{
for (int i = 0; i < types.Length; i++)
{
if (gameObject.GetComponent(types[i]) == null)
return false;
}
return true;
}
public static bool CompareTransformsData(GameObject objToCompare)
{
List<GameObject> results = allobj;
bool identical = true;
foreach(GameObject obj in results)
{
if (GameObject.ReferenceEquals(obj, objToCompare))
{
return identical;
}
}
return identical;
}
public const int FILTERMODE_ALL = 0;
public const int FILTERMODE_NAME = 1;
public const int FILTERMODE_TYPE = 2;
public static void SetSearchFilter(string filter, int filterMode)
{
SearchableEditorWindow[] windows = (SearchableEditorWindow[])Resources.FindObjectsOfTypeAll(typeof(SearchableEditorWindow));
foreach (SearchableEditorWindow window in windows)
{
if (window.GetType().ToString() == "UnityEditor.SceneHierarchyWindow")
{
hierarchy = window;
break;
}
}
if (hierarchy == null)
return;
MethodInfo setSearchType = typeof(SearchableEditorWindow).GetMethod("SetSearchFilter", BindingFlags.NonPublic | BindingFlags.Instance);
object[] parameters = new object[] { filter, filterMode, false };
setSearchType.Invoke(hierarchy, parameters);
}
}
}
但即使相同,它也会继续添加所有游戏对象。
【问题讨论】:
-
当前您正在检查列表中的对象是否与同一列表中的任何对象相同。这当然会返回所有对象。我不确定你想在这里实现什么..?
-
你想比较什么?您只有一个
List,并且您正在将该列表中的所有内容相互比较。如所写,要么至少有一个元素与其他元素不同,您将添加所有内容,或者它们都相同,您将不添加任何内容。你想做什么? -
我想要做的是 List
allobj 包含许多游戏对象,我希望从这个 List 中添加到 AddResult 中的游戏对象只有 HasAllComponents 和不同的游戏对象。它们可以是相同的名称,例如 Cube 和 Cube,但位置、旋转或父级不同。 HasAllComponents 工作正常,问题是如何不向 AddResult 添加相同的对象。例如,如果我有一个立方体并且我复制了立方体,那么只添加一个立方体,但如果我有 3 个同名但位置或旋转不同的立方体,则添加所有立方体。