diff --git a/src/client/Character/Client/Camera/Bobbing.lua b/src/client/Character/Client/Camera/Bobbing.lua new file mode 100644 index 0000000..e6aefd2 --- /dev/null +++ b/src/client/Character/Client/Camera/Bobbing.lua @@ -0,0 +1,60 @@ +local Bobbing = {} +Bobbing.__index = Bobbing + +Bobbing.LeanMultiplier = 1.5 +Bobbing.TurnAlpha = .05 +Bobbing.SwayMultiplier = 1.7 + +type Euler = CFrame +type AnimationsMap = {[string]: (tick: number, dt: number) -> Euler} + +local Animations: AnimationsMap = {} + +local Storage = game:GetService("ReplicatedStorage") +local UIS = game:GetService("UserInputService") +local Algebra = require(Storage:WaitForChild("AlgebraEasings")) + +local CN = CFrame.new +local ANG = CFrame.Angles + +local CameraLean = CN() + +function Bobbing.constructor(HumanoidRootPart: BasePart, CurrentCamera: Camera, Humanoid: Humanoid) + return setmetatable({ + HumanoidRootPart = HumanoidRootPart, + CurrentCamera = CurrentCamera, + Humanoid = Humanoid + }, Bobbing) +end + +function Animations.Idle(t, dt) + return ANG( + math.rad(math.sin(t)/350), + math.rad(math.sin(t)/150), + math.rad(-math.cos(t)/50) + ) +end + +function Animations.Walk(t, dt) + return ANG(0,0,0) +end + +function Bobbing:Frame(dt: number) + local Root = self.HumanoidRootPart + local Camera = self.CurrentCamera + local Humanoid = self.Humanoid + + local CameraCF = Camera.CFrame + local Magnitude = Root:GetVelocityAtPosition(Root.Position).Magnitude + local CurrentAnimation = Animations[Magnitude>1 and "Walk" or "Idle"](tick(), dt) + + --Lean the camera based on looking and moving direction(s) + local MouseDelta = UIS:GetMouseDelta() + local LeanDegree = -CameraCF.RightVector:Dot(Humanoid.MoveDirection)*Bobbing.LeanMultiplier + local LeanMult = math.max(-Bobbing.SwayMultiplier, math.min(LeanDegree-MouseDelta.X, Bobbing.SwayMultiplier)) + CameraLean = CameraLean:Lerp(ANG(0, 0, math.rad(LeanMult)), Bobbing.TurnAlpha) + + Camera.CFrame *= CurrentAnimation*CameraLean +end + +return Bobbing \ No newline at end of file diff --git a/src/client/Character/Client/Camera/init.lua b/src/client/Character/Client/Camera/init.lua new file mode 100644 index 0000000..a14ecb0 --- /dev/null +++ b/src/client/Character/Client/Camera/init.lua @@ -0,0 +1,82 @@ +local Camera = {} +local FakeCamera = {} +Camera.__index = Camera +FakeCamera.__index = FakeCamera + +local RS = game:GetService("RunService") +local Storage = game:GetService("ReplicatedStorage") + +local Bobbing = require(script:WaitForChild("Bobbing")) +local Algebra = require(Storage:WaitForChild("AlgebraEasings")) + +type FakeCamera = BasePart + +function Camera.constructor(CurrentCamera: Camera, HumanoidRootPart: BasePart, Humanoid: Humanoid) + local self = { + Binded = { + CameraFPS = false, + FakeCamera = false + } + } + self.CurrentCamera = CurrentCamera + self.HumanoidRootPart = HumanoidRootPart + self.BobbingCamera = Bobbing.constructor(HumanoidRootPart, CurrentCamera, Humanoid) + return setmetatable(self, Camera) +end + +function Camera:SetupFakeCamera() + --This entire function should be its own module but it only serves as 2 copied functions from here, + if not self.Binded.FakeCamera then + --Use a fake head part to follow the head on a "lerp" to smooth out movement so its not an instant halt at stop + local FakeCamera = Instance.new("Part") + FakeCamera.Size = Vector3.zero + FakeCamera.CanCollide = false + FakeCamera.CastShadow = false + FakeCamera.Anchored = true + FakeCamera.Parent = self.HumanoidRootPart + + --Tie with the roblox engine + RS:BindToRenderStep("FakeCameraMovement", Enum.RenderPriority.Camera.Value, function(dt) + FakeCamera.CFrame = FakeCamera.CFrame:Lerp( + self.HumanoidRootPart.CFrame+Vector3.yAxis, + Algebra.InOutBack(.9)) + end) + self.CurrentCamera.CameraSubject = FakeCamera + self.Binded.FakeCamera = true + else + print("Character Camera: Cannot call SetupFakeCamera while its active", debug.traceback()) + end +end + +function Camera:EnableBobbing() + if not self.Binded.CameraFPS then + RS:BindToRenderStep("CameraAnimations", Enum.RenderPriority.Camera.Value+1, function(dt) + self.BobbingCamera:Frame(dt) + end) + self.Binded.CameraFPS = true + else + print("Character Camera: Cannot call EnableBobbing while its active", debug.traceback()) + end +end + +function Camera:StopFakeCamera() + if self.Binded.FakeCamera then + RS:UnbindFromRenderStep("FakeCameraMovement") + self.CurrentCamera.CameraSubject = self.Humanoid + self.Binded.FakeCamera = false + else + print("Character Camera: StopFakeCamera was called before SetupFakeCamera", debug.traceback()) + end +end + +function Camera:DisableBobbing() + if self.Binded.CameraFPS then + RS:UnbindFromRenderStep("CameraAnimations") + self.Binded.CameraFPS = false + else + print("Character Camera: DisableBobbing was called before EnableBobbing", debug.traceback()) + end + self.CurrentCamera.CFrame *= CFrame.Angles(0,0,0) +end + +return Camera \ No newline at end of file diff --git a/src/client/Character/Client/LocalTransparencyModifier.lua b/src/client/Character/Client/LocalTransparencyModifier.lua new file mode 100644 index 0000000..265b434 --- /dev/null +++ b/src/client/Character/Client/LocalTransparencyModifier.lua @@ -0,0 +1,35 @@ +--Heh, i copied and pasted this from Character/Server/Shadows.lua + +local LTM = {} +LTM.__index = LTM + +type Character = Model + +function LTM.constructor(Character: Character) + return setmetatable({ + Character = Character + }, LTM) +end + +function LTM:PartToggle(Instance: BasePart, Visible: boolean) + if Instance:IsA("BasePart") then + Instance.LocalTransparencyModifier = Visible and 0 or 1 + end +end + +local function CharacterLTM(self, enabled: boolean) + local CharacterDescendants = self.Character:GetDescendants() + for i = 1, #CharacterDescendants do + self:PartToggle(CharacterDescendants[i], enabled) + end +end + +function LTM:on() + CharacterLTM(self, true) +end + +function LTM:off() + CharacterLTM(self, false) +end + +return LTM \ No newline at end of file diff --git a/src/client/Character/Client/init.client.lua b/src/client/Character/Client/init.client.lua index aa7482f..f72140f 100644 --- a/src/client/Character/Client/init.client.lua +++ b/src/client/Character/Client/init.client.lua @@ -1,8 +1,17 @@ local HumanoidRPSettings = require(script:WaitForChild("HumanoidRootPart")) +local CameraModule = require(script:WaitForChild("Camera")) +local LTM = require(script:WaitForChild("LocalTransparencyModifier")) --Should this just be part of Camera.lua? idk, -local Character = script.Parent +local Character = script.Parent local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart") +local Humanoid = Character:WaitForChild("Humanoid") +local CurrentCamera = workspace.CurrentCamera local HRPSettings = HumanoidRPSettings.constructor(HumanoidRootPart) +local LTMSettings = LTM.constructor(Character) +local CameraConsturctor = CameraModule.constructor(CurrentCamera, HumanoidRootPart, Humanoid) -HRPSettings:DisableRobloxSounds() \ No newline at end of file +HRPSettings:DisableRobloxSounds() +LTMSettings:off() +CameraConsturctor:SetupFakeCamera() +CameraConsturctor:EnableBobbing() \ No newline at end of file diff --git a/src/client/Character/Server/Shadows.lua b/src/client/Character/Server/Shadows.lua index eebdf06..df83087 100644 --- a/src/client/Character/Server/Shadows.lua +++ b/src/client/Character/Server/Shadows.lua @@ -32,5 +32,4 @@ function Shadows:off() CharacterShadows(self, false) end - return Shadows \ No newline at end of file diff --git a/src/client/Player/Camera/init.lua b/src/client/Player/Camera.lua similarity index 71% rename from src/client/Player/Camera/init.lua rename to src/client/Player/Camera.lua index a165271..fd6fa41 100644 --- a/src/client/Player/Camera/init.lua +++ b/src/client/Player/Camera.lua @@ -11,11 +11,8 @@ Camera.FOV.Speed = { } local Storage = game:GetService("ReplicatedStorage") -local RS = game:GetService("RunService") local Tween = require(Storage:WaitForChild("Tween")) --- local Bobbing = require(script:WaitForChild("Bobbing")) - local ZoomTween = Tween.constructor() function Camera.constructor(CurrentCamera: Camera, Player: Player) @@ -25,20 +22,12 @@ function Camera.constructor(CurrentCamera: Camera, Player: Player) }, Camera) end -function Camera:LockFirstPerson() +function Camera:FirstPerson() self.Player.CameraMode = Enum.CameraMode.LockFirstPerson end -function Camera:EnableBobbing() - self.CameraFrames = RS.RenderStepped:Connect(function(dt) - - end) -end - -function Camera:DisableBobbing() - if self.CameraFrames then - self.CameraFrames:Disconnect() - end +function Camera:ThirdPerson() + self.Player.CameraMode = Enum.CameraMode.Classic end function Camera:ZoomIn() diff --git a/src/client/Player/Camera/Bobbing.lua b/src/client/Player/Camera/Bobbing.lua deleted file mode 100644 index c4dda9d..0000000 --- a/src/client/Player/Camera/Bobbing.lua +++ /dev/null @@ -1,3 +0,0 @@ -return function(dt) - -end \ No newline at end of file diff --git a/src/client/Player/init.client.lua b/src/client/Player/init.client.lua index 7689e90..94e81ae 100644 --- a/src/client/Player/init.client.lua +++ b/src/client/Player/init.client.lua @@ -6,11 +6,11 @@ local Crosshair = require(script:WaitForChild("Crosshair")) local Players = game:GetService("Players") local Storage = game:GetService("ReplicatedStorage") -local ClientStorage = Storage:WaitForChild("Client") +local ClientStorage = Storage:WaitForChild("Client") local KeyBindsModule = require(ClientStorage:WaitForChild("KeyBinds")) local Player = Players.LocalPlayer -local CurrentCamera +local CurrentCamera = nil repeat task.wait() CurrentCamera = workspace.CurrentCamera @@ -33,7 +33,7 @@ end CoreGuis:off() Mouse:DisablePointer() -Camera:LockFirstPerson() +Camera:FirstPerson() CrosshairObject:Spawn() CameraBinds() \ No newline at end of file diff --git a/src/shared/AlgebraEasings.lua b/src/shared/AlgebraEasings.lua new file mode 100644 index 0000000..9dcd685 --- /dev/null +++ b/src/shared/AlgebraEasings.lua @@ -0,0 +1,30 @@ +--My versions + +type EaseFunction = (n: number) -> number + +export type EasingStyles = { + Linear: EaseFunction, + InOutBack: EaseFunction, + OutBounce: EaseFunction +} + +local Ease: EasingStyles = {} +--Google straight up gives wrong/bad math + +function Ease.Linear(a,b,t) + return a-a*t+b*t +end + +local c = 2.59491 +function Ease.InOutBack(n) + return n<.5 and 2*n*n*(-c+2*n+2*c*n) or 3*(-1+n)*(-1+n)*(-2-c+2*n+2*c*n) +end + +local n1, d1 = 7.5625, 2.75 +function Ease.OutBounce(n) + return (n<0.363636 and n*n*n1 or + n<0.727273 and (.75*(1.*d1-2.*n*n1)) or + n<0.909091 and (.9375*(1.*d1-2.4*n*n1)/d1)) or (.984375*(1.*d1-2.66667*n*n1))/d1 +end + +return Ease \ No newline at end of file diff --git a/src/shared/Client/KeyBinds.lua b/src/shared/Client/KeyBinds.lua index c86870a..612db6d 100644 --- a/src/shared/Client/KeyBinds.lua +++ b/src/shared/Client/KeyBinds.lua @@ -25,6 +25,7 @@ function BindLink.constructor() --Allow multiple bindings of the same keys, no o Began = {}, Ended = {} } + --Return these for convenience self.InputBegan = UIS.InputBegan:Connect(function(input, gameProcessedEvent) if not gameProcessedEvent then