Dash distance affected by camera

I am coding a game with a dash system bound to Q and I have run into the issue where if I use shiftlock, angle my camera above my character or look straight up and move forward or backwards while dashing, the dash distance is greatly reduced from what it should be. This issue is not present in sideways dashing and I am greatly confused on what is causing it. The code is below:

local uis = game:GetService("UserInputService")
local cas = game:GetService("ContextActionService")
local plrs = game:GetService("Players")

local plr = plrs.LocalPlayer
local char = plr.Character or plr.CharacterAdded:wait()
local hrp = char:WaitForChild("HumanoidRootPart")
local hume = char:WaitForChild("Humanoid")
local sf = char:WaitForChild("Stats")

local camMod = require(plr.PlayerScripts:WaitForChild("PlayerModule"):WaitForChild("CameraModule"))

local tEnabled = uis.TouchEnabled
local shiftlockCont, shiftLockEv, shiftlock

local cam = workspace.CurrentCamera

local server = script:WaitForChild("Server")
local stext = script:WaitForChild("Subtext")

local rs = game:GetService("ReplicatedStorage")
local remotes = rs:WaitForChild("Remotes")
local sound = remotes:WaitForChild("Sound")

local distance = 15

local OnCD = false
local ccd = 0
local cd = 2

if not tEnabled then
	shiftlockCont = camMod.activeMouseLockController
	shiftLockEv = shiftlockCont:GetBindableToggleEvent()
	shiftLockEv:Connect(function() shiftlock = shiftlockCont:GetIsMouseLocked() end)
end

local function cooldown() OnCD = true; ccd = cd 
	spawn(function()
		while wait(0.1) do 
			if not char:FindFirstChild("Stopped") then 
				ccd = math.max(ccd - .1, 0) 
				if ccd == 0 then OnCD = false; break end 
			end 
		end
	end)
end

local function dash(root, movedir)
	sound:FireServer("all", "rbxassetid://4255432837", {vol=1})
	local bp = Instance.new("BodyPosition")
	bp.MaxForce = Vector3.new(1000000,0,1000000)
	bp.P = 100000; bp.D = 2000
	local toPos = (root.CFrame*CFrame.new(0,0,-distance)).Position
	if movedir.magnitude > 0 then local moveToSpace = cam.CFrame:VectorToObjectSpace(movedir).unit*Vector3.new(1,0,1)
		toPos = (hrp.CFrame*(CFrame.new(moveToSpace*distance))).Position 
	end
	if not shiftlock or tEnabled then toPos = (root.CFrame*CFrame.new(0,0,-distance)).Position end
	bp.Position = toPos; bp.Parent = root
	game.Debris:AddItem(bp, 0.2)
end

local function dashCheckPC(input,isTyping)
	if hume.Health > 0 then
		if isTyping then return end
		if input.KeyCode == Enum.KeyCode.Q then
			if not OnCD and sf.Disable.Value <= 0 then cooldown(); dash(hrp, hume.MoveDirection)
			elseif OnCD then stext:FireServer(plr, [[Dash is currently on cooldown! (<font color="rgb(255,0,0)">]]..math.abs(ccd)..[[</font>)]])
			elseif not OnCD and sf.Disable.Value > 0 then stext:FireServer(plr, [[You cannot use dash right now! (<font color="rgb(255,0,0)">Disabled</font>)]]) end
		end
	end
end

local function dashCheckMobile(actionName,userInputState,inputObject)
	if hume.Health > 0 then
		if userInputState == Enum.UserInputState.Begin then
			if not OnCD and sf.Disable.Value <= 0 then cooldown(); dash(hrp, hume.MoveDirection)
			elseif OnCD then stext:FireServer(plr, [[Dash is currently on cooldown! (<font color="rgb(255,0,0)">]]..math.abs(ccd)..[[</font>)]])
			elseif not OnCD and sf.Disable.Value > 0 then stext:FireServer(plr, [[You cannot use dash right now! (<font color="rgb(255,0,0)">Disabled</font>)]]) end
		end
	end
end

--Computer dash button
uis.InputBegan:Connect(dashCheckPC)

--Mobile dash button
cas:BindAction("DashButton", dashCheckMobile, true)
cas:SetTitle("DashButton", "Dash")

If anyone has any ideas, please let me know.

EDIT: Additionally, if the camera is facing directly forward, the dash distance is doubled for forwards and backwards.

2 Likes

This happens because when you are looking directly up or down, the .Unit will be something like Vector3.new(0.001, 0.998, -0.001) or something. Your script currently removes the Y axis by multiplying by Vector3.new(1, 0, 1) but it does not recalculate the magnitude. To fix this, just put another .Unit after you cancel out the Y axis so instead of getting a vector of (0.001, 0, -0.001), you will get a vector of (0.7071, 0, -0.7071).

I believe that this part of your code controls move direction, so adding the .Unit like I did here will fix it.

local moveToSpace = cam.CFrame:VectorToObjectSpace(movedir).unit * Vector3.new(1,0,1)
toPos = (hrp.CFrame * (CFrame.new(moveToSpace.Unit * distance))).Position -- Changed moveToSpace to moveToSpace.Unit
6 Likes