Help making Dash System

  1. What do you want to achieve? Keep it simple and clear!
    I want to make it so the dash can change the direction of the velocity if the player changes direction mid-dash (ex: if the player dashes forwards with shiftlock on then turns to the left with their camera, it will make the dash go in that direction (similar to blox fruits or tsb dash))
  2. What is the issue? Include screenshots / videos if possible!
    LinearVelocity makes the player go in one direction and it cant be altered. Ive also tried increasing the cframe z, but that also doesnt let you turn
  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    i cant find anyone with my problem, its all people wondering how to check the direction of the player for a dash (i already did this)

Here is the serverscript

dashremote.OnServerEvent:Connect(function(player, dir)
	local character = player.Character or player.CharacterAdded:Wait()
	local hrp = character.HumanoidRootPart
	local hum = character.Humanoid
	if dir == 'forward' then
		--ive tried multiple things here but i want the direction to kinda be relative to the camera?
		--im not sure how to explain it
	elseif dir == 'backward' then
		
	elseif dir == 'left' then
		
	elseif dir == 'right' then
		
	end
end)

and here is the player direction detection localscript:

local function getdirection()
	if uis:IsKeyDown(Enum.KeyCode.A) then
		return 'left'
	elseif uis:IsKeyDown(Enum.KeyCode.D) then
		return 'right'
	elseif uis:IsKeyDown(Enum.KeyCode.S) then
		return 'backward'
	else
		return 'forward'
	end
end
4 Likes

Local script

local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local camera = workspace.CurrentCamera

local function dash()
    local character = player.Character
    if not character then return end
    
    -- Get camera's look vector
    local lookVector = camera.CFrame.LookVector
    
    -- If not in first person, use character's facing direction
    if (camera.CFrame.Position - character.HumanoidRootPart.Position).Magnitude > 1 then
        -- Flatten the look vector to prevent vertical dashing
        lookVector = Vector3.new(lookVector.X, 0, lookVector.Z).Unit
        
        -- Modify direction based on input
        local direction = getdirection()
        if direction == "backward" then
            lookVector = -lookVector
        elseif direction == "left" then
            lookVector = Vector3.new(-lookVector.Z, 0, lookVector.X)
        elseif direction == "right" then
            lookVector = Vector3.new(lookVector.Z, 0, -lookVector.X)
        end
    end
    
    -- Fire remote with look vector
    dashremote:FireServer(lookVector)
end

-- Bind dash to your desired key
UserInputService.InputBegan:Connect(function(input, gameProcessed)
    if input.KeyCode == Enum.KeyCode.Q and not gameProcessed then -- Change Q to your dash key
        dash()
    end
end)

-- Keep your existing getdirection() function
local function getdirection()
    if UserInputService:IsKeyDown(Enum.KeyCode.A) then
        return 'left'
    elseif UserInputService:IsKeyDown(Enum.KeyCode.D) then
        return 'right'
    elseif UserInputService:IsKeyDown(Enum.KeyCode.S) then
        return 'backward'
    else
        return 'forward'
    end
end

Server script fix:

local RunService = game:GetService("RunService")

dashremote.OnServerEvent:Connect(function(player, lookVector)
    local character = player.Character or player.CharacterAdded:Wait()
    local hrp = character.HumanoidRootPart
    local humanoid = character.Humanoid
    
    -- Create a BodyVelocity for smooth dash movement
    local bodyVelocity = Instance.new("BodyVelocity")
    bodyVelocity.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
    bodyVelocity.P = 1000
    bodyVelocity.Velocity = lookVector * 100 -- Adjust speed multiplier as needed
    bodyVelocity.Parent = hrp
    
    -- Remove BodyVelocity after dash duration
    task.delay(0.3, function() -- Adjust dash duration as needed
        bodyVelocity:Destroy()
    end)
end)
1 Like

Im not sure what you mean by this?? Please explain.

But I wrote a better function for your direction detection:

local Player = game.Players.LocalPlayer
local PlayerModule = require(Player:WaitForChild("PlayerScripts"):WaitForChild("PlayerModule"))
local PlayerControls = PlayerModule:GetControls()

function GetPlayerDirection(): string
    local moveVector = PlayerControls:GetMoveVector()

    if moveVector.Magnitude < 0.1 then
        return "Idle"
    elseif moveVector.Z < -0.5 then
        return "Forward"
    elseif moveVector.Z > 0.5 then
        return "Backward"
    elseif moveVector.X > 0.5 then
        return "Right"
    elseif moveVector.X < -0.5 then
        return "Left"
    end

    return "Unknown"
end

in StarterCharacterScripts.LocalScript:

local uis = game:GetService("UserInputService")
local ts = game:GetService("TweenService")

local dash_ti = TweenInfo.new(
	0.1,
	Enum.EasingStyle.Linear,
	Enum.EasingDirection.InOut
)
local dash_distance = 10

