Change dash relative to camera (AlignPosition)

Hello! I’m currently making a mock dash system but despite years of scripting I still vaguely understand CFrames, Vectors, etc.

Right now, the mock-up dash system works fine but I was hoping to make it relative to the camera position, rather than the player position.

Here’s a snippet of the mock-up (assume direction is a Vector depending on move direction)

e.g., direction = Vector3.new(.5, 0, .5)

local function Dash(direction)
	local humanoid = character.Humanoid
	local rootPart = character.HumanoidRootPart
	local alignPos = Instance.new("AlignPosition", rootPart)
	alignPos.Attachment0 = rootPart.RootAttachment
	alignPos.Mode = Enum.PositionAlignmentMode.OneAttachment
	alignPos.MaxForce = 50000
	alignPos.Responsiveness = 100
	alignPos.Position = (rootPart.CFrame * CFrame.new(direction*20)).Position
	task.wait(.2)
	alignPos:Destroy()
end

I know there’s plenty of posts with solutions for other methods, but I’d like to stick with AlignPosition if possible.

Any help would be super appreciated!

If you want the direction to be relative to the camera you’d just do something like goalPosition = rootPart.Position + camera.CFrame.LookVector * distance

I’d still need to account for the direction also which is the part I’m failing to figure out. Doing that would simply always go forwards of the camera

I’m a bit confused now, can you show what your goal direction would look like?

Essentially, my current mock-up works great if I was shift-locked because the camera is always facing the same direction as the character therefore, I’m always dodging relative to the camera. I’m trying to get this to work regardless of the camera orientation

Ohh okay I think I get what you mean, so you want it to dash relative to the humanoid root part’s direction?

If so then the rootPart.CFrame * CFrame.new(direction * 20)).Position should work. It’s just that the forward direction is negative Z so direction would be something like Vector3(0, 0, -0.5)

Unless you mean in the direction they’re moving, in which case you’d do something like humanoidRootPart.Position + humanoid.MoveDirection.Unit --[[or humanoidRootPart.LookVector]] * 20.

I might be completely misunderstanding though.

2 Likes

Sorry if I wasn’t clear, it was the middle of the night for me.

Right now my dash is relative to the rootpart already. I’m trying to get to to be relative to the camera so dodging right would ALWAYS dodge right in the camera view. Look at the video to see what I mean as obviously it works shift-locked

If I am correctly assuming what you want, then what you are looking for is the RightVector, specifically the Camera’s RightVector. RightVector is the same thing as LookVector, but towards the right (and left with negative).

local function Dash(direction)
	local character = game.Players.LocalPlayer.Character
	local humanoid = character.Humanoid
	local rootPart = character.HumanoidRootPart
	local alignPos = Instance.new("AlignPosition")
	alignPos.Parent = rootPart
	alignPos.Attachment0 = rootPart.RootRigAttachment
	alignPos.Mode = Enum.PositionAlignmentMode.OneAttachment
	alignPos.MaxForce = 50000
	alignPos.Responsiveness = 100
	alignPos.Position = rootPart.Position + direction + Vector3.new(0, -1, 0) -- -1 to Y so I don't go flying
	task.wait(.2)
	alignPos:Destroy()
end

game:GetService("UserInputService").InputBegan:Connect(function(inputobject)
	if inputobject.KeyCode == Enum.KeyCode.Q then
		Dash(-game.Workspace.CurrentCamera.CFrame.RightVector*20) -- always dash left no matter the camera angle
	elseif inputobject.KeyCode == Enum.KeyCode.E then
		Dash(game.Workspace.CurrentCamera.CFrame.RightVector*20) -- always dash right no matter the camera angle
	end
end)

I hope this is what you are looking for, correct me if im wrong!

2 Likes

You’re a legend, so much thanks for the two of you for bettering my understanding on this type of stuff. It’s really not my speciality.

Thank you!

3 Likes

