RBX docs Docs Idk

Vector3 Methods

Pre-requisites

Before reading this tutorial, you should know about vector3s. An explanation of vector3 exists in the Lua-Learning folder (not anymore). Or check out the Roblox docs.

Info

In this tutorial, I will teach you what each Vector3 method does and some of its use cases.

Dot(other: Vector3): Vector3

This method returns the scalar dot product between two vectors. The scalar dot formula is

scalarDot = (x1 * x2) + (y1 * y2) + (z1 * z2)

How is it useful?

Take this script for an example

local part1 = script.Parent.Part1 -- blue part
local part2 = script.Parent.Part2 -- green part

local dirArrow = script.Parent.Dir 	-- blue/yellow arrow

local function Update()
	-- this will be visualized by the light blue/yellow arrow
	local direction = (part2.Position - part1.Position).Unit

	-- this will be visualized by the black arrow
	local lv = part1.CFrame.lookVector
	local dotProduct = direction:Dot(lv)

	print("Dot: "..dotProduct)

	if dotProduct > 0 then
		-- if part 1 can see part 2
        --turn blue
		dirArrow.Color = Color3.new(0.0352941, 0.537255, 0.811765)
	else
		-- if part 1 cannot  see part 2
        --turn yellow
		dirArrow.Color = Color3.new(1, 1, 0)
	end
	--makes the direction arrow point toward the direction
	dirArrow.CFrame = CFrame.lookAt(part1.Position + Vector3.new(0,.5,0), part1.Position + Vector3.new(0, .5, 0) + direction)

end


Update()
part2.Changed:Connect(Update)

What this script does is if the green part is in a 180-degree view of the blue part, then make the arrow blue. Else make the arrow yellow, which you can see from the gif below. It also prints a value between -1 and 1 if you look at the output on the right side.

img

This can be very useful in some use cases, such as checking if you are in the field of view of an NPC.

But what if I want the NPC’s FOV to be narrower?

What you can do is replace this line

if dotProduct > 0 then

With

if dotProduct > math.cos(math.rad(MAX_ANGLE)) then

img

Why the math.cos you may ask?

Take this image as a reference

img

The bold black arrow is the lookVector. The blue arrows/rays create the cone shape, whereas the pink curve is the range in which the green part is considered inside, and the red line is the red part in the gif.

!!! info

A reminder to everyone that forgot trigonometry, cosine is the x value, and sine is the y value, but in this case, we only care about the x value, which is cosine.

Angle(other: Vector3, axis: Vector3 | nil ): number

This method returns the angle in radians between two vector3s. If an axis is provided, it will return an angle around the specified axis (default is Vector3.zAxis)

Example

(without providing axis)

local part1 = script.Parent.Part1 -- blue part
local part2 = script.Parent.Part2 -- green part

local dirArrow = script.Parent.Dir 	-- blue/yellow arrow


local function Update()
	-- this will be visualized by the light blue/yellow arrow
	local direction = (part2.Position - part1.Position).Unit

	-- this will be visualized by the black arrow
	local lv = part1.CFrame.lookVector
	local Angle = direction:Angle(lv)

	print("Angle: "..math.deg(Angle))

	--makes the direction arrow point toward the direction
	dirArrow.CFrame = CFrame.lookAt(part1.Position + Vector3.new(0, .5, 0), part1.Position + Vector3.new(0, .5, 0) + direction)

end


Update()
part2.Changed:Connect(Update)

img

(with axis argument = Vector3.xAxis) img

!!! info

You can play around more in the test place that I will link at the bottom.

FuzzyEq(other: Vector3, epsilon: number): boolean

This method returns true if the given vector3 is within the current vector3 by the epsilon.

How it works

Source

function fuzzyEq(a, b, epsilon)
	return a == b or math.abs(a - b) <= (math.abs(a) + 1) * epsilon
end

function fuzzyEqVec(v1, v2, epsilon)
	for _, axis in ipairs({"X", "Y", "Z"}) do
		if not fuzzyEq(v1[axis], v2[axis], epsilon) then
			return false
		end
	end

	return true
