Issues with dashing system

I have been trying to make a dashing system for my game and I have followed countless tutorials and read several topics, but none appeal to what I have been trying to achieve.

I want to create a dash system that:

A) Travels the same distance whether in the air or ground
B) Abides the laws of gravity and you can jump mid dash
C) Is turnable (You can turn mid dash)
D) During the dash the player always faces the opposite direction of the camera
E) Looks smooth

The main issues im having currently is that when I try to make it turnable everything, all the other conditions just fail.

(No turning, works smoothly, can jump)

(Turning, looks really bad and cant jump)

All of the available tutorials on youtube and posts on devforum that I have seen/read do not fulfill all the requirements that I am looking for

3 Likes

im gonna keep it 1000000% with you, I’m not explaining this cuz I have no idea what it means.
But, it works for me so im just gonna give you this I ripped from a video.

local function dashsettings()
		can_dash = false
		local BodyVelo = Instance.new("BodyVelocity", HumanoidRootPart)
		BodyVelo.MaxForce = Vector3.new(math.huge,0,math.huge)
		gameSettings.RotationType = Enum.RotationType.CameraRelative
		for i=50,10,-1.5 do
			local MoveDirection = Humanoid.MoveDirection
			BodyVelo.Velocity = Vector3.new(MoveDirection.X * i,0,MoveDirection.Z * i)
			task.wait()			
		end
		task.delay(1.5, function()
			can_dash = true
		end)
	BodyVelo:Destroy()
	gameSettings.RotationType = Enum.RotationType.MovementRelative
end
local function Dash(action_name, input_state, input_type)
	if input_state == Enum.UserInputState.Begin and can_dash and not attacking and not blocking and not stunned then
	dashsettings()
	end
end

ContextService:BindAction("Dash", Dash, false, Enum.KeyCode.Q)

Lmk if it works or not.

3 Likes

Remove the variables you don’t need my bad

2 Likes

mind sending me the video? There are a few variables which arent defined in the script that you sent (gameSettings, attacking, blocking, stunned) that I want to learn more about, which the context of the video might help with

3 Likes

What I’ve done to solve the same turning issue is consistently updating the player’s velocity relative to the player’s camera (e.g every 0.1s that you’re dashing).

local hrmpt = character.HumanoidRootPart
-- while task.wait(0.1) do
hrmpt.Velocity = Vector3.new(workspace.CurrentCamera.CFrame.LookVector.X * ability.Velocity.Magnitude, hrmpt.Velocity.Y, workspace.CurrentCamera.CFrame.LookVector.Z * ability.Velocity.Magnitude)
-- end

Note that directly modifying the Velocity property isn’t the best idea, but that’s the approach I’ve used. Hope this helps!

2 Likes
External Media

don’t mind the footsteps lol im messing around with a module
also don’t mind the mess

4 Likes

T̶h̶a̶n̶k̶ y̶o̶u̶ s̶o̶ m̶u̶c̶h̶, t̶h̶i̶s̶ w̶o̶r̶k̶s̶, I̶ a̶l̶s̶o̶ h̶a̶v̶e̶ n̶o̶ i̶d̶e̶a̶ w̶h̶y̶, b̶u̶t̶ i̶t̶ d̶o̶e̶s̶!̶

I̶ w̶i̶l̶l̶ t̶r̶y̶ a̶n̶d̶ u̶n̶d̶e̶r̶s̶t̶a̶n̶d̶ w̶h̶y̶ i̶t̶ w̶o̶r̶k̶s̶ a̶n̶d̶ e̶x̶p̶l̶a̶i̶n̶ i̶t̶ s̶o̶ t̶h̶a̶t̶ o̶t̶h̶e̶r̶ p̶e̶o̶p̶l̶e̶ w̶h̶o̶ v̶i̶e̶w̶ t̶h̶i̶s̶ p̶o̶s̶t̶ c̶a̶n̶ u̶n̶d̶e̶r̶s̶t̶a̶n̶d̶, a̶g̶a̶i̶n̶, t̶h̶a̶n̶k̶ y̶o̶u̶ s̶o̶ m̶u̶c̶h̶!̶ (̶a̶l̶s̶o̶, s̶o̶r̶r̶y̶ f̶o̶r̶ t̶h̶e̶ l̶a̶t̶e̶ r̶e̶p̶l̶y̶, I̶ w̶a̶s̶ v̶e̶r̶y̶ b̶u̶s̶y̶)̶

