How can I store vector3 data in a variable to refer to it later?

Hello everyone!

So, my scripting skills are still at a baby level and I can’t figure out how can I take Vector3 data from different object and store it in variable at start of the code, so I can refer to it in void Update.

To make myself more clear, I will show the code that works:

  void Update()
   {
        float step = speed * Time.deltaTime;
        projectile.transform.position = Vector3.MoveTowards(projectile.transform.position, Target.transform.position, step);

    }
}

And it does exactly what I want, the projectile moves at the position provided. But, when I replace “projectile.transform.position” and “Target.transform.position” with variables value1 and value2, it just doesn’t work anymore. How is that if that’s two same pieces of code, but written in different way?
I tried to initialize it in void Start:

void Start ()
    {

        Target = GameObject.Find("TARGET_AIM");
        Destroy(gameObject, 10.0f);
        Vector3 value1 = (projectile.transform.position);
        Vector3 value2 = (Target.transform.position);
}

It doesn’t give me any errors, warnings or anything, I can run the game, but projectiles just move into one fixed point in the world without any reason.
I tried with “var value1” and “var value2” but it also doesn’t work.

What I actually want to do? So, I want the projectiles to move at the position of the “Target”, but not actually follow it, that’s why I’m trying to save the Vector3 position into variable, so the point will be fixed and the projectile will not change the direction when the “Target” moves.
At last, there’s the whole script, from start to end:

public class FriendlyProjectileController : MonoBehaviour {
    public Rigidbody rb;
    public float speed;
    public GameObject projectile;
    public Transform projectile_tr;
    public GameObject Particle;
    public Transform position;
    private GameObject Target;
    private Vector3 TargetPos;
    private Vector3 value1;
    private Vector3 value2;

    void Start ()
    {

        Target = GameObject.Find("TARGET_AIM");
        Destroy(gameObject, 10.0f);
        Vector3 value1 = (projectile.transform.position);
        Vector3 value2 = (Target.transform.position);
    }

    private void OnCollisionStay(Collision col)
    {
        Destroy(gameObject);
        Instantiate(Particle, position.position, position.rotation);
    }

    void Update()
   {
        float step = speed * Time.deltaTime;
        projectile.transform.position = Vector3.MoveTowards(value1, value2, step);

    }
}

I spent some time searching and couldn’t figure it out myself. If I’m not clear enough, tell me and I’ll try to clarify. I hope it’s nothing dumb that I just can’t see. Can you help me guys?

Are you perhaps trying to make bullet tracers or some variant of that? I ran into this problem awhile back.

You can use a variable for the target, but not for the projectile. That is actually what you want to move. The only way you could use a variable would be to make the projectile equal to it every cycle of update, which would be the same as not using it.

No, no, I’m trying to make projectiles move towards the point I spawned by clicking mouse button. They do that with this code, but my problem is, I want the projectiles to move towards fixed point, even if the target change the position, so I want to store old Target’s Vector3, so the projectile will fly towards point the Target was when projectile was shoot.
I feel like this explanation really sucks, but I have no other idea how to explain that XD

You wanna look up value types vs reference types.

Unity’s Vector3 is a struct - and a struct is always a value type in C#.
That is, if you get a vector (e.g. the target’s position) in Start, it’ll copy the entire vector to your vector variable. Any changes to the source’s values will not be applied to that copy - they’re neither referring to one single object nor to the same address in memory. They’re completely decoupled. You’re also having an issue with re-declaration there (local variables).

In contrast to that, Target is a GameObject. GameObject is a class, i.e. a reference type. If you assign Target to anything else, you’re not performing a copy of the actual GameObject, but only a copy of a reference to that GameObject. You’ll end up with 2 references to a single object in memory. Both references can be used to access the same object.

Now that’s a quick and dirty overview about value type semantics vs reference type semantics (in C#). For any further and accurate in-depth information, you should spend a proper amount of time and effort to get a solid and exact understanding of both semantics - because it’s an important part of the fundamental knowledge that you’ll always need.

First of all, grats on trying to learn something new. Programming, like any skill, takes time to master and asking for help is the only way to get good at it.

Your problem is what is called a scoping problem. Each variable has a sort of life time. There is more to it, but in general when you define a variable inside a set of curly braces it only lives until the corresponding closing brace.

I am referencing the whole class here, so the line numbers I state are from the listing of FriendlyProjectileController in the first post. In lines 11 and 12 you define two fields (a special type of variable) and they live as long as the object does. In lines 19 and 20 you are creating two new variables that happen to have the same names as the fields. The compiler will use those variables instead of your fields. (There may be a warning in the console about the variable overriding the field, but I don’t know for sure.)

The fix is simple. Just remove the type (Vector3) from lines 19 and 20 and your code will use the fields.

Hi!
Thanks for your time, however I tried that before, having just “value2” instead of “Vector3 value2”, it didn’t work neither, the projectile seemed to move in correct direction, but stopped after travelling very small distance. It behaved completely different then when I used “Target.transform.position” so it doesn’t solve the problem for me.

Thanks a lot for your time there!
I’m looking into that right now, trying to understand it and see how I can do it properly in my code.

That is another problem. Time.deltaTime is how much time passed since the last frame. Each frame takes roughly 0.2 seconds, it changes each frame but hovers around the same value. So, the step variable hardly changes after the first frame so it looks like it is stuck.

To fix it, you need to make step a field private float step = 0f; then change float step = speed * Time.deltaTime; to step = step + speed * Time.deltaTime;

Now, this will only work for one projectile. Don’t do the following (if you choose to) until one projectile is working. To make it work with two or more at a time then you would want to refactor the code into two classes. One is the controller you have now with the OnCollisionStay method and the other would be a ProjectileController (ProjectileBehaviour is what I would use) with the Start, Update and needed fields then attache ProjectileController to the projectile prefab. You won’t need the projectile fields anymore since it is the object itself (I.E. instead of projectile.transform just use transform).

I should point out that the reason it worked before is because you were using the current position each frame. With the field value1, the position stays the same each frame so you must update the step. If you refactor the code so you have a MonoBehaviour attached to the projectile then you don’t need value1 and can just use transform.position instead.

Holy cow, this actually fixed that! Thank you so much! Projectiles now fly with a proper speed at the location provided and they doesn’t change the direction when target location changes! I would never figure it out myself, thank you so much!!!

:sweat_smile: I just noticed i completely missed this part:

My bad, I thought you wanted the complete opposite. :smile:

That’s fine, my explanation was really messy, my apologies for that :face_with_spiral_eyes:
But, thanks to you, I’ve looked into these value types and reference types, I didn’t know the difference before and didn’t even know C# distinguish them that way, so I’ve actually learnt something, so thanks for your time and help! :smile: