For my game, I'm trying to force a shift lock that controls the camera but also only makes the character look at the camera center when right-click is down. How would I do this? I have tried this but this just puts the cursor at the center and makes the Character face 1 particular direction
local players = game.Players.LocalPlayer local Mouse = players:GetMouse() local UserInputService = game:GetService("UserInputService") local Character = players.Character or players.CharacterAdded:Wait() wait(2) Mouse.Button2Down:Connect(function() Character.Humanoid.AutoRotate = false while Mouse.Button2Down ==true do Character.HumanoidRootPart.CFrame = CFrame.new(Character.HumanoidRootPart.CFrame,game.Workspace.CurrentCamera.Focus) end end) Mouse.Button2Up:Connect(function() Character.Humanoid.AutoRotate = true end) Character.Humanoid.AutoRotate = false while true do game:GetService("RunService").Heartbeat:Wait() UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter end
A good example of a game that does this is Warframe. The character only looks at the camera focus when aiming
Yea I found what I was looking for. So many views and not even an upvote or a comment. Thx anyways
local workspaceService = game:GetService("Workspace") local runService = game:GetService("RunService") local playersService = game:GetService("Players") local userInputService = game:GetService("UserInputService") -- config: local SENSITIVITY = 0.4 local WORLD_OFFSET = Vector3.new(0, 2, 0) local LOCAL_OFFSET = Vector3.new(3, 0, 9.5) -- variables: local camera = workspaceService.CurrentCamera local localPlayer = playersService.LocalPlayer local xAngle = 0 local yAngle = 0 -- main: -- handle camera moving userInputService.InputChanged:Connect(function(input, isProcessed) -- validate input if isProcessed then return end if input.UserInputType ~= Enum.UserInputType.MouseMovement then return end -- get delta local delta = input.Delta local deltaX = delta.X local deltaY = delta.Y -- update angles xAngle = xAngle - deltaX * SENSITIVITY yAngle = math.clamp(yAngle - deltaY * SENSITIVITY, -80, 80) end) -- handle camera update runService:BindToRenderStep("CameraUpdate", Enum.RenderPriority.Camera.Value, function() -- get necessary data local cameraSubject = camera.CameraSubject if not cameraSubject then return end local isLocalPlayer = false local subject local ignoredInstance -- check camera subject class if cameraSubject:IsA("Humanoid") then ignoredInstance = cameraSubject.Parent if not ignoredInstance:IsA("Model") then return end subject = ignoredInstance.PrimaryPart if not subject then return end if localPlayer.Character == ignoredInstance and cameraSubject.Health > 0 then isLocalPlayer = true end elseif cameraSubject:IsA("BasePart") then subject = cameraSubject ignoredInstance = cameraSubject else return end -- get positioned, world offset, and rotated cframe local xAngleCFrame = CFrame.Angles(0, math.rad(xAngle), 0) local anglesCFrame = xAngleCFrame:ToWorldSpace(CFrame.Angles(math.rad(yAngle), 0, 0)) local cameraPosition = subject.Position + WORLD_OFFSET local startCFrame = CFrame.new(cameraPosition):ToWorldSpace(anglesCFrame) -- get camera focus and local offset cframe local cameraCFrame = startCFrame:ToWorldSpace(CFrame.new(LOCAL_OFFSET)) local cameraFocus = cameraCFrame:ToWorldSpace(CFrame.new(0, 0, -LOCAL_OFFSET.Z)) -- assign camera properties camera.Focus = cameraFocus camera.CFrame = cameraCFrame camera.CFrame = cameraCFrame:ToWorldSpace(CFrame.new(0, 0, -camera:GetLargestCutoffDistance({ignoredInstance}))) -- rotate character if isLocalPlayer then local primaryPartCFrame = ignoredInstance:GetPrimaryPartCFrame() local newCFrame = CFrame.new(primaryPartCFrame.Position):ToWorldSpace(xAngleCFrame) end end) -- init userInputService.MouseBehavior = Enum.MouseBehavior.LockCenter