I have a custom camera system that works fine, however I want a function that forces the player to look towards a position, but also allow them to resist the effects, so they can try to pull away. The issue is that it seems like the onRenderStep function overrides the focus function, and i sometimes get focused, and other times my camera rotates on the wrong axis.
This is the code that updates the camera.
local function onRenderStep(dt)
if not character then return end
if not primaryPart then return end
if not humanoid then return end
-- Camera Bob
currentTime += dt
local bobAmplitudeX = math.clamp(Config.BOB_AMPLITUDE_X / (humanoid.Health / humanoid.MaxHealth), 0, 0.8)
local bobAmplitudeY = math.clamp( Config.BOB_AMPLITUDE_Y / (humanoid.Health / humanoid.MaxHealth), 0, 0.8)
local bobFrequencyX = math.clamp(Config.BOB_FREQUENCY_X * (humanoid.WalkSpeed / 10), 0, 4)
local bobFrequencyY = math.clamp( Config.BOB_FREQUENCY_Y * (humanoid.WalkSpeed / 10), 0, 6)
local bobOffsetX = (math.sin(currentTime * math.pi * Config.BOB_FREQUENCY_X) - 0.5) * bobAmplitudeX
local bobOffsetY = (math.sin(currentTime * math.pi * Config.BOB_FREQUENCY_Y) - 0.5) * bobAmplitudeY
local velocityMagnitude = (primaryPart.Velocity * Vector3.new(1,0,1)).Magnitude
local targetVelocityMultiplier = math.clamp(velocityMagnitude, 0, Config.MAX_BOB_VELOCITY) / Config.MAX_BOB_VELOCITY
velocityMultiplier = scalarLerp(velocityMultiplier, targetVelocityMultiplier, Config.BOB_RECENTER_SPEED * dt)
bobOffsetX *= velocityMultiplier
bobOffsetY *= velocityMultiplier
for _, part in pairs(character:GetDescendants()) do
if part:IsA("BasePart") then
part.LocalTransparencyModifier = 1
end
end
-- CAmera Movement
CAMERA.CameraType = Enum.CameraType.Scriptable
if mouseLocked then
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
UserInputService.MouseIconEnabled = false
else
UserInputService.MouseBehavior = Enum.MouseBehavior.Default
UserInputService.MouseIconEnabled = true
end
local mouseDelta = UserInputService:GetMouseDelta() * Config.SENSITIVITY
hAngle -= mouseDelta.X / CAMERA.ViewportSize.X
vAngle -= mouseDelta.Y / CAMERA.ViewportSize.Y
vAngle = math.rad(math.clamp(math.deg(vAngle), -80, 80))
local newCameraCFrame = CFrame.new(primaryPart.Position) *
CFrame.Angles(0, hAngle, 0) *
CFrame.Angles(vAngle, 0, 0) *
CFrame.new(Config.CAMERA_OFFSET) *
CFrame.new(bobOffsetX, 0, 0) *
CFrame.Angles(math.rad(bobOffsetY), 0, math.rad(bobOffsetX * 2))
newCameraCFrame = CAMERA.CFrame:Lerp(newCameraCFrame, Config.CAMERA_SPEED)
-- Camera Obstructions
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {character}
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
local raycastResult = workspace:Raycast(
primaryPart.Position,
newCameraCFrame.Position - primaryPart.Position,
raycastParams
)
if (raycastResult ~= nil) then
local obstructionDisplacement = (raycastResult.Position - primaryPart.Position)
local obstructionPosition = primaryPart.Position + (obstructionDisplacement.Unit * (obstructionDisplacement.Magnitude - 0.1))
local x,y,z,r00,r01,r02,r10,r11,r12,r20,r21,r22 = newCameraCFrame:components()
newCameraCFrame = CFrame.new(obstructionPosition.x, obstructionPosition.y, obstructionPosition.z, r00, r01, r02, r10, r11, r12, r20, r21, r22)
end
-- Primary Part Rotation
if humanoid.MoveDirection.Magnitude > 0 then
local newPrimaryPartCFrame = CFrame.new(primaryPart.Position) *
CFrame.Angles(0, hAngle, 0)
primaryPart.CFrame = primaryPart.CFrame:Lerp(newPrimaryPartCFrame, Config.CAMERA_SPEED / 2)
end
-- Set Camera Position
CAMERA.CFrame = newCameraCFrame
end
This is the code that forces the camera to face a position.
function CameraController:FocusCameraToPosition(position)
if isFocusing then return end
isFocusing = true
RunService:BindToRenderStep("CameraController_FocusCamera", Enum.RenderPriority.Camera.Value - 1, function()
local newCameraCFrame = CFrame.lookAt(CAMERA.CFrame.Position, position)
CAMERA.CFrame = newCameraCFrame
end)
end
function CameraController:StopFocusing()
if not isFocusing then return end
isFocusing = false
RunService:UnbindFromRenderStep("CameraController_FocusCamera")
end