After playing around a bit I found out that all it does is increase the walkspeed then slowly decrease it until it reaches a certain value (in your example, it increases the walkspeed to 50, decreases it by 1.5 per heartbeat until it reaches 10, then it resets it to 16), meaning you can change direction completely mid dash using WASD, which feels to unfair in a fighting game

However the camera rotation works perfectly!

2 Likes

Give me a second to script this really quickly I’ll provide something

1 Like

I have solved most of the problems except for problem A (that the distance is the same in the air or in the ground)

Here is the function that I used:

local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Character = Player.Character
local HRP = Character.PrimaryPart
local Humanoid = Character:FindFirstChildOfClass("Humanoid")
local DebrisService = game:GetService("Debris")
local gameSettings = UserSettings().GameSettings

local Camera = workspace.Camera

local function dashFunction(direction, dashSpeed, dashTime)	
	local cameraLV = Camera.CFrame.LookVector  -- The cameras look vector               
	local HRPCF= Character.HumanoidRootPart.CFrame -- Humanoid Root Parts CFrame
	local flatlook = Vector3.new(cameraLV.X, 0, cameraLV.Z) -- Doesnt Account for Y axis
	local setFrame = CFrame.new(HRPCF.Position, HRPCF.Position + flatlook) -- Future CFrame
	Character:SetPrimaryPartCFrame(setFrame) -- Sets the CFrame so that the new rotation type doesnt get buggy
	gameSettings.RotationType = Enum.RotationType.CameraRelative -- Makes it so character constantly faces away from camera

	local bodyVelocity = Instance.new("BodyVelocity", HRP) 
	bodyVelocity.MaxForce = Vector3.new(1,0,1) * 12000 -- Avoid math.huge, too laggy!

	local impact
	if direction == "backward" or direction == "left" then
		impact = -1 
	else
		impact = 1
	end

	DebrisService:AddItem(bodyVelocity, dashTime)
	if direction == "left" or direction == "right" then
		while bodyVelocity.Parent == HRP do
			if Humanoid:GetState() == Enum.HumanoidStateType.Jumping or Humanoid:GetState() == Enum.HumanoidStateType.Freefall or Humanoid:GetState() == Enum.HumanoidStateType.FallingDown then
				bodyVelocity.Velocity = HRP.CFrame.RightVector * dashSpeed * impact
			else
				bodyVelocity.Velocity = HRP.CFrame.RightVector * dashSpeed * impact * 1.5
			end
			wait(0.1)
		end
	else
		while bodyVelocity.Parent == HRP do
			if Humanoid:GetState() == Enum.HumanoidStateType.Jumping or Humanoid:GetState() == Enum.HumanoidStateType.Freefall or Humanoid:GetState() == Enum.HumanoidStateType.FallingDown then
				bodyVelocity.Velocity = HRP.CFrame.LookVector * dashSpeed * impact
			else 
				bodyVelocity.Velocity = HRP.CFrame.LookVector * dashSpeed * impact * 1.5
			end
			wait(0.1)
		end
	end
	gameSettings.RotationType = Enum.RotationType.MovementRelative -- Returns rotation type to normal
end

With recent edits, problem A is solved however the solution is very band-aid.

1 Like

well my work here is done it is getting too complicated for me good luck bro :skull:

Its probably just my script thats unreadable, mb. Anyways, thanks for all the help! Without your script I genuinely wouldnt have come this far

1 Like

This probably doesn’t do everything you want it to do but it may give you some code to start with, I made this to implement rolling in my movement script, it’s kind of old so keep that in mind if there are any issues, I also just pasted the function so you may need to define some variables beforehand

local function Roll(input, gameProcessedEvent)
	if input.KeyCode == Enum.KeyCode.Q then
		if gameProcessedEvent or not CanRoll then
			return
		end
		RollAnimation:Play()

		HumanoidRootPart.Velocity = HumanoidRootPart.CFrame.LookVector * VelocitySettings.RollForce -- Velocity Settings.RollForce is "RollForce = Vector3.new(150, 150, 150),"

		CanRoll = false
		task.wait(CooldownSettings.RollCooldown)
		RollAnimation:Stop()
		CanRoll = true
	end
