Vector3 instantiation

Hi, I’m following a tutorial that has the following code:

Two questions:

  1. On line 9, is the Vector3 input being instantiated every frame and given xyz values based on input? On the next frame, is “input” overwritten in memory by another newly instantiated Vector3 also named “input”?

  2. I thought the purpose of “new” is to instantiate a class/reference type but vector3 is a struct/value type?? Since vector3 is a value type, why can’t we treat a Vector3 like a variable? Why can’t we write something like “public vector3 input = 1, 2, 3;” like a variable?

Sorry I’m confused. My learning on C# has been very fragmented. Some systematic explanation would be much appreciated :slight_smile:

C# uses “new” on both structs and classes - their memory is handled differently from each other but the syntax to use structs and classes is basically the same. All of these are locally scoped structs, so as soon as Update() ends, the memory in which they were stored is immediately freed up (and they don’t need to be garbage collected, either).

1 Like

I see, so the Vector3 is like a local variable in a method.

But in terms of syntax, why was “new” used for instantiating the Vector3 input? Why isn’t “new” given to the Vector3 direction, velocity and movement on line 10, 11 and 12?

Thank you for your help btw!

Because at line 9 you created a “new” Vector3 with the various input values passed to its constructor.

Lines 10,11,12 aren’t you creating a new Vector3, but rather copying the results of some property/operation. Line 10 is copying the result of the ‘normalized’ property, line 11 is the result ‘direction * speed’, line 12 is the result of ‘velocity * Time.deltaTime’.

In the terms of structs calling new is effectively just the act of calling a function that returns a Vector3, that function being the constructor for that struct. In the case of line 9, the function takes in 3 float values and returns a Vector3 with those 3 floats as its 3 components.

Why did they use “new” for this? Because it syntactically looked the same as when you instantiate a class. It was consistent.

1 Like

Essentially, yes. input is a local variable there, so it will no longer exist once update finishes. Next frame, a new one will be created.

‘new’ calls the constructor for the type, whether the type is a class or struct. Because Vector3 is a struct, you don’t actually need to call the constructor if you don’t want to, so this code will run without error:

public void Update()
{
   Vector3 input;
   input.x = Input.GetAxisRaw("Horizontal");
   input.y = 0;
   input.z = Input.GetAxisRaw("Vertical");
   Vector3 direction = input.normalized;
}

Generally, you shouldn’t do this though. This will typically alarm other programmers when they see it and it takes a few moments to realize that it will work.
Maybe one day Unity will add an implicit converter from a float tuple to a Vector3, but today is not that day. If that ever happens, we will be able to do this

Vector3 vec = (1.0f, 2.0f, 3.0f);

But it doesn’t work… yet.

1 Like

Once the higher versions of C# are more broadly used across Unity maybe (if they did that now sharing code samples online would be a minefield, as the tuple-based syntax would break on most Unity installs today), though even so that would still just be syntactic sugar on top of the same basic code.