Hey, Ive been struggling with a dash system every since BodyVelocity got Deprecated and using LinearVelocity has just been a migraine.
The problems ive been encountering includes
- Player Dash Distance on Land is Very Different than in the air
- LinearVelocity is pulling the player left or right when trying to dash forward and is very inconsistent Weird (In the video im holding down Q + W and im only suppose to be moving forward)
What The DashS ystem Is…
The dash system allows the player to dash a specific direction without actually needing to face that direction. I do this by tracking what movement key the player is pressing while their hitting the dash keybind
For example…
Q + W = Dash Forward
Q + S = Dash Backward
Q + A = Dash Left
A + D = Dash Right
Here is how im accomplishing this
-- Services
local UserInputService : UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players : Players = game:GetService("Players")
local RunService : RunService = game:GetService("RunService")
-- @Modules & Folders
local dashFolder = ReplicatedStorage:WaitForChild("Movement"):WaitForChild("Dash")
local dashAnimationFolder = dashFolder:WaitForChild("Animations")
local CharacterMovment = require(ReplicatedStorage:WaitForChild("Modules"):WaitForChild("Character"))
-- @Character Objects
local player : Player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoidRootPart : Part = character:WaitForChild("HumanoidRootPart")
local humanoid : Humanoid = character:WaitForChild("Humanoid")
local animator : Animator = humanoid:WaitForChild("Animator")
-- @Animations
local frontRoll : AnimationTrack = animator:LoadAnimation(dashAnimationFolder:WaitForChild("RollFront"))
local backRoll : AnimationTrack = animator:LoadAnimation(dashAnimationFolder:WaitForChild("BackRoll"))
local rightRoll : AnimationTrack = animator:LoadAnimation(dashAnimationFolder:WaitForChild("RightRoll"))
local leftRoll : AnimationTrack = animator:LoadAnimation(dashAnimationFolder:WaitForChild("LeftRoll"))
-- @Config
local debounce : boolean = false
local D_KeyDown : boolean = false
local A_KeyDown : boolean = false
local S_Keydown : boolean = false
local W_KeyDown : boolean = false
UserInputService.InputBegan:Connect(function(Input : InputObject, gameProcessedEvent : boolean)
-- If User is typing we exit ignore this function
if gameProcessedEvent then return end
if Input.KeyCode == Enum.KeyCode.Q and debounce == false then
-- Set Debounce to true
debounce = true
-- After some time we use task.delay to handle
-- our cooldown on a seperate thread
task.delay(1.25, function()
debounce = false
end)
if W_KeyDown then
frontRoll.Priority = Enum.AnimationPriority.Action4
frontRoll:Play()
CharacterMovment:Dash(character, 0)
elseif S_Keydown then
backRoll.Priority = Enum.AnimationPriority.Action4
backRoll:Play()
CharacterMovment:Dash(character, 1)
elseif A_KeyDown then
leftRoll.Priority = Enum.AnimationPriority.Action4
leftRoll:Play()
CharacterMovment:Dash(character, 2)
elseif D_KeyDown then
rightRoll.Priority = Enum.AnimationPriority.Action4
rightRoll:Play()
CharacterMovment:Dash(character, 3)
end
end
end)
RunService.RenderStepped:Connect(function()
if UserInputService:IsKeyDown(Enum.KeyCode.W) then
W_KeyDown = true
else
W_KeyDown = false
end
if UserInputService:IsKeyDown(Enum.KeyCode.A) then
A_KeyDown = true
else
A_KeyDown = false
end
if UserInputService:IsKeyDown(Enum.KeyCode.S) then
S_Keydown = true
else
S_Keydown = false
end
if UserInputService:IsKeyDown(Enum.KeyCode.D) then
D_KeyDown = true
else
D_KeyDown = false
end
end)
The Problem starts to show when I call the CharacterMovment:Dash()
function though. Here is the logic behind the function
local CharacterMovment = {
Distance = 30,
Duration = .5,
Amount = 300,
airAmount = 300 / 2
}
function CharacterMovment:Dash(Character : Model, Direction : number)
if not Character then
warn("Character dosnt exist, did not apply dash")
return
end
local humanoidRootPart : Part = Character:WaitForChild("HumanoidRootPart")
local humanoid : Humanoid = Character:FindFirstChildWhichIsA("Humanoid")
local Velocity : LinearVelocity = Instance.new("LinearVelocity")
Velocity.MaxForce = 10000
Velocity.RelativeTo = Enum.ActuatorRelativeTo.World
Velocity.VelocityConstraintMode = Enum.VelocityConstraintMode.Plane
Velocity.PrimaryTangentAxis = Vector3.new(1,0,0)
Velocity.SecondaryTangentAxis = Vector3.new(0,0,1)
Velocity.Attachment0 = humanoidRootPart:WaitForChild("VectorForceAttachment")
local zeroYAxisLinearVelocity = Instance.new("LinearVelocity")
zeroYAxisLinearVelocity.VelocityConstraintMode = Enum.VelocityConstraintMode.Line
zeroYAxisLinearVelocity.Attachment0 = humanoidRootPart:WaitForChild("VectorForceAttachment")
zeroYAxisLinearVelocity.RelativeTo = Enum.ActuatorRelativeTo.World
zeroYAxisLinearVelocity.Enabled = false
zeroYAxisLinearVelocity.MaxForce = 10000
zeroYAxisLinearVelocity.LineDirection = Vector3.yAxis
zeroYAxisLinearVelocity.Parent = humanoidRootPart
Velocity.Parent = humanoidRootPart
-- IF the player is not in the air we apply basic amount of force
if humanoid.FloorMaterial ~= Enum.Material.Air then
if Direction == 0 then
local dashDirection = humanoidRootPart.CFrame.LookVector
dashDirection = Vector3.new(dashDirection.X, 0, dashDirection.Z).Unit
Velocity.PlaneVelocity = Vector2.new(dashDirection.X, dashDirection.Z).Unit * self.Amount
zeroYAxisLinearVelocity.LineVelocity = 0
elseif Direction == 1 then
local dashDirection = humanoidRootPart.CFrame.LookVector
dashDirection = Vector3.new(dashDirection.X, 0, dashDirection.Z).Unit
Velocity.PlaneVelocity = Vector2.new(dashDirection.X, dashDirection.Z).Unit * -self.Amount
zeroYAxisLinearVelocity.LineVelocity = 0
elseif Direction == 2 then
local dashDirection = humanoidRootPart.CFrame.RightVector
dashDirection = Vector3.new(dashDirection.X, 0, dashDirection.Z).Unit
Velocity.PlaneVelocity = Vector2.new(dashDirection.X, dashDirection.Z).Unit * -self.Amount
zeroYAxisLinearVelocity.LineVelocity = 0
elseif Direction == 3 then
local dashDirection = humanoidRootPart.CFrame.RightVector
dashDirection = Vector3.new(dashDirection.X, 0, dashDirection.Z).Unit
Velocity.PlaneVelocity = Vector2.new(dashDirection.X, dashDirection.Z).Unit * self.Amount
zeroYAxisLinearVelocity.LineVelocity = 0
end
-- if the player is in the air then we half the basic amount of force applied
elseif humanoid.FloorMaterial == Enum.Material.Air then
if Direction == 0 then
local dashDirection = humanoidRootPart.CFrame.LookVector
dashDirection = Vector3.new(dashDirection.X, 0, dashDirection.Z).Unit
Velocity.PlaneVelocity = Vector2.new(dashDirection.X, dashDirection.Z).Unit * self.airAmount
zeroYAxisLinearVelocity.LineVelocity = 0
elseif Direction == 1 then
local dashDirection = humanoidRootPart.CFrame.LookVector
dashDirection = Vector3.new(dashDirection.X, 0, dashDirection.Z).Unit
Velocity.PlaneVelocity = Vector2.new(dashDirection.X, dashDirection.Z).Unit * -self.airAmount
zeroYAxisLinearVelocity.LineVelocity = 0
elseif Direction == 2 then
local dashDirection = humanoidRootPart.CFrame.RightVector
dashDirection = Vector3.new(dashDirection.X, 0, dashDirection.Z).Unit
Velocity.PlaneVelocity = Vector2.new(dashDirection.X, dashDirection.Z).Unit * -self.airAmount
zeroYAxisLinearVelocity.LineVelocity = 0
elseif Direction == 3 then
local dashDirection = humanoidRootPart.CFrame.RightVector
dashDirection = Vector3.new(dashDirection.X, 0, dashDirection.Z).Unit
Velocity.PlaneVelocity = Vector2.new(dashDirection.X, dashDirection.Z).Unit * self.airAmount
zeroYAxisLinearVelocity.LineVelocity = 0
end
end
game.Debris:AddItem(Velocity, self.Duration)
game.Debris:AddItem(zeroYAxisLinearVelocity, self.Duration)
end
Any form of help would be appreciated as i know little amount when it comes to physics and vectors.