C# 如何将一个场景中的对象与其他场景中的对象进行比较?
例如,如果我有超过10000个对象,可能会很慢或需要很长时间,因为如果我没有弄错的话,应该将每个对象与所有其他对象进行比较 为什么??在我的游戏中,我对一个大对象做了一些修改,它有很多子对象。我不记得我对什么对象做了什么更改。但我也不想只是从原始场景复制原始对象,然后用更改覆盖其他对象,因为我想保留一些更改 有些更改是我做过的,知道的,想保留的,有些更改是我做过的,但不确定何时何地以及以后可能要删除的 主要目标是获得一个好的输出日志或一个文本文件,它将告诉我有多少个对象相同,有多少个不相同,每个不相同的对象具有相同的名称但不具有相同的旋转缩放位置或组件,以告诉我更改的不同之处 我的第一个场景是包含更改的对象。第二个场景包含更改前的原始对象 此脚本附加到我的第一个场景中的空游戏对象:C# 如何将一个场景中的对象与其他场景中的对象进行比较?,c#,unity3d,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);
}
}
}
}
}
使用系统;
使用系统集合;
使用System.Collections.Generic;
使用System.Linq;
运用系统反思;
使用UnityEditor;
使用UnityEngine;
公共类比较对象:单行为
{
公共游戏对象;
公共字符串numberOfObjects;
公共字符串比较对象;
公共浮动等待时间;
public List allobjects=new List();
公共bool compareAtStart=false;
public bool pauseGameOnComparison=false;
专用协程比较器;
私有void Start()
{
allobjects=FindObjectsOfType().ToList();
numberOfObjects=allobjects.Count.ToString();
if(compareAtStart==true)
{
开始比较();
}
}
公共无效开始比较()
{
if(pauseGameOnComparison==true)
{
mainGame.SetActive(false);
}
if(比较器==null)
{
比较器=启动例程(Compare());
}
}
公开作废停止比较()
{
if(比较器!=null)
{
比较对象=”;
allobjects=新列表();
StopCorroutine(比较器);
mainGame.SetActive(true);
比较器=null;
}
}
IEnumerator比较()
{
while(true)
{
if(allobjects.Count==0)
{
停止比较();
打破
}
其他的
{
foreach(游戏对象进入AllObject)
{
如果(go.name!=“游戏经理”)
{
search.PrintSearch(go.name);
}
返回新的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;
}
}
使用System.Collections.Generic;
使用System.Linq;
使用UnityEditor;
使用UnityEngine;
使用UnityEngine.SceneManagement;
公共静态类搜索器
{
[MenuItem(“工具/打印搜索”)]
公共静态void PrintSearch(字符串objectName)
{
var componentType=类型(BoxCollider);
var scenes=Enumerable.Range(0,SceneManager.sceneCount)
.选择(SceneManager.GetSceneAt)
.ToArray();
var objectsWithNames=场景
.ToDictionary(s=>s,s=>GetSceneObjectsWithName(s,objectName.ToLower());
var forLog=objectsWithNames
.SelectMany(pair=>pair.Value.Select(child=>
$“场景{pair.Key.name}:对象名称{child.gameObject.name}{(child.GetComponent(componentType)!=null?”包含“:“不包含”)}组件{componentType.name}”);
Debug.Log(string.Join(“\n”,forLog));
}
私有静态变换[]GetSceneObjectsWithName(场景场景,字符串objectName)
{
返回scene.GetRootGameObjects()
.SelectMany(g=>GetChildHierarchy递归(g.transform))
.Where(t=>t.gameObject.name.ToLower().Contains(objectName))
.ToArray();
}
私有静态IEnumerable GetChildHierarchy递归(Transform parentTransform)
{
收益率转换;
如果(parentTransform.childCount>0)
收益率转换;
}
}
第一个问题是我在控制台的日志中看到:
方法Searcher.PrintSearch具有无效参数。MenuCommand是唯一支持的可选参数。
UnityEditor.EditorApplication:Internal_CallUpdateFunctions()
它一直在写日志:
调试:日志(对象)
第二个问题是,我不确定使用CompareObject脚本是否正确。Oof。祝你好运,伙计,这可不是件容易的事,不管你怎么切。我所能建议的是,将来您可以使用某种源存储库。即使这样,单位场景文件也不容易合并更改;Unity构建了他们的collabs东西,它应该比源代码树处理得更好,但我没有使用它。完全同意Draco18s。。这看起来像是一个XY问题,应该使用版本控制来解决。另外,你可以考虑让它成为一个预置的下一个时间= Unity可以跟踪场景实例中的任何改变,而不是原来的预置,你可以决定哪些要回复,哪些要应用到预置…OOF。祝你好运,伙计,这可不是件容易的事,不管你怎么切。我所能建议的是,将来您可以使用某种源存储库。即使这样,单位场景文件也不容易合并更改;