如何在两个场景中循环覆盖层次结构中的所有游戏对象,包括禁用对象和所有子对象?


using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
public class CompareObjects : EditorWindow
{
string searchString = "";
List<GameObject> items = FindObjectsOfType(typeof(GameObject)).ToList();
void OnGUI()
{
GUILayout.BeginHorizontal(EditorStyles.toolbar);
GUILayout.FlexibleSpace();
searchString = GUILayout.TextField(searchString, EditorStyles.toolbarTextField);
GUILayout.EndHorizontal();
// Do comparison here. For example
for (int i = 0; i < items.Length; i++)
{
if (items[i].name.Contains(searchString))
{
GUI.Label(items[i].name);
}
}
}
}

第一个问题是我无法转换以下数组:

FindObjectsOfType(typeof(GameObject))

列出。

秒 如何在两个场景中循环访问对象?我想在场景 a 和场景 b 对象之间进行比较,并且还能够缩小搜索范围,搜索具有特定组件的对象并在编辑器窗口中列出结果:列出场景 A 中具有组件的对象,列出 B 中具有组件的对象 B

例如,如果我在搜索栏中输入:空格,盒子碰撞机 然后,它应该在两个场景中找到包含名称 Space 的所有对象,并且还附加了盒式碰撞体或未连接了盒式碰撞体。

我想知道结果中哪些对象名称空间有盒式碰撞体,哪些没有。

例:

List A : Space1 BoxCollider -- Scene A
List A : Space2 Empty -- Scene A
List B : Space1 Empty -- Scene B
List B : Space2 BoxCollider -- Scene B

像这样的比较。

我无法转换数组

方法FindObjectsOfType(Type)返回对象数组,若要将这些对象强制转换为列表,可以使用 LINQ 方法 OfType:

List<GameObject> items = FindObjectsOfType(typeof(GameObject)).OfType<GameObject>.ToList();

或者只是使用方法FindObjectsOfType<T>()的通用重写

List<GameObject> items = GameObject.FindObjectsOfType<GameObject>().ToList();

秒 如何在两个场景中循环访问对象?

您需要从SceneManager中选择所有场景并循环播放其GetRootGameObjects()

如果您需要循环所有对象并进行一些手动计算 - 您可以像这里描述的那样手动织机。如果您知道需要哪些组件,则可以对场景根对象使用方法public Component[] GetComponentsInChildren(Type t, bool includeInactive);(如果要在非活动对象中搜索,请确保将includeInactive设置为True(

我想知道结果中哪些对象名称空间有盒式碰撞体,哪些没有。

using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;
public static class Searcher
{
[MenuItem("Tools/PrintSearch")]
public static void PrintSearch()
{
var objectName = "Space";
var componentType = typeof(BoxCollider);
var scenes = Enumerable.Range(0, SceneManager.sceneCount)
.Select(SceneManager.GetSceneAt)
.ToArray();
var objectsWithNames = scenes
.ToDictionary(s => s, s=> GetSceneObjectsWithName(s, objectName.ToLower()));
var forLog = objectsWithNames
.SelectMany(pair => pair.Value.Select(child =>
$"Scene {pair.Key.name}: object name '{child.gameObject.name}' {(child.GetComponent(componentType) != null ? "contains" : "do not contains")} component {componentType.Name}"));
Debug.Log(string.Join("n", forLog));
}
private static Transform[] GetSceneObjectsWithName(Scene scene, string objectName)
{
return scene.GetRootGameObjects()
.SelectMany(g => GetChildHierarchyRecursively(g.transform))
.Where(t=>t.gameObject.name.ToLower().Contains(objectName))
.ToArray();
}
private static IEnumerable<Transform> GetChildHierarchyRecursively(Transform parentTransform)
{
yield return parentTransform;
if (parentTransform.childCount > 0)
yield return parentTransform;
}
}

最新更新