Uh @Moonvane , what if their angle are 45, will it be -0.5
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)
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
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.
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?
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
It does not work either it gets the correct angle
Well that is the simplest explanation of cross and dot I have ever seen. Incredible.
Great job, best tutorial on the devforum by far.
I appreciate it dude!!
This is enough chrar
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!
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
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
)
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
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 = 0local 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
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