The Ultimate Guide to Vector3:Cross() and Vector3:Dot()

Uh @Moonvane , what if their angle are 45, will it be -0.5

3 Likes

Yes it will be 0.5 if the angles are 45 from each other and -0.5 if the angles are 135 degrees from eachother (135 is just the flipped version of 45)

2 Likes

I made a car, and I would like to detect next waypoints, the car moves by waypoints, if the next way point is to the right side of car, car should turn right

How do I detect if the waypoint is right side of the car

1 Like

Ok this actually doesn’t even need to use Dot, what you can do is just number the waypoints in order and then tween the car to the next waypoint.

1 Like

No like, the car moves through tween, but the thing is, the steering inside the car should also move like auto pilot, so I need to detect left or right the car moves in order to find which side its going

How do I do it?

1 Like

You can use dot product to find the angle, and cross product to find the direction left or right.

Ex from Sleitnick is AngleBetween signed:

local function AngleBetween(vectorA, vectorB)
	return math.acos(math.clamp(vectorA:Dot(vectorB), -1, 1))
end

local function AngleBetweenSigned(vectorA, vectorB, axis)
	local unsigned = AngleBetween(vectorA, vectorB)
	local cross = vectorA:Cross(vectorB)
	local sign = math.sign((axis.X * cross.X) + (axis.Y * cross.Y) + (axis.Z * cross.Z))
	return (unsigned * sign)
end
3 Likes

It does not work either it gets the correct angle

2 Likes

Well that is the simplest explanation of cross and dot I have ever seen. Incredible.
Great job, best tutorial on the devforum by far.

1 Like

I appreciate it dude!!
This is enough chrar

1 Like

I really used to think these are complicated and for crazy good scripters who know what they are doing but turns out its simple as heck ty man have a great life!

1 Like

hi i was wondering if you knew how to find if the player is going down a slope, I need it to make the player go faster when they are sliding down a slope. this is what I have but what would go in the NORMAL part of the script