end
1 Like

Thanks for telling me to define the functions, I didnt even noticed them when I wrote that, however its updated now, and the problem is solved (for me, at the very least)


If you, the reader, are reading this in the future (when the post is closed and when the reply function is unavailable) and you are not satisfied with the solution, feel free to send me a message. I have most likely found a better solution by then

yooo broo im back, i did a little messing around and this is what i came up with. If you can ignore the messiness. It works completely how you asked. The player cannot change directions during the dash. They can dash in all directions. Also they can rotating while dashing, clipping isn’t an issue and they go the same speed in air and on land.

local function dashnorm(control, ev, increment)
	can_dash = false
	local BodyVelo = Instance.new("BodyVelocity", HumanoidRootPart)
	BodyVelo.MaxForce = Vector3.new(math.huge,0,math.huge)
	gameSettings.RotationType = Enum.RotationType.CameraRelative
	for i=control,ev,increment do
		local MoveDirection = CurrentCamera.CFrame.LookVector
		BodyVelo.Velocity = Vector3.new(MoveDirection.X * i,0,MoveDirection.Z * i)
		task.wait()			
	end
	task.delay(1.5, function()
		can_dash = true
	end)
	BodyVelo:Destroy()
	gameSettings.RotationType = Enum.RotationType.MovementRelative
end

local function dashangled(control, ev, increment)
	can_dash = false
	local BodyVelo = Instance.new("BodyVelocity", HumanoidRootPart)
	BodyVelo.MaxForce = Vector3.new(math.huge,0,math.huge)
	gameSettings.RotationType = Enum.RotationType.CameraRelative
	for i=control,ev,increment do
		local MoveDirection = CurrentCamera.CFrame.RightVector
		BodyVelo.Velocity = Vector3.new(MoveDirection.X * i,0,MoveDirection.Z * i)
		task.wait()			
	end
	task.delay(1.5, function()
		can_dash = true
	end)
	BodyVelo:Destroy()
	gameSettings.RotationType = Enum.RotationType.MovementRelative
end



local function Dash(action_name, input_state, input_type)
	local Velocity = HumanoidRootPart.CFrame:Inverse() * (HumanoidRootPart.Position + HumanoidRootPart.Velocity)
	local yDirect = math.atan2(Velocity.X, -Velocity.Z)
	local rDir = math.ceil(math.deg(yDirect))
	if input_state == Enum.UserInputState.Begin and can_dash then -- put your debounces here.
		if rDir > 45 and rDir < 135 then
			dashangled(55, 10, -1.5)
		elseif rDir < -45 and rDir > -135 then
			dashangled(-55, -10, 1.5)
		elseif rDir <= -135 or rDir >= 135 then
			dashnorm(-55, -10, 1.5)
		elseif rDir > -45 and rDir < 45 then
			dashnorm(55, 10, -1.5)
		end
	end
end

My plan for today is to find out how to clean up my code lol.
but for now this works so im gonna just continue about it

Angled isn’t for angled dashes it’s just for left and right thats all

1 Like

How do I use this? Like, what should the variables (control, ev, increment, action_name, input_state, input_type) be?

Also sorry for the late answer, Ive had lots of family come over so I couldnt really spend time on my pc

Control = your initial dash speed, i’d reccommend 55 or -55 for the opposite.
10 = the end speed of the dash.
1.5 = the rate at which it goes down. lessen it to make the dash longer, greaten it to make the dash shorter.
EXAMPLE*

blah blah front
dashnorm(50,10,-1.5)
blahblah backwards
dashnorm(-50,-10,1.5)
blahblah right
dashangled(50,10,-1.5)
blah blah left
dashangled(-50,-10,1.5)