end

Use cases

You can use it to detect when the player stopped moving using their MoveDirection


local humanoid: Humanoid = script.Parent.Humanoid

humanoid:GetPropertyChangedSignal("MoveDirection"):Connect(function()
	--if it is close by .001
	if humanoid.MoveDirection:FuzzyEq(Vector3.zero, .001) then
		print("Player Stopped Moving")
	end

end)

Cross(other: Vector3): Vector3

This method returns the cross product of the two vectors

Example

The blue arrow is the the direction(self), the yellow arrow is the cross(result), the black arrow is the lookVector(other)

local part1 = script.Parent.Part1 -- blue part
local part2 = script.Parent.Part2 -- green part

local dirArrow = script.Parent.Dir 	-- blue arrow
local crossArrow = script.Parent.Cross 	-- yellow arrow

local function Update()
	-- this will be visualized by the light blue arrow
	local direction = (part2.Position - part1.Position).Unit
	-- this will be visualized by the black arrow
	local lv = part1.CFrame.lookVector
	local Cross = direction:Cross(lv)
	print("Cross:", Cross)

	--makes the direction arrow point toward the direction
	dirArrow.CFrame = CFrame.lookAt(part1.Position + Vector3.new(0, .5, 0), part1.Position+Vector3.new(0, .5, 0) + direction)
	crossArrow.CFrame = CFrame.lookAt(part1.Position + Vector3.new(0, .5, 0), part1.Position+Vector3.new(0, .5, 0) + Cross)

end


Update()
part2.Changed:Connect(Update)

img

Lerp(goal: Vector3, alpha: number): Vector3

This method returns a Vector3 that is interpolated to the goal by the alpha or percent.

How it works

function Lerp(start,goal,alpha)
	return start + (goal - start) * alpha
end

function Vector3Lerp(start,goal,alpha)
	return Vector3.new(
		Lerp(start.X, goal.X, alpha),
		Lerp(start.Y, goal.Y, alpha),
		Lerp(start.Z, goal.Z, alpha),
	)
end

???+ info This also works and is more efficient then the other the way. Because Vector3 has **sub and **add metamethods lua function Vector3Lerp(start,goal,alpha) return Lerp(start,goal,alpha) end

Use Case

You can use it to make parts move smoothly


local start = script.Parent.Part1 -- blue part
local end = script.Parent.Part2 -- green part
local move = script.Parent.Move -- grey part

while true do
	-- lerp forward
	for i = 0, 1, .01 do-- go from 0-1
		task.wait()
		Move.Position = Start.Position:Lerp(End.Position,i)
	end

	task.wait(2)
	-- lerp back
	for i = 0, 1, .01 do -- go from 0-1
		task.wait()
		Move.Position = End.Position:Lerp(Start.Position, i)
	end
	task.wait(2)
	--repeat
end

(gif might be a bit laggy)

img !!! Info “Difference between Lerp and TweenService” Tween service is a roblox Service that only works on Instances while with Lerping you don’t need instances and all you need is just two values.

Min(vector: Vector3): Vector3

This method returns a Vector3 with each component being the lowest value for both Vectors

local vector1 = Vector3.new(5,2,7)
local vector2 = Vector3.new(1,5,3)

print("Min: ", vector2:Min(vector1)) -- "Min: 1,2,3"

Max(vector: Vector3): Vector3

This method returns a Vector3 with each component as the highest for both Vectors

local vector1 = Vector3.new(5,2,7)
local vector2 = Vector3.new(1,5,3)

print("Max: ", vector2:Min(vector1)) -- "Max: 5,5,7"

Conclusion

I hope this helps you understand these methods better and what they do. The link to the example will be here. To view the code, simply make a copy of the game by pressing the 3 dots on the top right and clicking edit. Once you are in, you can move the green parts around to see different results. Anyways bye! (It is currently 4:18 AM, I spent 3 hours on this)