local incline = Vector3.new(1, 0, 0):Cross(Vector3.new(NORMAL)

				if incline.magnitude == 0 then
					incline = Vector3.new(1, 0, 0)
				end

				local angle = math.acos(Vector3.new(0, 1, 0):Dot(incline))
				if angle > math.pi / 1.5 then
					print("Angle")
					Slide.Velocity = angle * Slide.Velocity * 1.15
				else
					print("No Angle")
					Slide.Velocity = Slide.Velocity * 0.99
				end
1 Like

Ok so this is a perfect example of somewhere where you can utilize Dot, and I love the way you did it in your code. Personally, I would just use a raycast from your HumanoidRootPart directly downward and then just use the normal from that.
(
local ray = workspace:Raycast(HRP.Position, Vector3.new(0, -hipheight - 1, 0), params)
local normal = ray and ray.Normal
)

1 Like

thank you so much i will try that

Its not working but im pretty sure this is my fault, as I’m very new to raycasting I think my variables are off.

local HumanoidRootPart = Character.PrimaryPart
local HipHeight = Humanoid.HipHeight
local Params = RaycastParams.new()
local ray = workspace:Raycast(HumanoidRootPart.Position, Vector3.new(0, -HipHeight - 1, 0), Params)
local normal = ray and ray.Normal

				local incline = Vector3.new(1, 0, 0):Cross(Vector3.new(normal))

				if incline.magnitude == 0 then
					incline = Vector3.new(1, 0, 0)
				end

				local angle = math.acos(Vector3.new(0, 1, 0):Dot(incline))
				if angle > math.pi / 1.5 then
					print("Angle")
					Slide.Velocity = angle * Slide.Velocity * 1.15
				else
					print("No Angle")
					Slide.Velocity = Slide.Velocity * 0.95
				end
1 Like

Ok yes do for the raycast, you will want to include an ignorelist. Do it like this:

local params = RaycastParams.new()
params.FilterDescendantsInstances = {player.Character}
params.FilterType = Enum.RaycastFilterType.Blacklist

ok thanks im trying it out now

ok so I dont think its working but my code is all messed up and I was wondering if you could help. basically I’m running a while true do lap but I couldn’t get the loop to stop when the player stoped sliding so I added a spawn() function hoping I would be able to stop it but I couldn’t and it kept running only difference is now the rest of my code is running with the spawn function still going but I want it to stop when the player stops sliding any tips if I should use a different loop or something to stop it. here’s the code:

local function OnHoldingDown(Action)
print(Variables.Sprinting)
if Module.HoldDownEnabled then
if not Variables.Overheated and Variables.ActuallyEquipped and Variables.Enabled and Variables.Sprinting == true then
Character.Humanoid.WalkSpeed = 0

  	local Slide = Instance.new("BodyVelocity")
  	
  	if Action == "Go"  and not HoldingDownCooldown then
  		ReplicatedStorage.Modules.ViewmodelHandler.Sliding.Value = true
  		HoldingDownCooldown = true
  		Variables.HoldDown = true
  		
  		--if Animations.HoldDownAnim then
  		--	Animations.HoldDownAnim:Play(nil, nil, Module.HoldDownAnimationSpeed)
  		--end
  		--if VMAnimations.VMHoldDownAnim then
  		--	VMAnimations.VMHoldDownAnim:Play(nil, nil, Module.VMHoldDownAnimationSpeed)
  		--end
  		Humanoid.HipHeight = 0.5
  		Slide.MaxForce = Vector3.new(1,0,1) * 45000
  		Slide.Velocity = Character.HumanoidRootPart.CFrame.lookVector * 50
  		Slide.Parent = Character.HumanoidRootPart
  		spawn(function()
  			while true do
  				wait(0.1)
  				if Variables.Sprinting == true then
  					local HumanoidRootPart = Character.PrimaryPart
  					local HipHeight = Humanoid.HipHeight
  					local Params = RaycastParams.new()
  					Params.FilterDescendantsInstances = {Character}
  					Params.FilterType = Enum.RaycastFilterType.Blacklist
  					local ray = workspace:Raycast(HumanoidRootPart.Position, Vector3.new(0, -HipHeight - 1, 0), Params)
  					local normal = ray and ray.Normal

  					local incline = Vector3.new(1, 0, 0):Cross(Vector3.new(normal))

  					if incline.magnitude == 0 then
  						incline = Vector3.new(1, 0, 0)
  					end

  					local angle = math.acos(Vector3.new(0, 1, 0):Dot(incline))
  					if angle > math.pi / 1.5 then
  						print("Angle")
  						Slide.Velocity = angle * Slide.Velocity * 1.5
  					else
  						print("No Angle")
  						Slide.Velocity = Slide.Velocity * 0.8
  					end
  				else
  					repeat wait(0.1) until Variables.Sprinting == true
  				end
  			end
  		end)
  	else
  		Character.Humanoid.WalkSpeed = 16
  		Variables.HoldDown = false
  		
  		--if Animations.IdleAnim then
  		--	Animations.IdleAnim:Play(nil, nil, Module.IdleAnimationSpeed)
  		--end
  		--if VMAnimations.VMIdleAnim then
  		--	VMAnimations.VMIdleAnim:Play(nil, nil, Module.VMIdleAnimationSpeed)
  		--end
  		--if Animations.HoldDownAnim and Animations.HoldDownAnim.IsPlaying then
  		--	Animations.HoldDownAnim:Stop()
  		--end
  		--if VMAnimations.VMHoldDownAnim and VMAnimations.VMHoldDownAnim.IsPlaying then
  		--	VMAnimations.VMHoldDownAnim:Stop()
  		--end
  		Humanoid.HipHeight = 2
  		Slide:Destroy()
  		Character.PrimaryPart.Velocity = Vector3.new(0,0,0)
  		ReplicatedStorage.Modules.ViewmodelHandler.Sliding.Value = false
  		wait(0.5)
  		HoldingDownCooldown = false
  	end
  end

end

1 Like

I actually have a trick I use for something like this. I do something like this:

function executeSlide()
    local localFunctionId = os.clock()
    globalFunctionId = localFunctionId

    while wait(0.1) do
       if localFunctionId ~= globalFunctionId then
            break
        end
        dostuff()
    end
end


-- and in a different part of the script when the player stops sliding, do this:
globalFunctionId = os.clock()

thanks but what is GlobalFunctionId it is underlining it like it doesn’t recognise it

TYSM I WORKED but that problem I had at the start still remains its not detecting the Slope or Angle here’s the script one more time:

Script Here

local function OnHoldingDown(Action)
print(Variables.Sprinting)
if Module.HoldDownEnabled then
if not Variables.Overheated and Variables.ActuallyEquipped and Variables.Enabled and Variables.Sprinting == true then

		local Slide = Instance.new("BodyVelocity")
		
		if Action == "Go"  and not HoldingDownCooldown then
			Character.Humanoid.WalkSpeed = 0
			ReplicatedStorage.Modules.ViewmodelHandler.Sliding.Value = true
			HoldingDownCooldown = true
			Variables.HoldDown = true
			
			--if Animations.HoldDownAnim then
			--	Animations.HoldDownAnim:Play(nil, nil, Module.HoldDownAnimationSpeed)
			--end
			--if VMAnimations.VMHoldDownAnim then
			--	VMAnimations.VMHoldDownAnim:Play(nil, nil, Module.VMHoldDownAnimationSpeed)
			--end
			Humanoid.HipHeight = 0.5
			Slide.MaxForce = Vector3.new(1,0,1) * 45000
			Slide.Velocity = Character.HumanoidRootPart.CFrame.lookVector * 50
			Slide.Parent = Character.HumanoidRootPart
			GlobalFunctionId = localFunctionId
			spawn(function()
				while wait(0.1) do
					if localFunctionId ~= GlobalFunctionId then
						Slide.Velocity = Slide.Velocity * 0
						if Slide then
							Slide:Destroy()
						end
						break
					end
					
					if Variables.Sprinting == true then
						local HumanoidRootPart = Character.PrimaryPart
						local HipHeight = Humanoid.HipHeight
						local Params = RaycastParams.new()
						Params.FilterDescendantsInstances = {Character}
						Params.FilterType = Enum.RaycastFilterType.Blacklist
						local ray = workspace:Raycast(HumanoidRootPart.Position, Vector3.new(0, -HipHeight - 1, 0), Params)
						local normal = ray and ray.Normal

						local incline = Vector3.new(1, 0, 0):Cross(Vector3.new(normal))

						if incline.magnitude == 0 then
							incline = Vector3.new(1, 0, 0)
						end

						local angle = math.acos(Vector3.new(0, 1, 0):Dot(incline))
						if angle > math.pi / 1.5 then
							print("Angle")
							Slide.Velocity = angle * Slide.Velocity * 1.1
						else
							print("No Angle")
							Slide.Velocity = Slide.Velocity * 0.9
						end
					else
						repeat wait(0.1) until Variables.Sprinting == true
					end
				end
			end)
		else
			GlobalFunctionId = os.clock()
			Character.Humanoid.WalkSpeed = 16
			Variables.HoldDown = false
			
			--if Animations.IdleAnim then
			--	Animations.IdleAnim:Play(nil, nil, Module.IdleAnimationSpeed)
			--end
			--if VMAnimations.VMIdleAnim then
			--	VMAnimations.VMIdleAnim:Play(nil, nil, Module.VMIdleAnimationSpeed)
			--end
			--if Animations.HoldDownAnim and Animations.HoldDownAnim.IsPlaying then
			--	Animations.HoldDownAnim:Stop()
			--end
			--if VMAnimations.VMHoldDownAnim and VMAnimations.VMHoldDownAnim.IsPlaying then
			--	VMAnimations.VMHoldDownAnim:Stop()
			--end
			Humanoid.HipHeight = 2
			Slide:Destroy()
			Character.PrimaryPart.Velocity = Vector3.new(0,0,0)
			ReplicatedStorage.Modules.ViewmodelHandler.Sliding.Value = false
			wait(0.5)
			HoldingDownCooldown = false
		end
	end
end

end