Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 尝试查找类在帧之间是否已更改的问题_C#_Unity3d - Fatal编程技术网

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。