C# 尝试查找类在帧之间是否已更改的问题
我有一个自定义类的列表。每一帧我都想找出自上一帧以来是否有任何类是新的或修改过的,如果有,则更改它们的一些属性 这是我最初认为最好的方法C# 尝试查找类在帧之间是否已更改的问题,c#,unity3d,C#,Unity3d,我有一个自定义类的列表。每一帧我都想找出自上一帧以来是否有任何类是新的或修改过的,如果有,则更改它们的一些属性 这是我最初认为最好的方法 public List<Custom> currList; List<Custom> lastFrameList; void Update() { if (lastFrameList != null) { foreach (Custom c in currList) {
public List<Custom> currList;
List<Custom> lastFrameList;
void Update()
{
if (lastFrameList != null)
{
foreach (Custom c in currList)
{
if (!lastFrameList.Contains(c)
{
DoStuff()
}
}
}
lastFrameList = currList;
}
公共列表;
列表框架列表;
无效更新()
{
如果(lastFrameList!=null)
{
foreach(currList中的自定义c)
{
如果(!lastFrameList.Contains)包含(c)
{
多斯塔夫()
}
}
}
lastFrameList=currList;
}
但是这个方法从来没有实现过。我也尝试过使用Find()Equals()Any()并将其放入OnValidate()中。该类包含很多内容,包括枚举数组。我目前主要测试运行时编辑器的更改
任何想法都将不胜感激。这里有几点:
1) 代码的哪一部分永远无法到达?试一试
public List<Custom> currList;
List<Custom> lastFrameList;
void Update()
{
if (lastFrameList != null)
{
Debug.Log("lastFrameList is not null");
foreach (Custom c in currList)
{
if (!lastFrameList.Contains(c))
{
Debug.Log("there is a new element in currList that was not there in lastFrameList");
DoStuff()
}
}
}
lastFrameList = currList;
}
或者让它成为一个结构,但这会产生一系列其他后果
3) 正如RenéKling所说,列表本身也只是一个引用,因此您没有使用“lastFrameList=currList;”进行复制,这意味着如果在此语句之后更改currList,这将传播到lastFrameList上的查询,因为它引用了相同的列表。这里有几点:
1) 代码的哪一部分永远无法到达?试一试
public List<Custom> currList;
List<Custom> lastFrameList;
void Update()
{
if (lastFrameList != null)
{
Debug.Log("lastFrameList is not null");
foreach (Custom c in currList)
{
if (!lastFrameList.Contains(c))
{
Debug.Log("there is a new element in currList that was not there in lastFrameList");
DoStuff()
}
}
}
lastFrameList = currList;
}
或者让它成为一个结构,但这会产生一系列其他后果
3) 正如RenéKling所说,列表本身也只是一个引用,因此您没有使用“lastFrameList=currList;”进行复制,这意味着如果在此语句之后更改currList,这将传播到lastFrameList上的查询,因为它引用的是同一个列表。而不是执行此操作
lastFrameList = currList
试用
lastFrameList = currList.toList()
这将创建currList的副本,而不是直接指向currList
currList中的所有更改都将与您的代码一起包含在lastFrameList中,因此lastFrameList从不缺少自定义项
编辑(检测到自定义对象已更改):
在自定义类中,可以执行以下操作:
public bool Attributes_changed { get;set;}
private int m_someAttribute;
public int SomeAttribute {
get
{
return m_someAttribute;
}
set
{
Attributes_changed = true;
m_someAttribute = value;
}
}
public Custom(//your parameters){
Attributes_changed = false;
}
因此,现在每当您设置属性(例如SomeAttribute=2)时,您的标志都将设置为true。然后,您可以在更新功能中检查它:
void Update()
{
if (lastFrameList != null)
{
foreach (Custom c in currList)
{
if (!lastFrameList.Contains(c))
{
//Do stuff for a newly added custom object
DoStuff()
}
if (c.Attributes_changed){
//Do stuff for changed attributes.
DoStuff()
c.Attributes_changed = false;
}
}
}
lastFrameList = currList.toList();
}
如果您想在这两种情况下执行相同的操作,您可以将两个if语句组合起来。而不是执行
lastFrameList = currList
试用
lastFrameList = currList.toList()
这将创建currList的副本,而不是直接指向currList
currList中的所有更改都将与您的代码一起包含在lastFrameList中,因此lastFrameList从不缺少自定义项
编辑(检测到自定义对象已更改):
在自定义类中,可以执行以下操作:
public bool Attributes_changed { get;set;}
private int m_someAttribute;
public int SomeAttribute {
get
{
return m_someAttribute;
}
set
{
Attributes_changed = true;
m_someAttribute = value;
}
}
public Custom(//your parameters){
Attributes_changed = false;
}
因此,现在每当您设置属性(例如SomeAttribute=2)时,您的标志都将设置为true。然后,您可以在更新功能中检查它:
void Update()
{
if (lastFrameList != null)
{
foreach (Custom c in currList)
{
if (!lastFrameList.Contains(c))
{
//Do stuff for a newly added custom object
DoStuff()
}
if (c.Attributes_changed){
//Do stuff for changed attributes.
DoStuff()
c.Attributes_changed = false;
}
}
}
lastFrameList = currList.toList();
}
如果要在这两种情况下执行相同的操作,可以将两个if语句组合起来。是否缺少
lastFrameList=newlist()
?因为第一个if
不会运行。编辑:嗯,但是在那之后它会被分配(到currList)。然而,第一个“变化”不会被找到。这是一个很好的观点@KYL3R。但是它不需要在第一个帧上运行,因为在此之前不可能有更改,因为没有设置初始值,是否缺少lastFrameList=newlist()
?因为第一个if
不会运行。编辑:嗯,但是在那之后它会被分配(到currList)。然而,第一个“变化”不会被找到。这是一个很好的观点@KYL3R。但是它不需要在第一个帧上运行,因为在此之前不可能有任何更改,即不设置初始值,1)我在问这个问题之前进行了调试(我真的不喜欢这样发布,除非我真的必须这样做)。它达到了第一个声明,但从未达到第二个声明。我不确定第二点和第三点有什么不同,但我明白了。谢谢你的帮助1)我在问这个问题之前做了调试(我真的不喜欢发帖子给SO,除非我真的必须发)。它达到了第一个声明,但从未达到第二个声明。我不确定第二点和第三点有什么不同,但我明白了。谢谢你的帮助。你如何把东西添加到你的列表中?正如Daveloper提到的,当您在第一个if语句中时,最好查看两个列表的计数,或者设置断点并手动查看列表,看看它们是否与您希望的不同。它们在任何时候都与您期望的完全相同。我通过unity编辑器进行所有修改。所以我要说清楚。您通过unity编辑器向currList添加了一个新对象,但没有编辑现有对象?我希望脚本能够同时处理这两个对象,但现在我只是编辑一个现有对象。确定了吗,您正在编辑一个现有的自定义对象?这就解释了为什么计数没有改变。正如Daveloper所写,lastFrameList确实包含您编辑的自定义文件,因此contains方法返回true。如何将内容添加到currList?正如Daveloper提到的,当您在第一个if语句中时,最好查看两个列表的计数,或者设置断点并手动查看列表,看看它们是否与您希望的不同。它们在任何时候都与您期望的完全相同。我通过unity编辑器进行所有修改。所以我要说清楚。您通过unity编辑器向currList添加了一个新对象,但没有编辑现有对象?我希望脚本能够同时处理这两个对象,但现在我只是编辑一个现有对象。确定了吗,您正在编辑一个现有的自定义对象?这就解释了为什么计数没有改变。正如Daveloper所写,lastFrameList确实包含您编辑的自定义文件,因此contains方法返回true。