我对团结和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数组不会改变它的大小,为什么会这样,我该如何解决这个问题呢?
答案 0 :(得分:1)
这里有一些误解,或许是你改变了数组的大小,但它也可能只是你说出问题的方式。
无论如何,这里的问题与参数传递有关。
这一行:
SetTargetPos (targetPos);
将引用的副本传递给该方法。此引用引用内存中的数组对象。
在方法内,这一行:
targets = new Vector3[targetCount];
创建新所需大小的新数组,并将该新数组对象引用分配给该方法的本地参数变量。
外部变量保持不变。
在这里,让我告诉你我的意思。
在方法调用之前,你在内存中有这些东西(包含2个元素的示例数组):
targetPos --> [V1, V2]
然后,当你的程序正在执行并且对方法的调用正在进行中时,在我们向targets
分配任何内容之前,我们有这样的场景:
targetPos ------+
+--> [V1, V2]
targets --------+
我们现在有2个变量引用同一个数组,一个是本地的,一个是外部的。 targets
因此包含引用的副本,它与外部变量无关。
因此,当您为本地参数变量分配一个新数组时,您会得到这个场景(假设我们为它分配了一个包含3个元素的数组):
targetPos --> [V1, V2]
targets ----> [V1, V2, V3]
您获得了一个新数组,并更改了targets
中的引用以引用此新数组。外部变量保持原样,仍然引用前一个数组。你在方法中没有做任何改变。
除非您更改方法以通过引用传递变量:
private void SetTargetPos(ref Vector3[] targets){
您还需要更改调用方式:
SetTargetPos (ref targetPos);
现在可以在外部正确地重新分配变量。
有关参数传递的更多信息,请阅读Jon Skeets blog article on parameter passing。
答案 1 :(得分:0)
只需使用List而不是数组。它将以音调调整大小
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;
}
}
答案 2 :(得分:0)
正如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);
}
}