如何比较一个场景中的对象与其他场景中的对象?

时间:2019-10-08 16:14:12

标签: c# unity3d

例如,如果我有10000个以上的对象,则可能会很慢或花费很长时间,因为如果我没记错的话,应该将每个对象与所有其他对象进行比较。

为什么?在我的游戏中,我对一个有很多子对象的大对象进行了一些更改。我不记得我对哪些对象进行了哪些更改。但我也不想只复制原始场景中的原始对象并用更改覆盖其他对象,因为我想保留某些更改。

有些事情我做了,知道并且想要保留,有些事情我做了,但不确定何时何地以及以后可能要删除的那些。

主要目标是获得一个不错的输出日志或文本文件,该文件将告诉多少个相同的对象,多少个不相同的对象以及每个不相同的对象具有相同的名称,但旋转缩放位置或组件不相同告诉我变化有什么区别。

我的第一个场景是包含具有更改的对象。第二个场景包含更改之前的原始对象。

此脚本在我的第一个场景中附加到空的游戏对象上:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;

public class CompareObjects : MonoBehaviour
{
    public GameObject mainGame;
    public string numberOfObjects;
    public string comparisonObjects;
    public float waitTime;
    public List<GameObject> allobjects = new List<GameObject>();
    public bool compareAtStart = false;
    public bool pauseGameOnComparison = false;

    private Coroutine comparer;

    private void Start()
    {
        allobjects = FindObjectsOfType<GameObject>().ToList();

        numberOfObjects = allobjects.Count.ToString();

        if (compareAtStart == true)
        {
            StartComparing();
        }
    }

    public void StartComparing()
    {
        if (pauseGameOnComparison == true)
        {
           mainGame.SetActive(false);
        }

        if (comparer == null)
        {
            comparer = StartCoroutine(Compare());
        }
    }

    public void StopComparing()
    {
        if (comparer != null)
        {
            comparisonObjects = "";
            allobjects = new List<GameObject>();
            StopCoroutine(comparer);
            mainGame.SetActive(true);

            comparer = null;
        }
    }

    IEnumerator Compare()
    {
        while (true)
        {
            if (allobjects.Count == 0)
            {
                StopComparing();
                break;
            }
            else
            {
                foreach (GameObject go in allobjects)
                {
                    if (go.name != "Game Manager")
                    {
                        Searcher.PrintSearch(go.name);
                    }

                    yield return new WaitForSeconds(waitTime);
                }
            }
        }
    }
} 

在我的第一个场景中,我将“主游戏”下的所有对象都移动了,以便在游戏持续运行或暂停时可以轻松进行比较。

第二类代码应自行进行比较:

using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;

public static class Searcher
{
    [MenuItem("Tools/PrintSearch")]
    public static void PrintSearch(string objectName)
    {
        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;
    }
}

第一个问题是我在控制台的日志中看到以下内容:

方法Searcher.PrintSearch包含无效的参数。 MenuCommand是唯一受支持的可选参数。 UnityEditor.EditorApplication:Internal_CallUpdateFunctions()

它一直在记录日志:

UnityEngine.Debug:Log(Object)

第二个问题是我不确定我是否使用CompareObjects脚本以正确的方式进行操作。

0 个答案:

没有答案
相关问题