3.9 Vector3

Every part has an X, a Y, and a Z dimension. But how exactly do we change its dimensions? If you attempt to assign the Size property with some number, it just returns an error:

Lua
local part = game.Workspace.Part
part.Size = 5
--Output: Unable to assign property Size. Vector3 expected, got number

The big hint here is the line about “Vector3 expected.”

Just like BrickColor and Color3 require a specific data type, the size property (and position among many other things) also requires the new target dimension to be a specific data type.

That datatype is the ‘Vector3.’


What is a Vector3? And why is it required?

3D operations always require 3 numbers; one for each axis. This means that if there is ever a case in which a dimension is missing, the entire 3D system breaks.

The Vector3 data type enforces and binds those three numbers together so that that does not happen.

Lua
local part = game.Workspace.Part
part.Size = Vector3.new(10, 20, 30)

Just like what you’re familiar with, Vector3 has a ‘new‘ constructor that accepts 3 arguments representing X, Y, and Z respectively.

If you do not provide an argument, a Vector3 with all dimensions set to 0 will be returned.

Every part requires a minimum dimension size of 0.001 studs, so if you attempt to set a dimension to 0, the part will default to 0.001 studs in that dimension.

Since position is represented in three dimensions, the Vector3 can also set a part’s position.

Lua
local part = game.Workspace.Part
part.Position = Vector3.new(11, 22, 33)

The dot operator may be used to read a dimension from a Vector3. This is a read-only property so you cannot modify it, but it is useful if you need to create a new Vector3 that builds on top of another Vector3.

Within a loop, this will create a part that moves some amount during a game.

Lua
local count = 1000
local part = game.Workspace.Part

while count > 0 do
	part.Position = Vector3.new(part.Position.X + 0.1, part.Position.Y, part.Position.Z)
	
	count = count - 1
	task.wait()
end

The current position is used to create a new Vector3 by keeping Y and Z constant and only adding to the X dimension. Because we did not supply an argument to the wait function, it loops once each frame.


Operators

In the same way that number and string datatypes have their own set of operators, the Vector3 also has its own.

Lua
local v3Original = Vector3.new(10, 10, 10)

print(v3Original + Vector3.new(1, 2, 3)) --Output: 11, 12, 13
print(v3Original - Vector3.new(1, 2, 3)) --Output: 9, 8, 7
print(v3Original * Vector3.new(1, 2, 3)) --Output: 10, 20, 30
print(v3Original / Vector3.new(1, 2, 3)) --Output: 10, 5, 3.333
print(v3Original * 2) --Output: 20, 20, 20
print(v3Original / 2) --Output: 5, 5, 5

When a math operation is performed between two Vector3s, the operation is applied to each corresponding axis, like you would expect.

The multiply and divide operators can also accept numbers as their second argument which is then applied to all dimensions.


Script a Moving Billboard

Lets build upon one of the previous examples and create a billboard that cycles back and forth.

The billboard will move along the X-axis. So each time through the loop, we will generate a Vector3 that keeps a constant YZ while incrementing or decrementing the X value. After X exceeds some maximum distance, the direction is reversed.

Lua
local part = game.Workspace.Part
part.Anchored = true
part.Size = Vector3.new(30, 15, 1)
part.Position = Vector3.new(0, 35, -75)

local direction = 1
local speed = 0.2 --in studs per frame
local maxDistance = 50

while true do
	part.Position = part.Position + Vector3.new(direction * speed, 0, 0)

	if part.Position.X > maxDistance or part.Position.X < -maxDistance then
		direction = -direction
	end

	task.wait()
end

Near the top, the ‘Anchored‘ property is set to true. This locks the part in place so that it does not fall as a result of gravity.

The first statement in the loop takes the current position of the part and adds some offset in the X dimension.

Because the part.Position property is a Vector3, it can be added to another Vector3.

Finally, the if statement checks the X position and reverse the direction after it exceeds the max/min X.