76 lines
2.1 KiB
Lua
76 lines
2.1 KiB
Lua
local PlayersService = game:GetService('Players')
|
|
local RootCameraCreator = require(script.Parent)
|
|
|
|
local ZERO_VECTOR2 = Vector2.new(0, 0)
|
|
local XZ_VECTOR = Vector3.new(1,0,1)
|
|
|
|
local Vector2_new = Vector2.new
|
|
local CFrame_new = CFrame.new
|
|
local math_atan2 = math.atan2
|
|
local math_min = math.min
|
|
|
|
local function IsFinite(num)
|
|
return num == num and num ~= 1/0 and num ~= -1/0
|
|
end
|
|
|
|
-- May return NaN or inf or -inf
|
|
-- This is a way of finding the angle between the two vectors:
|
|
local function findAngleBetweenXZVectors(vec2, vec1)
|
|
return math_atan2(vec1.X*vec2.Z-vec1.Z*vec2.X, vec1.X*vec2.X + vec1.Z*vec2.Z)
|
|
end
|
|
|
|
local function CreateAttachCamera()
|
|
local module = RootCameraCreator()
|
|
|
|
local lastUpdate = tick()
|
|
function module:Update()
|
|
local now = tick()
|
|
|
|
local camera = workspace.CurrentCamera
|
|
|
|
if lastUpdate == nil or now - lastUpdate > 1 then
|
|
module:ResetCameraLook()
|
|
self.LastCameraTransform = nil
|
|
end
|
|
|
|
local subjectPosition = self:GetSubjectPosition()
|
|
if subjectPosition and camera then
|
|
local zoom = self:GetCameraZoom()
|
|
if zoom <= 0 then
|
|
zoom = 0.1
|
|
end
|
|
|
|
|
|
local humanoid = self:GetHumanoid()
|
|
if lastUpdate and humanoid and humanoid.Torso then
|
|
|
|
-- Cap out the delta to 0.1 so we don't get some crazy things when we re-resume from
|
|
local delta = math_min(0.1, now - lastUpdate)
|
|
local gamepadRotation = self:UpdateGamepad()
|
|
self.RotateInput = self.RotateInput + (gamepadRotation * delta)
|
|
|
|
local forwardVector = humanoid.Torso.CFrame.lookVector
|
|
|
|
local y = findAngleBetweenXZVectors(forwardVector, self:GetCameraLook())
|
|
if IsFinite(y) then
|
|
-- Preserve vertical rotation from user input
|
|
self.RotateInput = Vector2_new(y, self.RotateInput.Y)
|
|
end
|
|
end
|
|
|
|
local newLookVector = self:RotateCamera(self:GetCameraLook(), self.RotateInput)
|
|
self.RotateInput = ZERO_VECTOR2
|
|
|
|
camera.Focus = CFrame_new(subjectPosition)
|
|
local newCFrame = CFrame_new(subjectPosition - (zoom * newLookVector), subjectPosition)
|
|
camera.CFrame = newCFrame
|
|
self.LastCameraTransform = newCFrame
|
|
end
|
|
lastUpdate = now
|
|
end
|
|
|
|
return module
|
|
end
|
|
|
|
return CreateAttachCamera
|