Hi! I made this custom camera script for my RTS-Style game, I tried mimicking the camera from this video as much as possible (I am still working on the camera rotation though).
local UserInputService = game:GetService("UserInputService")
local ContextActionService = game:GetService("ContextActionService")
local Player = game.Players.LocalPlayer
local cam = game.Workspace.CurrentCamera
local mouse = Player:GetMouse()
local scrollspeed = 1
local rotateRatio = 20
local pressed = UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton2)
game.Workspace.Camera.FieldOfView = 70
--Zoom
local max = 80
local min = 7
local focusLevel = 20
-- place the camera high in the air, looking down at the ground
local startingPos = Vector3.new(0, 60, 50)
local angle = 60
local downwardLookAngle = CFrame.Angles(-math.rad(angle), 0, 0)
cam.CFrame = CFrame.new(startingPos) * downwardLookAngle
-- create a function that moves the camera around
local moveDir = Vector3.new(0, 0, 0) -- we'll use this vector to control our movement
local moveSpeed = 0.5
spawn(function()
while true do
-- animate the camera movement
local c = game.Workspace.CurrentCamera.CFrame
game.Workspace.CurrentCamera.CFrame = CFrame.new(c.Position) * CFrame.new(moveDir) * downwardLookAngle
wait(0.01)
end
end)
-- create a function to handle keyboard inputs
local function onKeyPress(actionName, userInputState, inputObject)
-- when a key is pressed, modify our moveDir vector so our camera moves
-- W key input
if actionName == "moveCameraForward" then
if userInputState == Enum.UserInputState.Begin then
moveDir = Vector3.new(moveDir.X, moveDir.Y, -moveSpeed)
elseif userInputState == Enum.UserInputState.End then
moveDir = Vector3.new(moveDir.X, moveDir.Y, 0)
end
-- A key input
elseif actionName == "moveCameraLeft" then
if userInputState == Enum.UserInputState.Begin then
moveDir = Vector3.new(-moveSpeed, moveDir.Y, moveDir.Z)
elseif userInputState == Enum.UserInputState.End then
moveDir = Vector3.new(0, moveDir.Y, moveDir.Z)
end
-- S key input
elseif actionName == "moveCameraBackward" then
if userInputState == Enum.UserInputState.Begin then
moveDir = Vector3.new(moveDir.X, moveDir.Y, moveSpeed)
elseif userInputState == Enum.UserInputState.End then
moveDir = Vector3.new(moveDir.X, moveDir.Y, 0)
end
-- D key input
elseif actionName == "moveCameraRight" then
if userInputState == Enum.UserInputState.Begin then
moveDir = Vector3.new(moveSpeed, moveDir.Y, moveDir.Z)
elseif userInputState == Enum.UserInputState.End then
moveDir = Vector3.new(0, moveDir.Y, moveDir.Z)
end
end
end
-- Zoom in and zoom out
mouse.WheelForward:Connect(function() -- Zoom in
if game.Workspace.CurrentCamera.CFrame.Y >= min or game.Workspace.CurrentCamera.CFrame.Y == min then
game.Workspace.CurrentCamera.CFrame = CFrame.new(game.Workspace.CurrentCamera.CFrame.Position) * CFrame.new(0,-scrollspeed,0) * downwardLookAngle
else
-- Do nothing
end
scrollspeed = game.Workspace.CurrentCamera.CFrame.Y/10
if game.Workspace.CurrentCamera.CFrame.Y <= focusLevel and angle >= 15 then
--angle = angle - 5
downwardLookAngle = CFrame.Angles(-math.rad(angle), 0, 0)
else
--Do nothing again
end
end)
mouse.WheelBackward:Connect(function() -- Zoom out
if game.Workspace.CurrentCamera.CFrame.Y <= max or game.Workspace.CurrentCamera.CFrame.Y == max then
game.Workspace.CurrentCamera.CFrame = CFrame.new(game.Workspace.CurrentCamera.CFrame.Position) * CFrame.new(0,scrollspeed,0) * downwardLookAngle
else
-- Do nothing
end
scrollspeed = game.Workspace.CurrentCamera.CFrame.Y/10
if game.Workspace.CurrentCamera.CFrame.Y <= focusLevel and angle <= 60 then
--angle = angle + 5
downwardLookAngle = CFrame.Angles(-math.rad(angle), 0, 0)
else
--Do nothing again
end
end)
UserInputService.TouchPinch:Connect(function(touchPositions, scale, velocity, state, gameProcessedEvent)
if game.Workspace.CurrentCamera.CFrame.Y <= max and game.Workspace.CurrentCamera.CFrame.Y >= min then
game.Workspace.CurrentCamera.CFrame = CFrame.new(game.Workspace.CurrentCamera.CFrame.Position) * CFrame.new(0,scale,0) * downwardLookAngle
else
-- Do nothing
end
end)
-- listen for keyboard input that moves the camera
game.ContextActionService:BindAction("moveCameraForward", onKeyPress, false, Enum.KeyCode.W)
game.ContextActionService:BindAction("moveCameraLeft", onKeyPress, false, Enum.KeyCode.A)
game.ContextActionService:BindAction("moveCameraBackward", onKeyPress, false, Enum.KeyCode.S)
game.ContextActionService:BindAction("moveCameraRight", onKeyPress, false, Enum.KeyCode.D)
It’s an incredibly messy script since i am quite new to scripting but this is the most important part for my question:
-- Zoom in and zoom out
mouse.WheelForward:Connect(function() -- Zoom in
if game.Workspace.CurrentCamera.CFrame.Y >= min or game.Workspace.CurrentCamera.CFrame.Y == min then
game.Workspace.CurrentCamera.CFrame = CFrame.new(game.Workspace.CurrentCamera.CFrame.Position) * CFrame.new(0,-scrollspeed,0) * downwardLookAngle
else
-- Do nothing
end
scrollspeed = game.Workspace.CurrentCamera.CFrame.Y/10
if game.Workspace.CurrentCamera.CFrame.Y <= focusLevel and angle >= 15 then
--angle = angle - 5
downwardLookAngle = CFrame.Angles(-math.rad(angle), 0, 0)
else
--Do nothing again
end
end)
mouse.WheelBackward:Connect(function() -- Zoom out
if game.Workspace.CurrentCamera.CFrame.Y <= max or game.Workspace.CurrentCamera.CFrame.Y == max then
game.Workspace.CurrentCamera.CFrame = CFrame.new(game.Workspace.CurrentCamera.CFrame.Position) * CFrame.new(0,scrollspeed,0) * downwardLookAngle
else
-- Do nothing
end
scrollspeed = game.Workspace.CurrentCamera.CFrame.Y/10
if game.Workspace.CurrentCamera.CFrame.Y <= focusLevel and angle <= 60 then
--angle = angle + 5
downwardLookAngle = CFrame.Angles(-math.rad(angle), 0, 0)
else
--Do nothing again
end
end)
As you can see I rotate the camera forwards when the camera is certain distance from the ground, however, because I change the angle by 5 every time you move the mouseweel, this rotation isn’t smooth at all.
I have tried using Tweenservice, but you can only tween a instance’s properties and not a value. I have also tried using the :Lerp function, everytime you used the scroll wheel I would lerp the angle
value to angle + 5
. this didn’t work because if you scrolled fast enough you could be out of the focuslevel
before the camera returned to normal.
If anyone knows how to make this rotation more smooth please let me know, thanks!