0

I am very new to unity and C# so please be patient with me.

I want to make a method that takes one argument of a vector3 array that gets the positions of target objects in my game, but the array size does not change to the array i put in the method (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;
    }
}

i did set the targets array size inside the SetTargetPos method

targets = new Vector3[targetCount];

however the targetPos array does not change its size when i start the game, why is that, and how can i resolve this?

0

3 Answers 3

1

There's some misconception here, perhaps, that you change the size of an array, but it could also be just the way you worded the problem.

Anyway, the problem here is related to parameter passing.

This line:

SetTargetPos (targetPos);

passes a copy of the reference to the method. This reference refers to the array object in memory.

Inside the method, this line:

targets = new Vector3[targetCount];

Creates a new array of the new required size and assigns that new array object reference to the local parameter variable of that method.

The outside variable is left untouched.

Here, let me show you what I mean.

Before the method call you have these things in memory (with an example array containing 2 elements):

targetPos --> [V1, V2]

Then, when your program is executing and the call to that method is in progress, right inside the method, before we assign anything to targets, we have this scenario:

targetPos ------+
                +--> [V1, V2]
targets --------+

We now have 2 variables referring to the same array, one local and one outside. targets thus contains a copy of the reference, it has no relationship with the outside variable.

Thus, when you assign a new array to the local parameter variable you get this scenario (assuming we assign it an array of 3 elements):

targetPos --> [V1, V2]
targets ----> [V1, V2, V3]

You get a new array, and you change the reference in targets to refer to this new array. The outside variable is left as-is, and still refers to the previous array. Nothing you do inside the method will change this.

Except, if you change your method to pass the variable by reference:

private void SetTargetPos(ref Vector3[] targets){

You also need to change how you call it:

SetTargetPos (ref targetPos);

This will now correctly reassign the variable on the outside.

For some more information on parameter passing, you should go read Jon Skeets blog article on parameter passing.

Sign up to request clarification or add additional context in comments.

4 Comments

So.. adding "ref" will use the actual variable inside the method and not a copy?
Correct. Behind the scenes a pointer to the original variable will be passed and all variable access will actually use the original variable.
Though you should not discount the other answers here either, perhaps it might be better for you to actually use a list, but you need to determine that yourself.
Thank you, i will try even though i'm not very familliar with lists yet
0

Just use List instead of array. It will adjust size dinamically

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;
    }
}

Comments

0

As Ivan suggested, you might want to use a list instead of an array.

I think the problem your are encountering is due to this line:

targets = new Vector3[targetCount];

When you assign a value to the targets parameter, it updates the value of targets locally, but not update targetPos (even though it is passed by reference). Using a List would fix this because you could re-use the same instance instead of assigning a new instance.

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);
    }
}

4 Comments

It isn't passed by reference, which is the problem here. The code is passing a reference, but it is passing the reference by value.
Right, I suppose your explanation is technically more correct - it's passing the array by reference, but the reference is still passed by value.
We're only passing the reference, by value, the array is not passed at all, it is only referred to by the reference. I understand what you mean though but it's important to get the terms right if you want to google for more information :) However, that is nitpicking. I do, however, think that using a list is not the right answer or I would've let this one go. The question is asked in terms of Unity, which implies a game, and there are usually strong wishes/requirements to know when memory allocations are done in such a scenario. A list sort of removes that knowledge.
I'm not saying list is wrong, he's also saying he's new to unity and he's not saying anything about what he's making. I too would definitely go with a list first and fiddle with an array if performance suffers. I just thought I could post an answer referring to the actual problem with his code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.