I am trying to make a custom camera for my custom character (import to note that it has no humanoid) that behaves similar to shift lock. My goal is to have a centered camera that moves as you move your mouse but without moving the character. The key difference is that shift lock rotates your character with the camera, whereas I do not want that to occur. What are some approaches I could take to accomplish this? Thanks!
You could try scripting a local script like:
--Local Script
game:GetService("RunService").RenderStepped:Connect(function()
local camera = workspace.CurrentCamera
camera.CFrame = CharacterMainPart.CFrame * CFrame.new(0,2,-2)
--With "CharacterMainPart" I mean the PrimaryPart of your Character
--or the most important part
end)
I appreciate the code snippet, but that doesn’t address the part that I don’t know how to approach, which is making it so the camera rotates with the mouse. When the mouse moves, so should the camera like it does when using shift lock. Do you know how I would accomplish that?
You can accomplish this by using UserInputService:GetMouseDelta().
I created a short script that works in StarterCharacterScripts as an example:
local runService = game:GetService("RunService")
local userInputService = game:GetService("UserInputService")
local char = game.Players.LocalPlayer.Character
local camera = workspace.CurrentCamera
camera.CameraType = Enum.CameraType.Scriptable
userInputService.MouseBehavior = Enum.MouseBehavior.LockCenter -- The behavior must be LockCenter for this to work
local defaultCamOffset = Vector3.new(3.25,2.25,7.5)
local angleX = 0
local angleY = 0
runService.RenderStepped:Connect(function()
local mousePosChange = userInputService:GetMouseDelta() -- How much the mouse's position has changed since the previous frame
angleX = angleX - mousePosChange.X -- Update the X angle by subtracting the mouse's change in X
angleY = math.clamp(angleY - mousePosChange.Y, -75, 75) -- Update the Y angle by subtracting the mouse's change in Y. Clamp it so it doesn't go too high or low
local cameraCFrame = CFrame.new(char.HumanoidRootPart.Position) * CFrame.Angles(0, math.rad(angleX), 0) * CFrame.Angles(math.rad(angleY), 0, 0) -- Apply the camera angles
local cameraFocus = cameraCFrame:PointToWorldSpace(Vector3.new(defaultCamOffset.X, defaultCamOffset.Y, -9999)) -- Get the position the camera should be looking at
camera.CFrame = CFrame.new(cameraCFrame:PointToWorldSpace(defaultCamOffset), cameraFocus) -- Apply the offset and make the camera look at the focus
end)
Let me know if you have any issues with it, or need any further clarification.
So I did some messing around with this, and rewrote it in a way that’s more familiar to myself, but it doesn’t seem to be fully working, and I can’t determine why that is. I’m not the best with CFrame math, so I can’t quite follow why the operations in cameraCFrame
and cameraFocus
are being done. Although the camera locks into place as an offset, mouse movement has no impact on the rotation of the camera. Although it’s functionally the same, here’s what I’m currently working with. Do you know how it would be changed to allow for camera rotation relative to the mouse’s delta?
-- Services
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
-- Variables
local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local angleX,angleY = 0,0
-- Configuration
local defaultCamOffset = Vector3.new(3.25,2.25,7.5)
local clampRange = 75
workspace.CurrentCamera.CameraType = Enum.CameraType.Scriptable
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
RunService.RenderStepped:Connect(function()
local mousePosChange = UserInputService:GetMouseDelta() -- Mouse offset
angleX -= mousePosChange.X -- Subtract mouse's change in X
angleY = math.clamp(angleY-mousePosChange.Y,-clampRange,clampRange) -- Subtract mouse's change in Y
local cameraCFrame = CFrame.new(character.HumanoidRootPart.Position) * CFrame.Angles(0,math.rad(angleX),0) * CFrame.Angles(math.rad(angleY),0,0) -- Apply the camera angles
local cameraFocus = cameraCFrame:PointToWorldSpace(Vector3.new(defaultCamOffset.X,defaultCamOffset.Y,-9999)) -- Get the position the camera should be looking at
workspace.CurrentCamera.CFrame = CFrame.new(cameraCFrame:PointToWorldSpace(defaultCamOffset),cameraFocus) -- Apply offset and LookAt
end)
I put your code in a LocalScript within StarterCharacterScripts on an empty place and it seems to work fine. The only issue I noticed is that sometimes the mouse changes behavior from lock center, such as when the player tabs out, so you should reset it whenever that occurs.
Is there something else in your game that is affecting the camera or the mouse in some way?
Ah, it seems that things just weren’t initializing fast enough. I added a wait to the top, and it’s functional now. Thank you for your help! It works exactly as I was trying to accomplish!
For anyone’s future reference, my issue was caused by MouseBehavior
changing itself. this was accounted for via the below code.
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
UserInputService:GetPropertyChangedSignal("MouseBehavior"):Connect(function()
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
end)
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.