I have a system for building that requires I have the camera overhead of the in game building area. I can use right click and drag to rotate the camera, but as I use the A,W,D,S keys , can’t find any examples on how to make sure pressing w then keeps the camera going “forward” or “Up” in relation to the top of the camera, as its looking straight down at times 60 degrees. I think I need to somehow follow the LookVector of the camera, but can someone give me a quick tip on this?
You need to first disable the default camera script and set the camera type to Scriptable. Then you can define an offset height from the ground. You can do a RayCast from the camera position each time its updated to get the height of the ground beneath the camera. Then you can offset the camera from the ground to the desired height.
Your camera lookVector can be Vector3.fromNormalId(Enum.NormalId.Bottom)
Simply add the lookVector to the position component for your look component of the CFrame to get a CFrame with that lookVector: CFrame.new(pos, pos+lookVector)
Finally for your dragging feature you can simply set your camera CFrame to offset up from the mouse position while the player holds their mouse down.
Oh thanks, this sounds good. I’m going to try that now. Thanks.
By the way I have most of it already built… dragging etc… including all the building features… I just can’t seem to get this camera to work well, and I’ve left it for last.
This is what I’m currently doing…
–[[
https://stackoverflow.com/questions/54013176/how-do-you-go-about-making-an-rts-camera-city-builder-camera-in-roblox-studio
]]
local UT2 = require(game.ReplicatedStorage:WaitForChild(“UTILITY_CLASS”)).new()
local cam = game.Workspace.CurrentCamera
– place the camera high in the air, looking down at the ground
local startingPos = Vector3.new(0, 30, 0)
local downwardLookAngle = CFrame.Angles(-math.rad(60), 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
local Zrot = 0
local start_click_time = nil
local end_click_time = nil
spawn(function()
while true and script.UnBind.Value==false 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
game.ContextActionService:UnbindAction(“MouseMovement”)
game.ContextActionService:UnbindAction(“MouseRightClick”)
game.ContextActionService:UnbindAction(“mouseWheel”)
game.ContextActionService:UnbindAction(“moveCameraForward”)
game.ContextActionService:UnbindAction(“moveCameraLeft”)
game.ContextActionService:UnbindAction(“moveCameraBackward”)
game.ContextActionService:UnbindAction(“moveCameraRight”)
end)
local delta = nil
local blank = Vector3.new()
local rightclicked=false
local UserInputService = game:GetService(“UserInputService”)
– 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
elseif actionName =="MouseMovement" then
delta = inputObject.Delta
if rightclicked then
--print(delta)
if delta.X>0 then
Zrot = Zrot + 1
elseif delta.X<0 then
Zrot = Zrot - 1
end
if Zrot<0 then
Zrot = 350
end
if Zrot>360 then
Zrot = 0
end
downwardLookAngle = CFrame.Angles(-math.rad(90), 0, math.rad(Zrot))
end
elseif actionName =="MouseRightClick" then
if userInputState == Enum.UserInputState.Begin then
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCurrentPosition
rightclicked = true
start_click_time = UT2:gettime()
while (UT2:gettime() - start_click_time)<=.4 and rightclicked==true do
wait(.1)
end_click_time = (UT2:gettime() - start_click_time)
end
elseif userInputState == Enum.UserInputState.End or userInputState == Enum.UserInputState.Cancel then
UserInputService.MouseBehavior = Enum.MouseBehavior.Default
rightclicked = false
if end_click_time<=.3 then
local BUILDING_MOD = require(game.ReplicatedStorage.GUI_Building_Mod).new()
BUILDING_MOD:clearAllSelections(game.Players.LocalPlayer)
end
end
elseif actionName =="mouseWheel" then
local dir = 0
if inputObject.Position.Z>0 then
dir = -1
else
dir = 1
end
if userInputState == Enum.UserInputState.Change then
moveDir = Vector3.new(moveDir.X, (moveSpeed)*dir, moveDir.Z)
wait(1)
moveDir = Vector3.new(moveDir.X, 0, moveDir.Z)
else
moveDir = Vector3.new(moveDir.X, 0, moveDir.Z)
end
elseif actionName=="blah" then
end
end
– listen for keyboard input that moves the camera
game.ContextActionService:BindAction(“MouseMovement”,onKeyPress,false,Enum.UserInputType.MouseMovement)
game.ContextActionService:BindAction(“MouseRightClick”, onKeyPress,false,Enum.UserInputType.MouseButton2)
game.ContextActionService:BindAction(“mouseWheel”, onKeyPress,false,Enum.UserInputType.MouseWheel )
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)
@Hexcede Okay i solved the problem using the following function I found in a free model script for an RTS_Camerea that takes in account all possible directions to move provided by input, and then provides a directional vector for movement for the camera. I’ve seen similar scripts in the past but couldn’t find them.
function getMovement()
local look = CFrame.Angles(0, math.rad(rotation), 0)
local forwardUnit = (look.lookVector * Vector3.new(1, 0, 1)).unit
local strafeUnit = ((look * CFrame.Angles(0, math.rad(90), 0)).lookVector * Vector3.new(1, 0, 1)).unit
local forward = (input.forward and 1 or 0) - (input.backwards and 1 or 0)
local strafe = (input.left and 1 or 0) - (input.right and 1 or 0)
local mv = (forward * forwardUnit + strafe * strafeUnit)
if math.abs(mv.X) + math.abs(mv.Y) + math.abs(mv.Z) > 0 then moving = true mv = mv.unit else moving = false end
return mv
end