Files
Roblox-Elevator-Game/src/client/Character/Client/Camera/Bobbing.lua
2024-02-26 03:37:27 -05:00

117 lines
3.4 KiB
Lua

--!optimize 2
--!native
--!strict
local Bobbing = {}
Bobbing.__index = Bobbing
Bobbing.TurnAlpha = 0.050
Bobbing.LeanMultiplier = 1.7
Bobbing.SwayMultiplier = 1.5
Bobbing.AnimationAlpha = 0.5
Bobbing.MaxGimbalLockY = 65
Bobbing.AnimationSpeed = 200
Bobbing.Tick = 0
Bobbing.ForceStop = false
type AnimationsMap = {[string]: (tick: number, dt: number) -> Euler}
local Animations: AnimationsMap = {}
type Euler = CFrame
type HumanoidRootPart = BasePart
local UIS = game:GetService("UserInputService")
local CN = CFrame.new
local ANG = CFrame.Angles
local CameraLean = CN()
local Animation = CN()
function Bobbing.constructor(HumanoidRootPart: HumanoidRootPart, CurrentCamera: Camera, Humanoid: Humanoid)
return setmetatable({
HumanoidRootPart = HumanoidRootPart,
CurrentCamera = CurrentCamera,
Humanoid = Humanoid
}, Bobbing)
end
type deltatime = number
type tick = number
type EulerValue = number
function Animations.Idle(t: tick, dt: deltatime)
return ANG(
math.rad(math.cos(t/80)/(Bobbing.AnimationSpeed+50)),
math.rad(math.sin(t/50)/Bobbing.AnimationSpeed),
math.rad(math.sin(t/70)/(Bobbing.AnimationSpeed-50))
)
end
function Animations.Walk(t: tick, dt: deltatime)
-- return ANG(
-- math.rad(-10*math.cos(t)/2),
-- 0,
-- math.rad(5*math.cos(t)/2)
-- )
return ANG(
0,
0,
0
)
end
function Animations.Stop()
return ANG(0,0,0)
end
function Animations.Falling()
return ANG(0,0,0)
end
local function maxmin(min: number, mid: number, max: number): number
return math.max(min, math.min(mid, max))
end
local function Camera_YArc(Camera: Camera): EulerValue --stop Euler gimbal lock when you're looking directly up or down
local EulerY,_,_ = Camera.CFrame.Rotation:ToEulerAnglesYXZ()
return math.abs(math.deg(EulerY))
end
local function CameraAnimation(self, dt: deltatime)
--crying
Bobbing.Tick += 1
local Root: BasePart = self.HumanoidRootPart
local Velocity: Vector3 = Root:GetVelocityAtPosition(Root.Position)
local RootMagnitude: number = Velocity.Magnitude
--go go boolean algebra
local MaxMinY: boolean = Camera_YArc(self.CurrentCamera)>Bobbing.MaxGimbalLockY --TODO: instead, make this an equation so it will just subtract from the existing animation radians
local AnimationType: string = Bobbing.ForceStop and "Stop" or RootMagnitude>1 and "Walk" or (not MaxMinY and "Idle" or "Stop")
local CurrentAnimation: CFrame = Animations[AnimationType](Bobbing.Tick, dt)
--"Lerp" so the transitions between walking and idling are smoothed instead of instant
return Animation:Lerp(CurrentAnimation, Bobbing.AnimationAlpha)
end
function Bobbing:Frame(dt: number)
local Camera = self.CurrentCamera
local Humanoid = self.Humanoid
local CameraCF = Camera.CFrame
Animation = CameraAnimation(self, dt)
--Lean the camera based on looking and moving direction(s)
local MouseDelta = UIS:GetMouseDelta()
local LeanDegree_Roll = -CameraCF.RightVector:Dot(Humanoid.MoveDirection)*Bobbing.LeanMultiplier
--Jump?!
--local LeanDegree_Pitch = -CameraCF.UpVector:Dot(Humanoid.MoveDirection)*Bobbing.LeanMultiplier
local LeanMult_Roll = maxmin(-Bobbing.SwayMultiplier, LeanDegree_Roll-MouseDelta.X, Bobbing.SwayMultiplier)
CameraLean = CameraLean:Lerp(ANG(0, 0, math.rad(LeanMult_Roll)), Bobbing.TurnAlpha)
Camera.CFrame *= Animation*CameraLean
end
return Bobbing