简体   繁体   English

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

[英]How can I loop over all game objects in hierarchy including disabled objects all children too in both scenes?

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);
            }
        }
    }
}

The first problem is I can't convert the array of:第一个问题是我无法转换数组:

FindObjectsOfType(typeof(GameObject))

To List.列出。

Seconds how can I loop over the objects in two scenes?秒我如何在两个场景中循环对象? I want to make a comparison between scene a and scene b objects and to be able also to narrow the searching for objects with specific component/s and list the results in the EditorWindow: List A the objects with components in scene A and List B the objects with components in scene B我想在场景 a 和场景 b 对象之间进行比较,并且还能够缩小对具有特定组件的对象的搜索范围,并在 EditorWindow 中列出结果:列出 A 场景 A 和 B 中具有组件的对象场景 B 中具有组件的对象

For example if I type in the search bar: Space,BoxCollider Then it should find all objects in both scenes that contain the name Space and that also have a BoxCollider attached or without a BoxCollider attached.例如,如果我在搜索栏中键入: Space,BoxCollider 那么它应该会在两个场景中找到包含名称 Space 并且还附加了 BoxCollider 或未附加 BoxCollider 的所有对象。

I want to know in the result what objects name Space have boxcollider and what not.我想知道结果中哪些对象名称 Space 有 boxcollider 而没有。

Example:例子:

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

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

Something like this comparison.像这样的比较。

I can't convert the array of我无法转换数组

Method FindObjectsOfType(Type) return array of objects, to cast those objects to list you can use LINQ method OfType :方法FindObjectsOfType(Type)返回对象数组,要将这些对象转换为列表,您可以使用 LINQ 方法OfType

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

Or just use generic override of method FindObjectsOfType<T>()或者只是使用方法FindObjectsOfType<T>()的通用覆盖

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

Seconds how can I loop over the objects in two scenes?秒我如何在两个场景中循环对象?

You need select all scenes from SceneManager and make loop over it's GetRootGameObjects() .您需要 select SceneManager中的所有场景,并在其GetRootGameObjects()上进行循环。

If you need to loop all objects and make some manual calculations - you can loom manually like was described here .如果您需要循环所有对象并进行一些手动计算 - 您可以像这里描述的那样手动织机。 If you know what exactly components you need you can use method public Component[] GetComponentsInChildren(Type t, bool includeInactive);如果你知道你需要什么组件,你可以使用方法public Component[] GetComponentsInChildren(Type t, bool includeInactive); with scene root objects (make sure then you set includeInactive to True if you want to search in inactive objects)使用场景根对象(如果要在非活动对象中搜索,请确保将includeInactive设置为True

I want to know in the result what objects name Space have boxcollider and what not.我想知道结果中哪些对象名称 Space 有 boxcollider 而没有。

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;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM