Dash dependant on camera tutorial

What do I mean by dash based on camera?
The dash changes direction depending on where the characters camera is facing.
Heres an example:

dash

This will be my first time documenting my scripting - go easy on me

To achieve a dash that changes dependant on the cameras direction is somewhat simple.

First I detect if the player has pressed w/a/s/d/q in a local script in StarterCharacterScripts

local player = game.Players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
repeat wait() until player.Character
char = player.Character
local w = false
local a = false
local s = false
local d = false
local ctrl = false
local m = player:GetMouse() -- used to detect input
local UIS = game:GetService("UserInputService")
local cam = game.Workspace.CurrentCamera -- camera
local CD = false
-------------------------
m.KeyDown:connect(function(key)
	if key == "w" then
		print(key)
		w = true
	elseif key == "s" then
		print(key)
		s = true
	elseif key == "a" then
		print(key)
		a = true
	elseif key == "d" then
		print(key)
		d = true
	elseif key == "q" then
		print("q pressed")
	end
end)

Now I create a dash function (make sure to create this function ABOVE the keydown function)

function Dash(Speed, Duration)
	if not w and not a and not s and not d then return end
	CD = true -- sets debounce
	spawn(function() -- spawn a function so "wait" doesn't interfere with the function
		wait(1.5)
		CD = false
	end)
	local v = Instance.new("BodyVelocity") -- creates a new body velocity in the character
	v.MaxForce = Vector3.new(50000, 0, 50000)
	v.Name = "DashVelocity"
	v.Parent = char.HumanoidRootPart

	local Way = 0 -- this will be the direction the dash will be in (left, right, etc)
	if UIS.MouseBehavior == Enum.MouseBehavior.LockCenter then -- detects if the player is in shiftlock
		if a == true then -- left
                -- put animations here
			Way = -90 
		elseif d == true then  -- right

			Way = 90
		elseif w == true then  -- forward

			Way = -180
		elseif s == true then -- backward

			Way = 0 -- is set to 0 because you are going backwards when the bodyvelocity is added
		end
	end
end

In the future, when this runs, if you unshiftlock and press w, the character will always go backwards. To fix this do this:

function Dash(Speed, Duration)
	if not w and not a and not s and not d then return end
	CD = true -- sets debounce
	spawn(function() -- spawn a function so "wait" doesn't interfere with the function
		wait(1.5)
		CD = false
	end)
	local v = Instance.new("BodyVelocity") -- creates a new body velocity in the character
	v.MaxForce = Vector3.new(50000, 0, 50000)
	v.Name = "DashVelocity"
	v.Parent = char.HumanoidRootPart

	local Way = 0 -- this will be the direction the dash will be in (left, right, etc)
	if UIS.MouseBehavior == Enum.MouseBehavior.LockCenter then -- detects if the player is in shiftlock
		if a == true then -- left
                -- put animations here
			Way = -90 
		elseif d == true then  -- right

			Way = 90
		elseif w == true then  -- forward

			Way = -180
		elseif s == true then -- backward

			Way = 0 -- is set to 0 because you are going backwards when the bodyvelocity is added
		end
	else -- not in shiftlock
		if a == true then
                -- put the same animaton for each dash here
			Way = -90 
		elseif d == true then 

			Way = 90
		elseif w == true then 

			Way = -180
		elseif s == true then

			Way = 0
		end
	end
end



We aren’t done with the dash function yet! Now for the camera work:

local canloope = true -- determines if you can loop through or not

	spawn(function() -- spawn a function so this doesn't interfere with anything
		while true do 
			if canloope then else break end -- detects if you can loop through or not, if not then it breaks
			if v then -- remembers "v" is the name of the bodyvelocity we created, so it's detecting if v exists.
				local c1 = Vector3.new(cam.CFrame.X, char.HumanoidRootPart.CFrame.Y, cam.CFrame.Z)-- c1 is equal to the current camera, but the y value is changed to the characters cframe
				local c2 = cam.CFrame * CFrame.new(0, 0, 2) -- changes the cameras cframe
				local c2 = Vector3.new(c2.X, char.HumanoidRootPart.CFrame.Y, c2.Z) -- this is basically c1, except inserting c2 to the x and z values
				local DD = CFrame.new(c1, c2)*CFrame.Angles(0,  math.rad(Way), 0) -- this is everything wrapped together. "Way" is the direction you're going, this makes the dash go the direction your camera is facing
				if v then
					v.Velocity = DD.lookVector *(Speed + (Speed)) -- "Speed" is a variable you can change
				end
			end
			wait(.05) -- every 0.05 seconds the direction of the dash gets updated dependant on the characters camera direction. also added so the game doesnt die. (dont forget this is in a while true do)
		end
	end)

	wait(Duration) -- this is how long the dash will last.

	canloope = false -- breaks the while true do.

	if v then v:Destroy() end -- destroys the body velocity.

This completes the dash function. Woah there- we aren’t done yet. We have to return to the keydown detection to add the function in as well as detect when a key is lifted.