So for short
CONTROL - Your initial speed during the dash. (Use a positive number for this if you are going forward or right.
END VALUE - The value in which the loop will end/End Velocity Number. ^^^ Same logic as control.
INCREMENT - The speed at which the body velocity goes down/up. It’s defining factor (Positive, Negative) Must be the opposite of the controls defining factor. Or it will not work.

50<- Control, 10 ← EndValue, -1.5 ← Increment.

CONTROL Starting Speed,
EV Ending speed,
INCREMENT Basically just time.

1 Like

THIS IS FIRE!!! So much smoother than mine

I adjusted your function so that it can be used as one function instead of four different ones, the main difference is, however, that I changed the variables. Also, added a direction variable

For starters, control changed to dashStartSpeed for clarity, ev changed to dashEndSpeed, also for more clarity and increment changed completely to dashDuration (increment is converted to time)

I also used a similar method to compact it all into one function, hopefully this time I wrote it more clearly.

Changed its name too because now its just a general dash function

local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Character = Player.Character
local HRP = Character.PrimaryPart
local Humanoid = Character:FindFirstChildOfClass("Humanoid")
local DebrisService = game:GetService("Debris")
local gameSettings = UserSettings().GameSettings
local UIS = game.UserInputService

local Camera = workspace.Camera

local function dashFunction(direction, dashStartSpeed, dashDuration, dashEndSpeed)

	local increment = ((dashEndSpeed- dashStartSpeed) / (dashDuration* 60)) * 2 -- Simple velocity calculation
	local BodyVelocity = Instance.new("BodyVelocity", HRP)
	BodyVelocity.MaxForce = Vector3.new(math.huge,0,math.huge)
	gameSettings.RotationType = Enum.RotationType.CameraRelative --Makes player follow mouse)

	local directionalForce
	if direction == "forward" or direction == "right" then
		directionalForce = 1 -- Imagine that the player position is a graph/2d coordinate, if all values => 0 then its either going up or left
	elseif direction == "backward" or direction == "left" then
		directionalForce = -1 -- And if its all =< 0 then its either going down or left (this works because the dash only changes X or Y value, not both at once)
	end

	for i=dashStartSpeed,dashEndSpeed,increment do
		if direction == "forward" or direction == "backward" then
			local MoveDirection = HRP.CFrame.LookVector
			if Humanoid:GetState() == Enum.HumanoidStateType.Jumping or Humanoid:GetState() == Enum.HumanoidStateType.Freefall or Humanoid:GetState() == Enum.HumanoidStateType.FallingDown then
				BodyVelocity.Velocity = Vector3.new(MoveDirection.X * i * directionalForce, 0, MoveDirection.Z * i * directionalForce) / 1.25 -- So that you dash less further in air
				wait()
			else 
				BodyVelocity.Velocity = Vector3.new(MoveDirection.X * i * directionalForce, 0, MoveDirection.Z * i * directionalForce) 
				wait()
			end
		elseif direction == "left" or direction == "right" then
			local MoveDirection = HRP.CFrame.RightVector
			if Humanoid:GetState() == Enum.HumanoidStateType.Jumping or Humanoid:GetState() == Enum.HumanoidStateType.Freefall or Humanoid:GetState() == Enum.HumanoidStateType.FallingDown then
				BodyVelocity.Velocity = Vector3.new(MoveDirection.X * i * directionalForce, 0, MoveDirection.Z * i * directionalForce) / 1.25 -- So that you dash less further in air
				wait()
			else 
				BodyVelocity.Velocity = Vector3.new(MoveDirection.X * i * directionalForce, 0, MoveDirection.Z * i * directionalForce) 
				wait()
			end
		end		
	end
	BodyVelocity:Destroy()
	gameSettings.RotationType = Enum.RotationType.MovementRelative
end



--test and instructions

--Adjust variables beforehand, this test simulates W being held
local dashDirection 
local dashStartSpeed = 55
local dashDuration = 0.35
local dashEndSpeed = 16



UIS.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.Q then
		-- if WKey == true then
			dashDirection = "forward"
		dashFunction("forward", dashStartSpeed, dashDuration, dashEndSpeed)
	end
end)

I also decided to not put the cooldown in the script because im too tired for that, its like 3 AM.
Anyways, this script works so well now that I understand it, thank you so much!

PS: If you dont want the dash speed to gradually lower, just change the dashEndSpeed to dashStartSpeed - 1

(this also works if you want your dash to start slow and get faster, if you want it to start slow, get fast and then get slow again then you could probably easily do it by just playing around with the function)

PS #2: If all the players have the same dash, consider defining the variables before the function so that its easier to read, in other words


UIS.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.Q then
		-- if WKey == true then
			dashDirection = "forward"
		    dashFunction()
	end
end)

-- Looks way better IMO

Glad I could help dawg :smirk_cat::+1:

1 Like