Further testing seems that this may not be the exact solution. It took me so long to realise but the orientation of my camera seems to play a large part in how far the character is dashing. This sometimes produces some really unnatural results; I’ve tried copying your exact code and had the same issue.

Here’s my original code

local function Dash()
	local humanoid = character.Humanoid
	local rootPart = character.HumanoidRootPart
	local alignPos = Instance.new("AlignPosition", rootPart)
	local multiplier
	local animation = Instance.new("Animation")
	local animTrack
	local duration
	local direction = Vector3.new(0, 0, 0)
	if userInputService:IsKeyDown("W") then
		direction += camera.CFrame.LookVector * data.abilityData.Dash.Distance
		animation.AnimationId = animations.ForwardDash.AnimationId
	end
	if userInputService:IsKeyDown("S") then
		direction -= camera.CFrame.LookVector * data.abilityData.Dash.Distance
		animation.AnimationId = animations.BackwardDash.AnimationId
	end
	if userInputService:IsKeyDown("D") then
		direction += camera.CFrame.RightVector * data.abilityData.Dash.Distance
		animation.AnimationId = animations.RightDash.AnimationId
	end
	if userInputService:IsKeyDown("A") then
		direction -= camera.CFrame.RightVector * data.abilityData.Dash.Distance
		animation.AnimationId = animations.LeftDash.AnimationId
	end
	if direction.X > 1 or direction.X < -1 then
		if direction.Z > 1 or direction.Z < -1 then
			direction = Vector3.new(direction.x/2, 0, direction.z/2)
		end
	end
	if direction ~= Vector3.new(0, 0, 0) then
		if userInputService.MouseBehavior ~= Enum.MouseBehavior.LockCenter then
			animation.AnimationId = animations.ForwardDash.AnimationId
		end
		animTrack = humanoid:LoadAnimation(animation)
		if humanoid.FloorMaterial == Enum.Material.Air then
			duration = data.abilityData.Dash.AirDuration
			multiplier = data.abilityData.Dash.AirMultiplier
		else
			duration = data.abilityData.Dash.GroundDuration
			multiplier = data.abilityData.Dash.GroundMultiplier
		end
		animTrack:Play()
		alignPos.Attachment0 = rootPart.RootAttachment
		alignPos.Mode = Enum.PositionAlignmentMode.OneAttachment
		alignPos.MaxForce = data.abilityData.Dash.MaxForce
		alignPos.Responsiveness = data.abilityData.Dash.Responsiveness
		alignPos.Position = rootPart.Position + Vector3.new(direction.X, 0, direction.Z) * multiplier
		task.wait(duration)
		alignPos:Destroy()
		task.wait(.1)
		debounces.dash = true
	else
		debounces.dash = true
	end
end

Now here’s a video of results:

EDIT: So, whenever the camera is facing down towards the player or upwards it’s manipulating the values a lot which you can’t simply clamp otherwise, you’d have even worse accuracy

why not just use the humanoid root part cframe instead of the camera

I’ve attempted using the rootpart for lookvector but still produces weird movement say you’re mid-turning direction.

Might just be time to ditch this concept for velocity and movedirection.

weird movement like how? like stiff? or moving in the wrong direction?

I think it’s possibly because you’d only want to take into account the X and Z axes (left/right and forward/backward) for your dashing, not the Y (upwards) axis, so direction would be something like (camera.CFrame.RightVector * Vector3.new(1, 0, 1)).Unit * 20

Multiplying a vector by another vector just multiplies each axis by its corresponding axis so that would negate the Y axis, then we would want to use its Unit property to get the same direction but limited/“extended” to a single stud, and then multiply again by 20 for the length of the dash.

3 Likes

Just adding .Unit made the entire thing work perfectly… Yeah CFrames and Vectors are easily my weakest point I hardly even understand what .Unit achieved…

Either way, you’ve again been a legend so, thank you!!

2 Likes