# Why do I need to move target position into new Vector3, and can not use the Vector3 that holds the target position directly?

With the help of a script I found on here, I was able to move a butterfly sprite to a new random location. However, I need to first load the x and y values of the new location Vector3 into another Vector3.x and .y, otherwise it does not work. Logically I would think that I can use directly the randomly defined targetPosition Vector3. I would like to understand what is wrong in my logic.

I have the 2 scripts below. Script 1 works, but is not logical to me. Script 2 should work in my opinion but does not.

The way it works:
I have a butterfly sprite in my world
At Start, I select a random point on a sphere and make this my targetPosition
Then in Update, I check the current location of the butterfly and move it towards the targetPosition.
In script 1 this works but I first put the random target location into Vector3 targetPos and then assign targetPos.x to targetPosition.x and same for y.
In script 2 I put the random location directly into targetPoistion and looking at the debug.log, the x and y values are not zero.

Could someone please explain what is wrong in my logic of script 2 and explain how I should move my butterfly properly to the targetPosition?

Thanks!

Script1:
using UnityEngine;
using System.Collections;

public class ButtMove : MonoBehaviour {

``````private Vector3 targetPosition;
private Vector3 targetPos;

public void Start(){
**Vector3 targetPos = transform.position + Random.insideUnitSphere * 10;**
**targetPosition.x = targetPos.x;**
**targetPosition.y = targetPos.y;**
**targetPosition.z = 0f;**
Debug.Log ("targetposition = " + targetPosition.x + " - " + targetPosition.y);
}

public void Update(){
float speed = 2;		//move towards targetPosition with this speed

Vector3 currentPosition = this.transform.position;		//position of butterfly
//Debug.Log ("currentposition= " + currentPosition);
//first, check to see if we're not yet close to the target
if (Vector3.Distance (currentPosition, targetPosition) > .1f) {
Vector3 directionOfTravel = targetPosition - currentPosition;
//now normalize the direction, since we only want the direction information
directionOfTravel.Normalize ();
//scale the movement on each axis by the directionOfTravel vector components

this.transform.Translate (
(directionOfTravel.x * speed * Time.deltaTime),
(directionOfTravel.y * speed * Time.deltaTime),
(directionOfTravel.z * speed * Time.deltaTime),
Space.World);
}
}
``````

}

Script2 only difference to script 1 is in Start():

``````public void Start(){
**Vector3 targetPosition = transform.position + Random.insideUnitSphere * 10;
targetPosition.z = 0f;**
Debug.Log ("targetposition = " + targetPosition.x + " - " + targetPosition.y);
}
``````

Well, if the code is exactly as you wrote it your problem is that you define a new local variable inside Start with the same name as your member variable of the class.

``````Vector3 targetPosition = transform.position + Random.insideUnitSphere * 10;
``````

you have to use

``````targetPosition = transform.position + Random.insideUnitSphere * 10;
``````

To answer the question about modifying transform’s position: you cannot directly assign `.z` of `transform.position`, because `Vector3` is a `struct` and `.position` is a property.

Here is an example to demonstrate how writing fields and properties works with structs and classes:

``````public class FieldAndPropertyModify : MonoBehaviour
{
private Vector3 structField;
private Vector3 StructProperty { get; set; }

private MyVector classField;
private MyVector ClassProperty { get; set; }

private void Start()
{
structField.z = 3f; // fine
// StructProperty.z = 3f; ** NOT fine **

classField.z = 3f; // fine
ClassProperty.z = 3f; // fine
}

private class MyVector { public float z; }
}
``````

Firstly, `struct` is a value type. This means it returns a copy when you read it:

``````Vector3 first = new Vector3(1, 2, 3);
Vector3 second = first;
second.z = 10f;
Debug.Log(first.z); // 3f
``````

Secondly, accessing `StructProperty` returns a copy. While I used a `{ get; set; }` shorthand, here is what the compiler “sees”:

``````private Vector3 _structProperty;
private Vector3 StructProperty { get { return _structProperty; } set { _structProperty = value; } }
``````

So when you read `transform.position` (which is a `get` method), you receive a copy of `Vector3`. You can then modify this struct to your needs. Then you pass it back into `transform.position` (which is a `set` method with a `value` parameter), which stores a copy again. But accessing `.z` from reading a property simply accesses the value of the copy and assigning a new value to it that just gets “lost” makes no sense.

See Bunny83’s answer for the issue in the source code itself.

Edit: rewrote and scrapped incorrect info, thanks Bunny83