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
Bump since this post is very helpful, thanks for making it.
I am going to use dot for my game. The soldiers that you control move and turn via AlignForce/Orientation respectively, meaning its not instant turning so the unit can only shoot once it has lined up the shot. So i will use the dot product of the offset vector (offset vector from object a to b is always B.Position - A.Position) and the units LookVector to see if it is able to shoot
Ok so there are just a couple things about this, number one:
if incline.magnitude == 0 then
This will literally never occur, instead it get down to like 0.005. Replace that with this:
if incline.magnitude < 0.01 then
Next, you may have meant to write this instead:
local incline = Vector3.new(0, 1, 0):Cross(Vector3.new(normal))
Vector3.new(1, 0, 0) is a vector pointing directly to the right, so I donāt think thats what you meant to put, however Vector3.new(0, 1, 0) faces directly up.
Hope all this helps man!
It seems to print the same thing still (āNo Angleā) Although I feel Iām getting really close to getting it right
so here is my new script:
local function OnHoldingDown(Action)
if Module.HoldDownEnabled then
if not Variables.Overheated and Variables.ActuallyEquipped and Variables.Enabled 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(0, 1, 0):Cross(Vector3.new(normal))
if incline.magnitude < 0.01 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
Sorry if Iām late, but how exactly would you do this?
So basically, since you can use Dot to calculate how much your camera is looking at something:
First, find the unit vector between the monsterās position and your characterās position,
local unit = (monsterPosition - localCharacterPosition).Unit
This āunitā variable above is a Vector3 unit direction that the monster is from you.
You can calculate how much your camera is going in that direction by using:
local dotProduct = unit:Dot(camera.CFrame.LookVector)
The closer to -1 this ādotProductā variable is, the farther away from the monster you are looking!
Thank you, this really helped!
How can I implement this into my flying system to turn like a airplane?