diff --git a/src/client/Character/Client/Camera/Bobbing.lua b/src/client/Character/Client/Camera/Bobbing.lua index e6aefd2..a76398e 100644 --- a/src/client/Character/Client/Camera/Bobbing.lua +++ b/src/client/Character/Client/Camera/Bobbing.lua @@ -1,25 +1,29 @@ local Bobbing = {} Bobbing.__index = Bobbing -Bobbing.LeanMultiplier = 1.5 -Bobbing.TurnAlpha = .05 -Bobbing.SwayMultiplier = 1.7 +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 -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")) +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: BasePart, CurrentCamera: Camera, Humanoid: Humanoid) +function Bobbing.constructor(HumanoidRootPart: HumanoidRootPart, CurrentCamera: Camera, Humanoid: Humanoid) return setmetatable({ HumanoidRootPart = HumanoidRootPart, CurrentCamera = CurrentCamera, @@ -27,34 +31,69 @@ function Bobbing.constructor(HumanoidRootPart: BasePart, CurrentCamera: Camera, }, Bobbing) end -function Animations.Idle(t, dt) +type deltatime = number +type tick = number +type EulerValue = number + +function Animations.Idle(t: tick, dt: deltatime) return ANG( - math.rad(math.sin(t)/350), - math.rad(math.sin(t)/150), - math.rad(-math.cos(t)/50) + 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, dt) +function Animations.Walk(t: tick, dt: deltatime) + return ANG( + math.rad(-10*math.cos(t)/2), + 0, + math.rad(5*math.cos(t)/2) + ) +end + +function Animations.Stop() return ANG(0,0,0) end -function Bobbing:Frame(dt: number) +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) + Bobbing.Tick += 1 local Root = self.HumanoidRootPart + local RootMagnitude = Root:GetVelocityAtPosition(Root.Position).Magnitude + + local MaxMinY = Camera_YArc(self.CurrentCamera)>Bobbing.MaxGimbalLockY --TODO: instead, make this an equation so it will just subtract from the existing animation radians + local AnimationType = RootMagnitude>1 and "Walk" or (not MaxMinY and "Idle" or "Stop") + local CurrentAnimation = 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 - local Magnitude = Root:GetVelocityAtPosition(Root.Position).Magnitude - local CurrentAnimation = Animations[Magnitude>1 and "Walk" or "Idle"](tick(), dt) + Animation = CameraAnimation(self, 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) + local LeanDegree_Roll = -CameraCF.RightVector:Dot(Humanoid.MoveDirection)*Bobbing.LeanMultiplier + --Jump?! + --local LeanDegree_Pitch = -CameraCF.UpVector:Dot(Humanoid.MoveDirection)*Bobbing.LeanMultiplier - Camera.CFrame *= CurrentAnimation*CameraLean + 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 \ No newline at end of file diff --git a/src/client/Character/Client/Camera/init.lua b/src/client/Character/Client/Camera/init.lua index a14ecb0..0a51659 100644 --- a/src/client/Character/Client/Camera/init.lua +++ b/src/client/Character/Client/Camera/init.lua @@ -4,75 +4,34 @@ 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 - } - } + local self = {} + self.CameraFPS = 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 + if not self.CameraFPS then RS:BindToRenderStep("CameraAnimations", Enum.RenderPriority.Camera.Value+1, function(dt) self.BobbingCamera:Frame(dt) end) - self.Binded.CameraFPS = true + self.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 + if self.CameraFPS then RS:UnbindFromRenderStep("CameraAnimations") - self.Binded.CameraFPS = false + self.CameraFPS = false else print("Character Camera: DisableBobbing was called before EnableBobbing", debug.traceback()) end diff --git a/src/client/Character/Client/LocalTransparencyModifier.lua b/src/client/Character/Client/LocalTransparencyModifier.lua deleted file mode 100644 index 265b434..0000000 --- a/src/client/Character/Client/LocalTransparencyModifier.lua +++ /dev/null @@ -1,35 +0,0 @@ ---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 f72140f..c317275 100644 --- a/src/client/Character/Client/init.client.lua +++ b/src/client/Character/Client/init.client.lua @@ -1,6 +1,5 @@ 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 HumanoidRootPart = Character:WaitForChild("HumanoidRootPart") @@ -8,10 +7,7 @@ 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() -LTMSettings:off() -CameraConsturctor:SetupFakeCamera() CameraConsturctor:EnableBobbing() \ No newline at end of file diff --git a/src/client/Character/Server/Humanoid.lua b/src/client/Character/Server/Humanoid.lua index f417ba8..5f3f1fc 100644 --- a/src/client/Character/Server/Humanoid.lua +++ b/src/client/Character/Server/Humanoid.lua @@ -1,7 +1,7 @@ local HumanoidModule = {} HumanoidModule.__index = HumanoidModule -type WalkSpeed = number | nil +type WalkSpeed = number? function HumanoidModule.constructor(Humanoid: Humanoid) return setmetatable({ diff --git a/src/client/Character/Server/init.server.lua b/src/client/Character/Server/init.server.lua index e1c4650..64bd775 100644 --- a/src/client/Character/Server/init.server.lua +++ b/src/client/Character/Server/init.server.lua @@ -9,7 +9,7 @@ local CharacterShadows = Shadows.constructor(Character) local HumanoidSettings = HumanoidModule.constructor(Humanoid) CharacterShadows:off() --I plan to have 2 player support and characters block a ton of light -HumanoidSettings:SetWalkSpeed(12) +HumanoidSettings:SetWalkSpeed(10) Character.DescendantAdded:Connect(function(Instance) task.wait() --Wait for the instance to properly replicate? diff --git a/src/client/Player/Camera.lua b/src/client/Player/Camera.lua index fd6fa41..04dfc18 100644 --- a/src/client/Player/Camera.lua +++ b/src/client/Player/Camera.lua @@ -3,22 +3,27 @@ Camera.__index = Camera Camera.FOV = { Default = 70, - Zoomed = 40, + Zoomed = 30, } Camera.FOV.Speed = { In = 0.3, Out = 0.4 } +Camera.VignetteEnabled = true +Camera.CrosshairEffect = true +Camera.EffectsEase = Enum.EasingStyle.Quad local Storage = game:GetService("ReplicatedStorage") local Tween = require(Storage:WaitForChild("Tween")) + local ZoomTween = Tween.constructor() +local VignetteTween = Tween.constructor() function Camera.constructor(CurrentCamera: Camera, Player: Player) return setmetatable({ Camera = CurrentCamera, - Player = Player + Player = Player, }, Camera) end @@ -30,16 +35,60 @@ function Camera:ThirdPerson() self.Player.CameraMode = Enum.CameraMode.Classic end -function Camera:ZoomIn() +--damn... +type Vignette = any +type Crosshair = any + +function Camera:ZoomIn(Vignette: Vignette?, Crosshair: Crosshair?) ZoomTween:Start(self.Camera, { FieldOfView = Camera.FOV.Zoomed - }, TweenInfo.new(Camera.FOV.Speed.In, Enum.EasingStyle.Quad)) + }, TweenInfo.new(Camera.FOV.Speed.In, Camera.EffectsEase)) + + if Camera.VignetteEnabled then + if Vignette then + Vignette.VignetteSettings.Enabled = true + + VignetteTween:Start(Vignette.VignetteSettings.VignetteIcon, { + ImageTransparency = 0 + }, TweenInfo.new(Camera.FOV.Speed.In, Camera.EffectsEase)) + else + warn("Camera: ", debug.traceback()) + end + end + + if Camera.CrosshairEffect then + if Crosshair then + + else + warn("Camera: ", debug.traceback()) + end + end end -function Camera:ZoomOut() +function Camera:ZoomOut(Vignette: Vignette?, Crosshair: Crosshair?) ZoomTween:Start(self.Camera, { FieldOfView = Camera.FOV.Default - }, TweenInfo.new(Camera.FOV.Speed.Out, Enum.EasingStyle.Quad)) + }, TweenInfo.new(Camera.FOV.Speed.Out, Camera.EffectsEase)) + + if Camera.VignetteEnabled then + if Vignette then + Vignette.VignetteSettings.Enabled = true + + VignetteTween:Start(Vignette.VignetteSettings.VignetteIcon, { + ImageTransparency = 1 + }, TweenInfo.new(Camera.FOV.Speed.Out, Camera.EffectsEase)) + else + warn("Camera: ", debug.traceback()) + end + end + + if Camera.CrosshairEffect then + if Crosshair then + + else + warn("Camera: ", debug.traceback()) + end + end end return Camera \ No newline at end of file diff --git a/src/client/Player/Crosshair.lua b/src/client/Player/Crosshair.lua deleted file mode 100644 index 8b88074..0000000 --- a/src/client/Player/Crosshair.lua +++ /dev/null @@ -1,34 +0,0 @@ -local Crosshair = { - Icon = "rbxassetid://12643750723" -} -Crosshair.__index = Crosshair - ---Use a custom crosshair so we can do effects to it - -function Crosshair.constructor(Player: Player) - local ScreenGui = Instance.new("ScreenGui") - ScreenGui.ResetOnSpawn = false - ScreenGui.IgnoreGuiInset = true - ScreenGui.Name = "Crosshair" - - local CrosshairIcon = Instance.new("ImageLabel") - CrosshairIcon.AnchorPoint = Vector2.new(.5,.5) - CrosshairIcon.Position = UDim2.fromScale(.5,.5) - CrosshairIcon.Size = UDim2.fromScale(.4,.4) - CrosshairIcon.Image = Crosshair.Icon - CrosshairIcon.BackgroundTransparency = 1 - CrosshairIcon.ScaleType = Enum.ScaleType.Fit - CrosshairIcon.Parent = ScreenGui - - return setmetatable({ - Player = Player, - ScreenGui = ScreenGui, - CrosshairIcon = CrosshairIcon - }, Crosshair) -end - -function Crosshair:Spawn() - self.ScreenGui.Parent = self.Player:WaitForChild("PlayerGui") -end - -return Crosshair \ No newline at end of file diff --git a/src/client/Player/UI/Crosshair.lua b/src/client/Player/UI/Crosshair.lua new file mode 100644 index 0000000..421f092 --- /dev/null +++ b/src/client/Player/UI/Crosshair.lua @@ -0,0 +1,31 @@ +local CrosshairModule = { + Icon = "rbxassetid://12643750723" +} +CrosshairModule.__index = CrosshairModule + +--Use a custom crosshair so we can do effects to it +type rbxassetid = string + +function CrosshairModule.constructor(PlayerGui: PlayerGui) + local Crosshair = PlayerGui:WaitForChild("Crosshair") + local CrosshairIcon = Crosshair:WaitForChild("ImageLabel") + + return setmetatable({ + Crosshair = Crosshair, + CrosshairIcon = CrosshairIcon + }, CrosshairModule) +end + +function CrosshairModule:Enable() + self.Crosshair.Enabled = true +end + +function CrosshairModule:Disable() + self.Crosshair.Enabled = false +end + +function CrosshairModule:Change(ID: rbxassetid) + self.CrosshairIcon.Image = ID or CrosshairModule.Icon +end + +return CrosshairModule \ No newline at end of file diff --git a/src/client/Player/UI/Vignette.lua b/src/client/Player/UI/Vignette.lua new file mode 100644 index 0000000..95061ae --- /dev/null +++ b/src/client/Player/UI/Vignette.lua @@ -0,0 +1,26 @@ +local VignetteModule = { + Enabled = false +} +VignetteModule.__index = VignetteModule + +function VignetteModule.constructor(PlayerGui: PlayerGui) + local Vignette = PlayerGui:WaitForChild("Vignette") + local VignetteIcon = Vignette:WaitForChild("ImageLabel") + + return setmetatable({ + Vignette = Vignette, + VignetteIcon = VignetteIcon + }, VignetteModule) +end + +function VignetteModule:Enable() + VignetteModule.Enabled = true + self.Vignette.Enabled = true +end + +function VignetteModule:Disable() + VignetteModule.Enabled = false + self.Vignette.Enabled = false +end + +return VignetteModule \ No newline at end of file diff --git a/src/client/Player/init.client.lua b/src/client/Player/init.client.lua index 94e81ae..e79566f 100644 --- a/src/client/Player/init.client.lua +++ b/src/client/Player/init.client.lua @@ -1,7 +1,9 @@ -local CoreGuis = require(script:WaitForChild("CoreGuis")) -local Mouse = require(script:WaitForChild("Mouse")) -local CameraSettings = require(script:WaitForChild("Camera")) -local Crosshair = require(script:WaitForChild("Crosshair")) +local UI = script:WaitForChild("UI") +local Crosshair = require(UI:WaitForChild("Crosshair")) +local VignetteSettings = require(UI:WaitForChild("Vignette")) +local CoreGuis = require(script:WaitForChild("CoreGuis")) +local Mouse = require(script:WaitForChild("Mouse")) +local CameraSettings = require(script:WaitForChild("Camera")) local Players = game:GetService("Players") local Storage = game:GetService("ReplicatedStorage") @@ -10,30 +12,33 @@ local ClientStorage = Storage:WaitForChild("Client") local KeyBindsModule = require(ClientStorage:WaitForChild("KeyBinds")) local Player = Players.LocalPlayer +local PlayerGui = Player:WaitForChild("PlayerGui") + local CurrentCamera = nil repeat task.wait() CurrentCamera = workspace.CurrentCamera until CurrentCamera +local Vignette = VignetteSettings.constructor(PlayerGui) local Camera = CameraSettings.constructor(CurrentCamera, Player) -local CrosshairObject = Crosshair.constructor(Player) +local CrosshairObject = Crosshair.constructor(PlayerGui) --Keybinds local function CameraBinds() local CameraBindMap = KeyBindsModule.constructor() CameraBindMap:AddInputBegan(Enum.KeyCode.C, function() - Camera:ZoomIn() + Camera:ZoomIn(Vignette) end) CameraBindMap:AddInputEnded(Enum.KeyCode.C, function() - Camera:ZoomOut() + Camera:ZoomOut(Vignette) end) end CoreGuis:off() Mouse:DisablePointer() Camera:FirstPerson() -CrosshairObject:Spawn() +CrosshairObject:Enable() CameraBinds() \ No newline at end of file diff --git a/src/server/StudioEntities.server.lua b/src/server/StudioEntities.server.lua index c0e1fd0..8f95ecb 100644 --- a/src/server/StudioEntities.server.lua +++ b/src/server/StudioEntities.server.lua @@ -5,19 +5,22 @@ local EntityDebug = game:GetService("RunService"):IsStudio() local WorkspaceEnt = workspace:GetDescendants() -local function DisablePart(Part: BasePart) +local function HidePart(Part: BasePart) Part.Transparency = 1 Part.CanCollide = false Part.CastShadow = false end +local function HideBarrierCollision(Part: BasePart) + Part.Transparency = 1 + Part.CanCollide = true + Part.CastShadow = false +end + local SwitchEntities = { - ["LightSource"] = function(Part: BasePart) - DisablePart(Part) - end, - ["PulleyRopeContact"] = function(Part: BasePart) - DisablePart(Part) - end + ["LightSource"] = HidePart, + ["PulleyRopeContact"] = HidePart, + ["BarrierCollision"] = HideBarrierCollision } if not EntityDebug then diff --git a/src/shared/String.lua b/src/shared/String.lua new file mode 100644 index 0000000..c6801db --- /dev/null +++ b/src/shared/String.lua @@ -0,0 +1,20 @@ +local StringModule = {} +StringModule.__index = StringModule + +function StringModule.new(String: string) + return setmetatable({ + String = String + }, StringModule) +end + +type ByteArray = {string} + +function StringModule:bytes(): ByteArray + local cbytes = {self.String:byte(1,-1)} + for i = 1, #cbytes do + cbytes[i] = tostring(cbytes[i]):char() + end + return cbytes +end + +return StringModule \ No newline at end of file diff --git a/src/shared/Tween.lua b/src/shared/Tween.lua index 573c011..53f6167 100644 --- a/src/shared/Tween.lua +++ b/src/shared/Tween.lua @@ -5,7 +5,7 @@ local TS = game:GetService("TweenService") type TweenAnimation = {[string]: any} -function Tween.constructor(TweenSettings: TweenInfo | nil, Object: Instance | nil, PreProperties: TweenAnimation | nil) +function Tween.constructor(TweenSettings: TweenInfo?, Object: Instance?, PreProperties: TweenAnimation?) return setmetatable({ TweenInfo = TweenSettings, Instance = Object, @@ -13,7 +13,7 @@ function Tween.constructor(TweenSettings: TweenInfo | nil, Object: Instance | ni }, Tween) end -function Tween:Start(PostInstance: Instance | nil, PostProperties: TweenAnimation | nil, PostTweenSettings: TweenInfo | nil): Tween +function Tween:Start(PostInstance: Instance?, PostProperties: TweenAnimation?, PostTweenSettings: TweenInfo?): Tween local Props = self.PreProperties local Object = self.Instance local TweenSettings = self.TweenInfo