How can I get this camera affect?

How can I get the camera to be locked but allow for movement only when the player is stationary like this:

I’m not really sure how to explain it but I want the player to be able to look around their character when they are not moving but I also want the camera to be in the locked position (facing the back of the character) when they are moving.

Not sure how to go about this, any help appreciated!

4 Likes

While they’re moving, just lerp the HumanoidRootPart to face the direction the camera is also facing, it’s just that

2 Likes

you can detect it by using Humanoid.Running and make the camera lock everytime the player moves which is like this;

local plr = game.Players.LocalPlayers.Character
local hmn = plr:WaitForChild("Humanoid")
hmn.Running:Connect(function(s: number)
	if s > 0 then
		camera.CameraType = Enum.CameraType.Scriptable
		camera.CFrame = plr.Head.CFrame -- might want to change this
	else
		camera.CameraType = Enum.CameraType.Custom
	end
end)
2 Likes

What you could do is have some sort of body mover such as a BodyGyro (or one of those newer Constraint instances) and if the player is moving, you will set the target CFrame of the body mover to the camera’s Y rotation and parent it to the HumanoidRootPart

2 Likes

use Humanoid.MoveDirection (which is a vector3 pointing to where the player wants to go) to detect if the player is moving

you could use Character:PivotTo() to change the orientation, but keep the position the same

local Position = Character:GetPivot().Position
Character:PivotTo(CFrame.new(Position, Position + Humanoid.MoveDirection))

you can hook this up to a Humanoid:GetPropertyChangedSignal(“MoveDirection”) and check if the magnitude is greater than an epsilon (0.01)

2 Likes

It seems to be choppy and jittery, the character also doesn’t face forward when walking backwards, left or right.

2 Likes

while spoon-feeding code is not the best thing to do as long as you ask questions and understand this, then you should be good:

local RunService = game:GetService('RunService')
local UserInputService = game:GetService('UserInputService')
local character = script.Parent
local humanoid = character.Humanoid
local camera = workspace.CurrentCamera

local CAMERA_OFFSET = Vector3.new(1.2,1.2,0)
local cameraConnection
local running = false
	
local function onRunning(speed: number)
	if speed > 0 and running == false then
		running = true
		UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
		pcall(function()
			cameraConnection:Disconnect()	
		end)
		cameraConnection = RunService.RenderStepped:Connect(function()
			local characterPosition = character:GetPivot().Position
			local lookDirection = camera.CFrame.LookVector
			character:PivotTo(CFrame.new(characterPosition, characterPosition + Vector3.new(lookDirection.X, 0, lookDirection.Z)))
		end)
	elseif speed == 0 then
		running = false
		UserInputService.MouseBehavior = Enum.MouseBehavior.Default
		pcall(function()
			cameraConnection:Disconnect()	
		end)
	end
end

humanoid.CameraOffset = CAMERA_OFFSET
humanoid.Running:Connect(onRunning)
1 Like

Walking backwards is quite choppy/jittery, I think this is because its manually setting the CFrame of the character every frame, isn’t there a more passive way of doing it? Like how does Roblox do it with the shift lock setting?

1 Like

I tried this and it works, my only issue is that when setting the camera offset for the over the shoulder view and trying to move the character in a new direction from being stationary, it jumps/jitters:

How could I get it to be smooth?

1 Like

Idk what was wrong with the code, but I simplified it and put it into StarterCharacterScripts and I think it is how you want it now:

local RunService = game:GetService('RunService')
local UserInputService = game:GetService('UserInputService')
local character = script.Parent
local humanoid = character.Humanoid
local camera = workspace.CurrentCamera

local CAMERA_OFFSET = Vector3.new(1.2,1.2,0)
local cameraConnection
local running = false
	
local function onRunning(speed: number)
	if speed > 0 and running == false then
		running = true
		pcall(function()
			cameraConnection:Disconnect()	
		end)
		cameraConnection = RunService.Heartbeat:Connect(function()
			character.PrimaryPart.CFrame = CFrame.new(character.PrimaryPart.Position, character.PrimaryPart.Position + Vector3.new(camera.CFrame.LookVector.X, 0, camera.CFrame.LookVector.Z))
			UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
		end)
	elseif speed == 0 and running == true then
		running = false
		UserInputService.MouseBehavior = Enum.MouseBehavior.Default
		pcall(function()
			cameraConnection:Disconnect()	
		end)
	end
end

humanoid.AutoRotate = false
humanoid.CameraOffset = CAMERA_OFFSET
humanoid.Running:Connect(onRunning)
1 Like

Actually nvm, I realized that I didn’t actually understand what you were going for, so I double checked the video, and I reworked the code and this is the result:

1 Like