在方法中设置数组大小
本文关键字:数组 设置 方法 | 更新日期: 2023-09-27 17:49:21
我对unity和c#都是新手,所以请耐心等待。
我想创建一个方法,该方法接受一个vector3数组的参数,该数组获取游戏中目标对象的位置,但数组大小不会改变为我在方法中放入的数组(targetPos)
private Vector3[] targetPos;
public int targetCount;
void Awake()
{
SetTargetPos (targetPos);
}
private void SetTargetPos(Vector3[] targets){
targetCount = GameObject.Find ("Targets").transform.childCount;
targets = new Vector3[targetCount];
for (int i = 0; i<targetCount; i++) {
targets[i] = GameObject.Find("Targets").transform.FindChild("Target " + i.ToString()).position;
}
}
我确实在SetTargetPos方法中设置了目标数组的大小
targets = new Vector3[targetCount];
然而targetPos数组不改变它的大小,当我开始游戏,为什么是这样,我怎么能解决这个问题?
这里可能有一些误解,认为您更改了数组的大小,但这也可能只是您表达问题的方式。
无论如何,这里的问题与参数传递有关。
这条线:
SetTargetPos (targetPos);
传递引用的副本给该方法。这个引用指向内存中的数组对象。
在方法内部,这一行:
targets = new Vector3[targetCount];
创建一个新的所需大小的数组,并将新的数组对象引用赋值给该方法的局部形参变量。
外部变量保持不变。
来,让我告诉你我的意思。
在方法调用之前,内存中有这些东西(包含两个元素的示例数组):
targetPos --> [V1, V2]
然后,当你的程序正在执行并且对该方法的调用正在进行时,就在方法内部,在我们给targets
赋值之前,我们有这样的场景:
targetPos ------+
+--> [V1, V2]
targets --------+
现在有两个变量指向同一个数组,一个在本地,一个在外部。因此targets
包含引用的副本,它与外部变量没有关系。
targetPos --> [V1, V2]
targets ----> [V1, V2, V3]
你得到一个新的数组,你改变targets
中的引用来引用这个新的数组。外部变量保持原样,仍然引用前一个数组。你在方法内做的任何事情都不会改变这个。
除非你改变你的方法通过引用传递变量:
private void SetTargetPos(ref Vector3[] targets){
你还需要改变你如何称呼它:
SetTargetPos (ref targetPos);
现在将正确地在外部重新分配变量。
有关参数传递的更多信息,您应该阅读Jon Skeets关于参数传递的博客文章
用List代替array。它会动态调整大小
private List<Vector3> targetPos = new List<Vector3>();
public int targetCount;
void Awake()
{
SetTargetPos (targetPos);
}
private void SetTargetPos(Vector3[] targets){
targetCount = GameObject.Find ("Targets").transform.childCount;
targets = new Vector3[targetCount];
for (int i = 0; i<targetCount; i++) {
targets[i] = GameObject.Find("Targets").transform.FindChild("Target " + i.ToString()).position;
}
}
正如Ivan所建议的,您可能希望使用列表而不是数组。
我认为你遇到的问题是由于这一行:
targets = new Vector3[targetCount];
当您为targets
参数赋值时,它在本地更新targets
的值,但不更新targetPos
(即使它是通过引用传递的)。使用List可以解决这个问题,因为你可以重用相同的实例,而不是分配一个新的实例。
private List<Vector3> targetPos = new List<Vector3>();
public int targetCount;
void Awake()
{
SetTargetPos(targetPos);
}
private void SetTargetPos(List<Vector3> targets)
{
targetCount = GameObject.Find ("Targets").transform.childCount;
targets.Clear();
for (int i = 0; i<targetCount; i++)
{
targets.Add(GameObject.Find("Targets").transform.FindChild("Target " + i.ToString()).position);
}
}