Ive been trying to make it when a player activates a tool their camera keeps the current direction its pointing in.
Goes over their shoulder and the torso then points in the same position as the camera.
From there the camera and torso both follow mouse position
Ive copied roblox’s base code and played around with it:
I realized that the cameraFocus variable is where the problem lies.
When I activate the tool the camera turns towards -10000 z axis. Instead of where the players current camera is facing.
I tried replacing it with the Cameras current look vector but it didnt work making the camera go wonky
If anyone could help explain if the problem is with the cameraFocus variable, and how to fix it.
Make an invisible accessory/tool where you want the camera to focus and make it focus on it. Because the player moves with that accessory/tool it will keep its focus on the player from the angle you set it to be. I find this way to be easier than starting to calculate.
The issue is the -10000 z value. When the tool is activated and the function below runs it points them at the -10000 z direction of world.
After this initial turn at -10000 the script works as intended, with the mouse locked to center, torso following the mouse, and camera staying offset
When changing the value to 0 it completely removes the camera offset.
And when making it +10000 the camera goes bananas
Im trying to make it as soon as the player activates tool it makes player face toward camera (not -10000).
local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetSerivce("RunService")
local ContextActionService = game:GetService("ContextActionService")
local Player = Players.LocalPlayer
local Mouse = Player:GetMouse()
local Character = Player.Character
local Humanoid = Character.Humanoid
local RootPart = Character.HumanoidRootPart
local Camera = game.Workspace.CurrentCamera
local DefaultCFrame = CameraOffSet = Vector3.new(2,2.05,8)
local function OnToolActivated()
RunService:BindToRenderStep("MouseLock", Enum.RenderPriority.Last.Value+1, function()
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
end)
Humanoid.AutoRotate = false
local cameraAngleX = 0
local cameraAngleY = 0
local function playerInput(actionName, inputState, inputObject)
if inputState == Enum.UserInputState.Change then
cameraAngleX -= inputObject.Delta.X
cameraAngleY = math.clamp(cameraAngleY - inputObject.Delta.Y * 0.4, -75, 75)
end
end
ContextActionService:BindAction("PlayerInput",playerInput,false,Enum.UserInputType.MouseMovement,Enum.UserInputType.Touch)
RunService:BindToRenderStep("CameraUpdate", Enum.RenderPriority.Camera.Value,function()
local startCFrame = CFrame.new(RootPart.CFrame.Position)*CFrame.Angles(0,math.rad(cameraAngleX),0)*CFrame.Angles(math.rad(cameraAngleY),0,0)
local cameraCFrame = startCFrame:PointToWorldSpace(CameraOffSet)
local cameraFocus = startCFrame:PointToWorldSpace(Vector3.new(CameraOffSet.X,CameraOffSet.Y,-10000))
Camera.CFrame = CFrame.lookAt(cameraCFrame,cameraFocus)
local lookingCFrame = CFrame.lookAt(RootPart.Position, Camera.CFrame:PointToWorldSpace(Vector3.new(0,0,-100000)))
RootPart.CFrame = CFrame.fromMatrix(RootPart.Position, lookingCFrame.XVector, RootPart.CFrame.YVector)
end)
end
This is my fixed script, It even comes with it’s own deactivated event!
local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local ContextActionService = game:GetService("ContextActionService")
local Player = Players.LocalPlayer
local Mouse = Player:GetMouse()
Player.CharacterAdded:Connect(function(plr)
if plr ~= nil then
local Character = plr
Humanoid = Character:WaitForChild("Humanoid")
RootPart = Character:WaitForChild("HumanoidRootPart")
end
end)
local Camera = game.Workspace.CurrentCamera
local CameraOffSet = Vector3.new(2,2.05,8)
local function OnToolActivated()
RunService:BindToRenderStep("MouseLock", Enum.RenderPriority.Last.Value+1, function()
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
end)
Humanoid.AutoRotate = false
local cameraAngleX = 0
local cameraAngleY = 0
local function playerInput(actionName, inputState, inputObject)
if inputState == Enum.UserInputState.Change then
cameraAngleX -= inputObject.Delta.X
cameraAngleY = math.clamp(cameraAngleY - inputObject.Delta.Y * 0.4, -75, 75)
end
end
ContextActionService:BindAction("PlayerInput",playerInput,false,Enum.UserInputType.MouseMovement,Enum.UserInputType.Touch)
RunService:BindToRenderStep("CameraUpdate", Enum.RenderPriority.Camera.Value,function()
local startCFrame = CFrame.new(RootPart.CFrame.Position)*CFrame.Angles(0,math.rad(cameraAngleX),0)*CFrame.Angles(math.rad(cameraAngleY),0,0)
local cameraCFrame = startCFrame:PointToWorldSpace(CameraOffSet)
local cameraFocus = startCFrame:PointToWorldSpace(Vector3.new(CameraOffSet.X,CameraOffSet.Y,-10000))
Camera.CFrame = CFrame.lookAt(cameraCFrame,cameraFocus)
RootPart.CFrame = CFrame.fromMatrix(RootPart.Position, Camera.CFrame.XVector, RootPart.CFrame.YVector)
end)
end
local function OnToolDeactivated()
RunService:UnbindFromRenderStep("MouseLock")
ContextActionService:UnbindAction("PlayerInput")
RunService:UnbindFromRenderStep("CameraUpdate")
Humanoid.AutoRotate = true
end
script.Parent.Activated:Connect(OnToolActivated)
script.Parent.Deactivated:Connect(OnToolDeactivated)
What I did is that, instead of CFrame.lookat(), I made the rotation based on the camera XVector, nothing else was changed and I added RunService Unbind functions and ContextActionService UnbindAction functions for the deactivated part.
If the Camera’s CFrame of the CFrame.lookat() is greater than the Camera’s Focus, then it would increase how far it should be from the player, making the camera not be like shift lock at all.
What it would look like? Let’s see:
Well those results didn’t work, even if we mirror their effects… Welp this result is the only one that looks like shiftlock except the z-axis rotation ain’t good: