Как я могу зациклить все игровые объекты в иерархии, включая отключенные объекты, все дочерние объекты в обеих сценах? - PullRequest
0 голосов
/ 05 октября 2019
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, а также иметь возможность сузить поиск объектов с конкретными компонентами и перечислить результаты в EditorWindow: список A объектов с компонентами в сцене A и список Bобъекты с компонентами в сцене B

Например, если я наберу в строке поиска: Space, BoxCollider, то он должен найти все объекты в обеих сценах, которые содержат имя Space и к которым также прикреплен BoxCollider или без BoxColliderattach.

Я хочу узнать в результате, какие объекты с именем Space имеют boxcollider, а какие нет.

Пример:

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

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

Что-то похожее на это сравнение.

1 Ответ

1 голос
/ 08 октября 2019

Я не могу преобразовать массив

Метод 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, если хотите искать в неактивных объектах)

В результате я хочу узнать, какие объекты с именем 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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...