m.KeyDown:connect(function(key)
	if key == "w" then
		print(key)
		w = true
	elseif key == "s" then
		print(key)
		s = true
	elseif key == "a" then
		print(key)
		a = true
	elseif key == "d" then
		print(key)
		d = true
	elseif key == "q" and CD == false then
		print("q pressed")
		Dash(20, .35) -- insert your own values here, or have mine <3
	end
end)

-- now detect when the key is released

m.KeyUp:connect(function(key)
	if key == "w" then
		w = false
	elseif key == "s" then
		s = false
	elseif key == "a" then
		a = false
	elseif key == "d" then
		d = false
	end
end)

Hope this helps! If you have any questions please ask. I’m unsure if this was confusing or not. Heres what the final product looks like:

30 Likes

is this all in a local script? can u also compile it into 1 whole section instead of splitting it into different parts becuz some parts have varibles that i dont get

1 Like

It is indeed all in a local script. I’ll gladly compile all the parts together for you!

local player = game.Players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
repeat wait() until player.Character
char = player.Character
local w = false
local a = false
local s = false
local d = false
local ctrl = false
local m = player:GetMouse() -- used to detect input
local UIS = game:GetService("UserInputService")
local cam = game.Workspace.CurrentCamera -- camera
local CD = false
-------------------------
function Dash(Speed, Duration)
	if not w and not a and not s and not d then return end
	CD = true -- sets debounce
	spawn(function() -- spawn a function so "wait" doesn't interfere with the function
		wait(1.5)
		CD = false
	end)
	local v = Instance.new("BodyVelocity") -- creates a new body velocity in the character
	v.MaxForce = Vector3.new(50000, 0, 50000)
	v.Name = "DashVelocity"
	v.Parent = char.HumanoidRootPart

	local Way = 0 -- this will be the direction the dash will be in (left, right, etc)
	if UIS.MouseBehavior == Enum.MouseBehavior.LockCenter then -- detects if the player is in shiftlock
		if a == true then -- left
			-- put animations here
			Way = -90 
		elseif d == true then  -- right

			Way = 90
		elseif w == true then  -- forward

			Way = -180
		elseif s == true then -- backward

			Way = 0 -- is set to 0 because you are going backwards when the bodyvelocity is added
		end
	else -- not in shiftlock
		if a == true then
			-- put the same animaton for each dash here
			Way = -90 
		elseif d == true then 

			Way = 90
		elseif w == true then 

			Way = -180
		elseif s == true then

			Way = 0
		end
	end
	local canloope = true -- determines if you can loop through or not

	spawn(function() -- spawn a function so this doesn't interfere with anything
		while true do 
			if canloope then else break end -- detects if you can loop through or not, if not then it breaks
			if v then -- remembers "v" is the name of the bodyvelocity we created, so it's detecting if v exists.
				local c1 = Vector3.new(cam.CFrame.X, char.HumanoidRootPart.CFrame.Y, cam.CFrame.Z)-- c1 is equal to the current camera, but the y value is changed to the characters cframe
				local c2 = cam.CFrame * CFrame.new(0, 0, 2) -- changes the cameras cframe
				local c2 = Vector3.new(c2.X, char.HumanoidRootPart.CFrame.Y, c2.Z) -- this is basically c1, except inserting c2 to the x and z values
				local DD = CFrame.new(c1, c2)*CFrame.Angles(0,  math.rad(Way), 0) -- this is everything wrapped together. "Way" is the direction you're going, this makes the dash go the direction your camera is facing
				if v then
					v.Velocity = DD.lookVector *(Speed + (Speed)) -- "Speed" is a variable you can change
				end
			end
			wait(.05) -- every 0.05 seconds the direction of the dash gets updated dependant on the characters camera direction. also added so the game doesnt die. (dont forget this is in a while true do)
		end
	end)

	wait(Duration) -- this is how long the dash will last.

	canloope = false -- breaks the while true do.

	if v then v:Destroy() end -- destroys the body velocity.
end


m.KeyDown:connect(function(key)
	if key == "w" then
		print(key)
		w = true
	elseif key == "s" then
		print(key)
		s = true
	elseif key == "a" then
		print(key)
		a = true
	elseif key == "d" then
		print(key)
		d = true
	elseif key == "q" and CD == false then
		print("q pressed")
		Dash(20, .35) -- insert your own values here, or have mine <3
	end
end)

-- now detect when the key is released

m.KeyUp:connect(function(key)
	if key == "w" then
		w = false
	elseif key == "s" then
		s = false
	elseif key == "a" then
		a = false
	elseif key == "d" then
		d = false
	end
end)
17 Likes

ummm, I do not see a dash effect on your final product video…

Question, how do body velocity works if they are created on the client? Would the server know that the player has a body velocity?

1 Like

Thank you! I was looking for something like this for a long time.

1 Like

Thats cool. Do you need help or something?

How would you make this server sided?

1 Like

You’re a life saver, thank you very much!

Do you know how to make one work also on mobile if not I can help you because some people might also want it on mobile. You can also just use user input to detect if the pressed WASD with input began