我有一个GameObjects列表,我想将每个游戏对象与List游戏对象进行比较,如果它们不相同,则将其添加为结果。名称可以相同,但如果位置或旋转等参数不相同,则将游戏对象添加为结果即可。
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);
}
}
}
但是即使它们相同,它也会继续添加所有游戏对象。
答案 0 :(得分:1)
由于比较器,您没有得到想要的结果。您不应使用“ ==”来比较浮点值/向量/四元数。由于它们基于浮点数,因此很多时候它们不够准确。甚至克隆的对象也将具有浮点值1.000001或0.999999。
更好的选择是对于矢量使用“ Vector3.distance”或“ Vector3.Equals”,对于四元数,可以使用“ Quaternion.Angle”或Quaternion.Equals来检查相应的结果。
即obj.transform.position.Equals(objToCompare.transform.position)
&obj.transform.quaternion.Equals(objToCompare.transform.quaternion)
。这应该返回正确的结果,但是有可能结果可能不一样
如果发生这种情况,您可以使用
即Vector3.Distance(obj.transform.position, objToCompare.transform.position) < "Margin of difference"
。
Quaternion.Angle(transform.rotation, rotation)<"Margin of difference"
您可以指定自己的值,例如允许的差额。
注意:如果您想要较少的CPU密集型解决方案,则应使用
(obj.transform.position - objToCompare.transform.position).sqrMagnitude
比 .Distance因为.Distance必须计算平方根,即 真的很慢。
以下是一些后续链接: Vector3 Compare Quaternion Compare
更新:
public static bool CompareTransformsData(GameObject objToCompare)
{
List<GameObject> results = allobj;
foreach (GameObject obj in results)
{
//Method 1 using Equal
if( obj.transform.position.Equals(objToCompare.transform.position) &&
obj.transform.rotation.Equals(objToCompare.transform.rotation))//Do confirm here if the vectors & quaternions are able to use equal comparer & result is satisfactory to your needs
{
return true;
}
//Method 2 using sqrmagnitude & Quaternion.angle
//Use this one if you need more acurate result and control on objects
//modify the 0.1f paramters for more accuracy and filtering
if ((obj.transform.position - objToCompare.transform.position).sqrMagnitude < 0.1f &&
Quaternion.Angle(obj.transform.rotation, objToCompare.transform.rotation) < 0.1f)//Do confirm here if the vectors & quaternions are able to use equal comparer & result is satisfactory to your needs
{
return true;
}
}
return false;
}
使用其中任何一个,但不要同时使用。