local function getdirection()
	local cam_cf = workspace.CurrentCamera.CFrame
	cam_cf = CFrame.lookAlong(
		cam_cf.Position,
		cam_cf.LookVector * Vector3.new(1,0,1), -- remove Y element in look vector
		Vector3.yAxis
	)
	local rot_cf = cam_cf.Rotation
	if uis:IsKeyDown(Enum.KeyCode.A) then
		return (rot_cf * Vector3.new(-1,0,0)).Unit -- left
	elseif uis:IsKeyDown(Enum.KeyCode.D) then
		return (rot_cf * Vector3.new(1,0,0)).Unit -- right
	elseif uis:IsKeyDown(Enum.KeyCode.S) then
		return (rot_cf * Vector3.new(0,0,1)).Unit -- backward
	else
		return (rot_cf * Vector3.new(0,0,-1)).Unit -- forward
	end
end

local char = script.Parent
uis.InputBegan:Connect(function(inp, gpe)
	if gpe then return end
	if inp.KeyCode==Enum.KeyCode.LeftControl then
		local dir = getdirection()
		local hum = char.Humanoid
		local hrp = char.HumanoidRootPart
		local tween = ts:Create(
			hrp,
			dash_ti,
			{
				CFrame = CFrame.lookAlong(
					hrp.Position + dir*dash_distance,
					dir,
					Vector3.yAxis
				)
			}
		)
		tween.Completed:Once(function()
			hum.AutoRotate = true
		end)
		hum.AutoRotate = false
		tween:Play()
	end
end)

Explaination of how it works:
Dashing is generally handled on the client and not on the server unless you have a custom character system where the server owns the character (not default configuration). Generally speaking any character movement of the player’s character is handled locally. This is the default configuration.
→ make local script in StarterCharacterScripts (thus char = script.Parent)

Next we get TweenService to actually animate and not teleport the character to the desired location.

To get the direction with respect to the camera, we get the cframe of the camera with a 0’d Y value in the LookVector.
Then we do cam_cf:VectorToWorldSpace which is the same as cam_cf.Rotation * v3
This will take any vector and rotate it with respect to the rotation of the cframe.
If we did cam_cf * v3 this will be wrong since it transform it “as if the camera was the origin”

Creating the tween:
so I created the tween with the goal of

CFrame = CFrame.lookAlong(
	hrp.Position + dir*dash_distance,
	dir,
	Vector3.yAxis
)

This is the position of the HumanoidRootPart plus the direction times the distance. It is looking in the direction of the dash (LookVector), and has an UpVector of the Y axis.

Finally, I disable AutoRotate to prevent the character from rotating while the tween is rotating.

seems a little ai generated, also bodyvelocity is deprecated dont use it

you can make a vector force, set the force to the Camera.CFrame.LookAt and then multiplying that with the force you want to exert

this actually works pretty well when i put it in a for loop and changed some variables, but i cant use it because i need to be able to use main.spawnhitbox at the end (im making a combat system)

Pass the direction vector3 to the server instead of a left,right,forward,backward
Play the tween on the server.

when you are dashing, you shouldnt be able to control the direction with wasd but you can here.

bro in your code you posted you straight up check for ASD and etc for direction. And then you said you want the forward direction to be with respect to camera. Camera is NOT replicated to the server so you have to get it from the client. So what do you want?

sorry if i explained it bad. im still a little new to scripting. im making a combat system and im making it so the front dash sends you forward (obviously). However, just adding a linearvelocity makes you just go in one direction you can’t change. I want the front dash to make you go forward, but if you are in shiftlock and turn your camera, it will also change the direction of the dash. I dont want wasd to affect it at all, only the camera. If you still dont understand go play The Strongest Battlegrounds and see their front dash.

change getdirection function to this:

local function getdirection() : (Vector3, Vector3)
	local cam_cf = workspace.CurrentCamera.CFrame
	cam_cf = CFrame.lookAlong(
		cam_cf.Position,
		cam_cf.LookVector * Vector3.new(1,0,1), -- remove Y element in look vector
		Vector3.yAxis
	)
	local rot_cf = cam_cf.Rotation
	local lv = rot_cf.LookVector
	if uis:IsKeyDown(Enum.KeyCode.A) then
		return (rot_cf * Vector3.new(-1,0,0)).Unit, lv -- left
	elseif uis:IsKeyDown(Enum.KeyCode.D) then
		return (rot_cf * Vector3.new(1,0,0)).Unit, lv -- right
	elseif uis:IsKeyDown(Enum.KeyCode.S) then
		return (rot_cf * Vector3.new(0,0,1)).Unit, lv -- backward
	else
		return (rot_cf * Vector3.new(0,0,-1)).Unit, lv -- forward
	end
end

change variables to get the lookvector:

local dir, char_lv = getdirection()

finally change the looking direction:

local tween = ts:Create(
	hrp,
	dash_ti,
	{
		CFrame = CFrame.lookAlong(
			hrp.Position + dir*dash_distance,
			char_lv, -- changed to make character look in the direction of the camera
			Vector3.yAxis
		)
	}
)