Toggle Face-Mouse Direction Script + Make Player Face The Direction They're Moving?

Currently I’m trying to make a dodge roll for my game, and I want to make it look like this:
(AutoRotate was turned on to demonstrate this better)

But I ran into several issues when trying to replicate that without AutoRotate turned on.


I have tried to figure this out on my own, but it seems to be the script that makes the player face the mouse being the problem, because even with an if statement to turn off letting the player face the mouse, the player faces the wrong direction.

So how can I make this (the script that makes the player face the mouse) be toggled and allow the player to face the direction they’re moving in?

RS.RenderStepped:Connect(function()
	local RootPos, MousePos = HRP.Position, Mouse.Hit.Position
	HRP.CFrame = CFrame.new(RootPos, Vector3.new(MousePos.X, RootPos.Y, MousePos.Z))
end)

I think the solution is figuring out what direction they are moving when they press the roll button, and then setting the cframe to look the direction they are rolling? I am not sure how you would get the direction they are rolling though… if your game is 100% pc and they need to use wasd to move, you could check inputs ig? how are you making the character roll in the direction they are moving? that could be used to set the lookdirection, and one possible solution is to keep track of last frames position and get the difference between the vectors and set lookdirection as current position + -difference.

1 Like

This problem is similar to this:

You’d preferably make the player face the mouse, not the walkdirection. To get the rotation, we need to calculate the angle of alpha. Assuming the camera does not change rotation, this is how:

  • Get the character’s location on the screen [cPos : Vector2].
  • Get the mouse’s location on the screen [mPos : Vector2].
  • Get the vector from cPos to mPos [v = mPos-cPos]
  • Get the angle between the screen’s upvector (0,1) and v.
    how? Using math.atan2 of v.X and -v.Y (negative v.Y because v.Y goes from top to bottom of screen). We also apply a 90deg rotation
  • Apply the rotation to the characters’s y axis.

75618e92bbd4d9c36169e10e45508321

local Players = game:GetService("Players")
local GuiService = game:GetService("GuiService")
local RunService = game:GetService("RunService")

local player = Players.LocalPlayer
local mouse = player:GetMouse()
local camera = workspace.CurrentCamera
local guiInset = GuiService:GetGuiInset()

local function setupTopDownCamera()
		local humanoidRootPart = player.Character:FindFirstChild("HumanoidRootPart")
		camera.CameraType = Enum.CameraType.Scriptable
		camera.CFrame = CFrame.new(humanoidRootPart.Position + Vector3.new(0, 50, 0), humanoidRootPart.Position)
end

local function faceMouse(character)
	local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
	-- Get character position on screen
	local camera = workspace.CurrentCamera
	local cPos = camera:WorldToScreenPoint(humanoidRootPart.Position)
	local mPos = Vector2.new(mouse.X - guiInset.X, mouse.Y - guiInset.Y)

	-- Calculate vector from character to mouse
	local v = mPos - Vector2.new(cPos.X, cPos.Y)

	-- Calculate angle between up vector (0, 1) and v
	local angle = math.atan2(v.X, -v.Y) + math.pi / 2-- atan2 returns the angle in radians. Plus math.pi/2 because 90deg offset

	-- Apply rotation to character's Y axis
	local newCFrame = CFrame.new(humanoidRootPart.Position) * CFrame.Angles(0, -angle, 0)
	humanoidRootPart.CFrame = newCFrame
end

-- Connect to RenderStepped to update the character's facing direction
RunService.RenderStepped:Connect(function()
	local character = player.Character
	if character and character:FindFirstChild("HumanoidRootPart") then
		faceMouse(character)
		setupTopDownCamera()
	end
end)

2 Likes

Just a simple change is needed to your script

local lastLook = Vector3.zAxis
RS.RenderStepped:Connect(function()
    local dir = HRP.AssemblyLinearVelocity
    if dir.Magnitude > 0 then
        dir = dir.Unit
        lastLook = dir
    else
        dir = lastLook
    end
	local RootPos = HRP.Position

	HRP.CFrame = CFrame.LookAlong(RootPos, dir, Vector3.yAxis)
end)
1 Like

That incurs errors at HRP.CFrame = CFrame.LookAlong(RootPos, dir, Vector3.yAxis)

2 Likes

The same issue still remains even after using your code

1 Like

Whats the error? I dont see anything that could be wrong

1 Like

It’s nil, so it doesn’t actually do anything. Did you test the code beforehand?

1 Like

I thought youd understand u needed to declare the HRP. You should try to read the code and learn from it rather than blindly copying

local
local
local
local
RS game "Runservice")
player game. Players. Local Player .Character
HRP player. HumanoidRootPart
lastL00k Vector3.ZAxis
RS. Renderstepped : connect( function( )
local dir =
HRP.AssemblyLinearVeIocity
if dir . Magnitude > e then
dir
dir. Unit
lastLook
= dir
else
dir tastLook
end
local Rootpos •
HRP.Position
CFrame. LookAlong( Root Pos ,
HRP.CFrame
dir.
vector3 . yAxis )

try this do the locals in the renderstped

put line four after line 7 and put line 2 also after line 7

Your solution might be interpolation (Springs work wonders) instead of using AutoRotation.
Considering you need a one size catches all behavior, I believe that’s one of the better options you could aim for to keep transitioning back from a dodge-roll seamless.

1 Like

I’m sorry but can you please elaborate and provide some resources about the specific interpolation I need?

Edit: I figured it out.