如何在 Unity 中创建数组的独立副本?
Posted
技术标签:
【中文标题】如何在 Unity 中创建数组的独立副本?【英文标题】:How do I create an independent copy of an array in Unity? 【发布时间】:2021-10-22 17:21:52 【问题描述】:TL;DR:我需要一种方法来复制带有整数的数组,其中副本不会更改原始数组,并且可以在 Unity 中使用。
我正在尝试实现以下算法:我有一个数组字段,其中包含可在检查器中编辑的数字。这些数字表示要生成的每种类型的敌人的数量:
public int[] EnemiesToSpawn;
还有,比如我把数组设置为3位,数组中每个的索引对应于数组中带有敌人prefab的对象的索引。
然后,在函数中,我随机生成敌人,每次将数组中对应的数字减一(如果元素整数为0,则选择另一个敌人,如果所有元素的整数都为0,则生成函数结束执行)。
一切都很顺利,直到我需要在关卡上设置多个点,每个点都会独立生成敌人。我做了什么:我添加了另一个数组,每次我需要在新的点产生敌人时,我都会从第一个数组中复制值,并编辑这个特定的第二个数组而不是原始数组(只需分配值通过“=”)。当然不行,我google了一下,发现C#中的数组是作为引用存储的,而不是值,所以原来的数组也被编辑了。
我尝试了很多提供正确复制的选项(例如 System.Array.Copy 等),但由于某种原因,它们都不能在 Unity 中工作。 我自己想出的唯一办法就是循环迭代并分别赋值:
EnemiesToSpawnCurrent = new int [EnemiesToSpawn.Length];
for (int i = 0; i <EnemiesToSpawn.Length; i ++)
EnemiesToSpawnCurrent [i] = i;
但是,由于某种原因,此代码也无法正常工作,数字与检查器中输入的数字不对应(很可能元素的索引不匹配)。 如果您能告诉我如何以最佳方式解决此问题,我将不胜感激。
【问题讨论】:
你可能会提到EnemiesToSpawnCurrent[i] = EnemiesToSpawn[i];
..这会使这个问题基本上基于一个错字......
【参考方案1】:
选项 A:
int[] a; // original array you want to deep copy
int[] b = new int[a.length]; // your copy
System.Array.Copy(a, b, a.length);
选项 B:
int[] a; // original array you want to deep copy
int[] b = (int[]) a.Clone();
编辑:在您的代码中,数字将不匹配,因为您将它们分配给i
。
EnemiesToSpawnCurrent = new int [EnemiesToSpawn.Length];
for (int i = 0; i <EnemiesToSpawn.Length; i ++)
EnemiesToSpawnCurrent [i] = i; // wrong!
这应该可行:
EnemiesToSpawnCurrent = new int[EnemiesToSpawn.Length];
for (int i = 0; i <EnemiesToSpawn.Length; i ++)
EnemiesToSpawnCurrent[i] = EnemiesToSpawn[i]; // copy each value from original to new Array.
解释:对于 int 数组,这是有效的,因为整数是“值类型”而不是引用类型。整个数组是引用类型,所以你需要创建一个新的、独立的实例。但是将值(整数)分配给新数组将起作用。
但是,如果您想复制 Player[]
之类的内容,您还需要创建 Player 实例的深层副本。
【讨论】:
感谢您的回答。我之前在另一个线程中找到了类似的答案,但以防万一我再次检查它。问题与我不成功的循环相同:复制数组中的数字与原始数组中的数字不匹配(在检查器中指定)。难道是在复制的时候,数字的索引发生了某种偏移? 我编辑了我的帖子以解释您的代码可能存在的问题。但是,我建议的深层副本在复制后应该包含完全相同的值。以上是关于如何在 Unity 中创建数组的独立副本?的主要内容,如果未能解决你的问题,请参考以下文章
javascript 如何在JavaScript中创建对象或数组的副本?