Hello:
I am currently in the process of developing a game that emulates the legacy follower camera that was present in versions of Roblox around 2007. Unfortunately, I am not very experienced with camera manipulation, particularly the mathematical operations involved therein, so the script I have created does not presently work as intended. The current follower camera (that is, when workspace.CurrentCamera.CameraType is set to Enum.CameraType.Follow) is not a usable alternative as there is a noticeable delay in automatic camera rotation after the right mouse button is released and the zooming behavior of the current follower camera is markedly different from that in 2007.
The following shows the intended behavior:
The following shows the actual behavior:
As shown, the height of the camera in the second video changes at an exponential rate when moving in a constant direction and the zooming behavior has noticeable flaws. Neither of these are intended, as demonstrated by their absence in the first video.
The script that causes the actual behavior, as shown in the second video, is as follows:
local camera = workspace.CurrentCamera
camera.CameraType = Enum.CameraType.Scriptable
local character = player.Character
local characterHead = character:WaitForChild("Head")
player.CharacterAdded:Connect(function(newCharacter)
character = newCharacter
characterHead = newCharacter:WaitForChild("Head")
end)
local cameraDistance = 10 --The distance of the camera from the character's head
local currentZoom = 2 --The number of times the mouse wheel must be scrolled backward in order to achieve the desired zoom
function updateStep(direction)
if characterHead then
currentZoom = math.clamp(math.round(currentZoom - direction), 0, 15)
local cameraPosY = 3^(currentZoom - 3)
cameraDistance = ((currentZoom^2) + (cameraPosY^2))^(1/2)
return characterHead.CFrame:ToWorldSpace(CFrame.new(currentZoom, cameraPosY, 0)).Position
end
end
userInputService.InputChanged:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseWheel then
camera.CFrame = CFrame.new(updateStep(input.Position.Z))
end
end)
local lastHeadPosition = Vector3.new() --The world position of the character's head as of the previous heartbeat
runService:BindToRenderStep("CameraConnection", Enum.RenderPriority.Camera.Value, function()
if character and characterHead then
local cameraFinalCFrame = CFrame.lookAt(camera.CFrame.Position - Vector3.new(0, lastHeadPosition.Y - characterHead.Position.Y, 0) --[[+ (characterHead.Position - lastPosition)]], characterHead.Position, Vector3.new(0, 1, 0))
local cameraOriginalCFrame = camera.CFrame
local cameraOrientation = {cameraFinalCFrame:ToEulerAnglesXYZ()}
local originalCameraOrientation = {cameraOriginalCFrame:ToOrientation()}
if not userInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton2) then
--cameraFinalCFrame = CFrame.new(cameraFinalCFrame.Position) * CFrame.Angles(--[[originalCameraOrientation[1]] 0, cameraOrientation[2], originalCameraOrientation[3])
end
local distanceFromHead = (camera.CFrame.Position - characterHead.Position).Magnitude
--if distanceFromHead > cameraDistance then
cameraFinalCFrame = cameraFinalCFrame:ToWorldSpace(CFrame.new(0, 0, cameraDistance - distanceFromHead))
--end
camera.CFrame = cameraFinalCFrame
lastHeadPosition = characterHead.Position
end
end)
To clarify, I understand what is causing the camera to behave in the manner shown, but I do not know how to correct that behavior.
One similar topic was found on the Developer Forum, but no solution is present.
Any help achieving the desired behavior will be greatly appreciated!