Cannot move Character when using a Custom Camera

I’ve been working on a new game recently, however one issue has barred my progress. I’ve made a script that acts as a custom camera, but I cannot move my character while it’s active. Disabling the script, even while running the game, lets me move my character. The script is below.

local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:wait()
local Camera = game.Workspace.CurrentCamera

Camera.CameraType = Enum.CameraType.Scriptable

game:GetService("RunService").RenderStepped:connect(function()
	if game.Workspace:FindFirstChild("Map") then
		if Character and Character.Parent ~= nil then
			Camera.CFrame = CFrame.new(Character.HumanoidRootPart.Position + Vector3.new(0,25,0), Character.HumanoidRootPart.Position)
		end
	end
end)
1 Like

Because the movement of the character is based off of where the player is looking with their camera, your script won’t work because it’s directly overhead.

To fix this just add a small offset on the X axis:

local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:wait()
local Camera = game.Workspace.CurrentCamera

Camera.CameraType = Enum.CameraType.Scriptable

game:GetService("RunService").RenderStepped:Connect(function()
	if game.Workspace:FindFirstChild("Map") then
		if Player.Character and Player.Character.Parent then
			Camera.CFrame = CFrame.new(Player.Character.HumanoidRootPart.Position + Vector3.new(-0.1,25,0), Player.Character.HumanoidRootPart.Position)
		end
	end
end)
7 Likes

You can also use a tiny angular offset, such as changing the important line of this script to

Camera.CFrame = CFrame.fromOrientation(-0.49*math.pi,-0.5*math.pi,0) + Character.HumanoidRootPart.Position + Vector3.new(0,25,0)

With tiny values, the difference will negligible. This does keep the camera directly over the character though, so if it’s of critical importance to be seeing the character exactly top down, this will do it. If you use a tiny offset and the 2-argument CFrame constructor, you still have a slight tilt, but you also have the camera looking at the character from ever so slightly behind. Exaggerate the corrections and it will become clear.

In general, I don’t recommend people use the CFrame.new(Vector3, Vector3) constructor when they know the look direction (second argument) is going to be near to the +/- Y axis. You can get some puzzling bugs from the singularity here. If you construct your camera CFrame with fromOrientation, fromAxisAngle, or any of the other fully-qualified angle-based constructors, you always know exactly which way your camera will end up on all platforms. For example, with fromOrientation, the second argument (Y rotation) can be used to set which compass direction is up on your screen, without having to do any trig or worry about numerical instabilities.

If you absolutely must have the camera pointed exactly down, that’s possible too, but not without forking the playerscripts to override the cameraRelative Boolean passed to Humanoid:Move().

2 Likes

Thank you, this fixed it!
And thanks for the detailed explanation @AllYourBlox