Big client character refactor

This commit is contained in:
2024-04-21 15:04:12 -04:00
parent 36625162a1
commit 65e4b7eef2
9 changed files with 152 additions and 110 deletions

View File

@@ -41,6 +41,8 @@ type Constructor_Return_Props = {
ActionsTCP: TCP ActionsTCP: TCP
} }
export type ActionsConstructor = ClassConstructor
local Actions = {} :: Impl_Constructor local Actions = {} :: Impl_Constructor
Actions.__index = Actions Actions.__index = Actions
@@ -116,7 +118,7 @@ function Actions:DisableCrouch()
}, Easing) }, Easing)
end end
function Actions:EnableFlashlight(FlashlightKey: Enum.KeyCode) function Actions:EnableFlashlight(FlashlightKey)
Actions.FlashlightEnabled = true Actions.FlashlightEnabled = true
task.spawn(function() task.spawn(function()
@@ -133,12 +135,12 @@ function Actions:EnableFlashlight(FlashlightKey: Enum.KeyCode)
self.ActionsTCP:FireServer(FlashlightKey) self.ActionsTCP:FireServer(FlashlightKey)
end end
function Actions:DisableFlashlight(FlashlightKey: Enum.KeyCode) function Actions:DisableFlashlight(FlashlightKey)
self.ActionsTCP:FireServer(FlashlightKey) self.ActionsTCP:FireServer(FlashlightKey)
Actions.FlashlightEnabled = false Actions.FlashlightEnabled = false
end end
function Actions:ToggleFlashlight(FlashlightKey: Enum.KeyCode) function Actions:ToggleFlashlight(FlashlightKey)
if Actions.FlashlightEnabled then if Actions.FlashlightEnabled then
self:DisableFlashlight(FlashlightKey) self:DisableFlashlight(FlashlightKey)
else else

View File

@@ -40,11 +40,16 @@ type Constructor_Return_Props = {
Humanoid: Humanoid Humanoid: Humanoid
} }
export type BobbingConstructor = Impl_Constructor export type BobbingConstructor = ClassConstructor
local Bobbing = {} :: Impl_Constructor local Bobbing = {} :: Impl_Constructor
Bobbing.__index = Bobbing Bobbing.__index = Bobbing
local UIS = game:GetService("UserInputService")
local RS = game:GetService("ReplicatedStorage")
local Algebra = require(RS:WaitForChild("Algebra"))
Bobbing.TurnAlpha = 0.050 Bobbing.TurnAlpha = 0.050
Bobbing.LeanMultiplier = 1.7 Bobbing.LeanMultiplier = 1.7
Bobbing.SwayMultiplier = 1.5 Bobbing.SwayMultiplier = 1.5
@@ -56,8 +61,6 @@ Bobbing.ForceStop = false
local Animations = {} :: AnimationsMap local Animations = {} :: AnimationsMap
local UIS = game:GetService("UserInputService")
local CN = CFrame.new local CN = CFrame.new
local ANG = CFrame.Angles local ANG = CFrame.Angles
local CameraLean = CN() local CameraLean = CN()
@@ -100,10 +103,6 @@ function Animations.Falling()
return ANG(0,0,0) return ANG(0,0,0)
end 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 function Camera_YArc(Camera: Camera): EulerValue --stop Euler gimbal lock when you're looking directly up or down
local EulerY,_,_ = Camera.CFrame.Rotation:ToEulerAnglesYXZ() local EulerY,_,_ = Camera.CFrame.Rotation:ToEulerAnglesYXZ()
return math.abs(math.deg(EulerY)) return math.abs(math.deg(EulerY))
@@ -126,7 +125,7 @@ local function CameraAnimation(self: ClassConstructor, dt: deltatime)
return Animation:Lerp(CurrentAnimation, Bobbing.AnimationAlpha) return Animation:Lerp(CurrentAnimation, Bobbing.AnimationAlpha)
end end
function Bobbing:Frame(dt: number) function Bobbing:Frame(dt)
local Camera = self.CurrentCamera local Camera = self.CurrentCamera
local Humanoid = self.Humanoid local Humanoid = self.Humanoid
@@ -139,7 +138,7 @@ function Bobbing:Frame(dt: number)
--Jump?! --Jump?!
--local LeanDegree_Pitch = -CameraCF.UpVector:Dot(Humanoid.MoveDirection)*Bobbing.LeanMultiplier --local LeanDegree_Pitch = -CameraCF.UpVector:Dot(Humanoid.MoveDirection)*Bobbing.LeanMultiplier
local LeanMult_Roll = maxmin(-Bobbing.SwayMultiplier, LeanDegree_Roll-MouseDelta.X, Bobbing.SwayMultiplier) local LeanMult_Roll = Algebra.maxmin(-Bobbing.SwayMultiplier, LeanDegree_Roll-MouseDelta.X, Bobbing.SwayMultiplier)
CameraLean = CameraLean:Lerp(ANG(0, 0, math.rad(LeanMult_Roll)), Bobbing.TurnAlpha) CameraLean = CameraLean:Lerp(ANG(0, 0, math.rad(LeanMult_Roll)), Bobbing.TurnAlpha)
Camera.CFrame *= Animation*CameraLean Camera.CFrame *= Animation*CameraLean

View File

@@ -4,10 +4,8 @@
local Bobbing = require(script:WaitForChild("Bobbing")) local Bobbing = require(script:WaitForChild("Bobbing"))
type FakeCamera = BasePart
type CurrentCamera = Camera type CurrentCamera = Camera
type HumanoidRootPart = BasePart type HumanoidRootPart = BasePart
type Module = any
type ClassConstructor = typeof(setmetatable({} :: Constructor_Return_Props, {} :: Impl_Constructor)) type ClassConstructor = typeof(setmetatable({} :: Constructor_Return_Props, {} :: Impl_Constructor))
type Impl_Constructor = { type Impl_Constructor = {
@@ -26,13 +24,15 @@ type Constructor_Return_Props = {
BobbingCamera: Bobbing.BobbingConstructor BobbingCamera: Bobbing.BobbingConstructor
} }
export type CameraConstructor = ClassConstructor
local Camera = {} :: Impl_Constructor local Camera = {} :: Impl_Constructor
Camera.__index = Camera Camera.__index = Camera
local RS = game:GetService("RunService") local RS = game:GetService("RunService")
function Camera.constructor(CurrentCamera: CurrentCamera, HumanoidRootPart: HumanoidRootPart, Humanoid: Humanoid) function Camera.constructor(CurrentCamera: CurrentCamera, HumanoidRootPart: HumanoidRootPart, Humanoid: Humanoid)
local self = {} local self = {} :: Constructor_Return_Props
self.CameraFPS = false self.CameraFPS = false
self.CurrentCamera = CurrentCamera self.CurrentCamera = CurrentCamera
self.HumanoidRootPart = HumanoidRootPart self.HumanoidRootPart = HumanoidRootPart

View File

@@ -22,20 +22,22 @@ type Constructor_Return_Props = {
Humanoid: Humanoid Humanoid: Humanoid
} }
export type HumanoidConstructor = ClassConstructor
local HumanoidModule = {} :: Impl_Constructor local HumanoidModule = {} :: Impl_Constructor
HumanoidModule.__index = HumanoidModule HumanoidModule.__index = HumanoidModule
function HumanoidModule.constructor(Humanoid: Humanoid) function HumanoidModule.constructor(Humanoid)
return setmetatable({ return setmetatable({
Humanoid = Humanoid Humanoid = Humanoid
}, HumanoidModule) }, HumanoidModule)
end end
function HumanoidModule:SetWalkSpeed(Speed: WalkSpeed) function HumanoidModule:SetWalkSpeed(Speed)
self.Humanoid.WalkSpeed = Speed or 10 self.Humanoid.WalkSpeed = Speed or 10
end end
function HumanoidModule:SetJumpHeight(Height: JumpHeight) function HumanoidModule:SetJumpHeight(Height)
self.Humanoid.JumpHeight = Height or 7.2 self.Humanoid.JumpHeight = Height or 7.2
end end

View File

@@ -18,6 +18,8 @@ type Constructor_Return_Props = {
HumanoidRootPart: HumanoidRootPart HumanoidRootPart: HumanoidRootPart
} }
export type HumanoidRPSettingsConstructor = ClassConstructor
local HumanoidRPSettings = {} :: Impl_Constructor local HumanoidRPSettings = {} :: Impl_Constructor
HumanoidRPSettings.__index = HumanoidRPSettings HumanoidRPSettings.__index = HumanoidRPSettings

View File

@@ -4,6 +4,7 @@
type UDP = UnreliableRemoteEvent type UDP = UnreliableRemoteEvent
type CurrentCamera = Camera type CurrentCamera = Camera
type CharacterShared = Folder
type ClassConstructor = typeof(setmetatable({} :: Constructor_Return_Props, {} :: Impl_Constructor)) type ClassConstructor = typeof(setmetatable({} :: Constructor_Return_Props, {} :: Impl_Constructor))
type Impl_Constructor = { type Impl_Constructor = {
@@ -14,7 +15,7 @@ type Impl_Constructor = {
Disable: (self: ClassConstructor) -> () Disable: (self: ClassConstructor) -> ()
} & Impl_Static_Props } & Impl_Static_Props
type Constructor_Fun = (CurrentCamera: CurrentCamera) -> ClassConstructor type Constructor_Fun = (CharacterShared: CharacterShared, CurrentCamera: CurrentCamera) -> ClassConstructor
type Impl_Static_Props = { type Impl_Static_Props = {
Running: boolean Running: boolean
} }
@@ -23,6 +24,8 @@ type Constructor_Return_Props = {
CurrentCamera: CurrentCamera CurrentCamera: CurrentCamera
} }
export type SpineConstructor = ClassConstructor
local Spine = {} :: Impl_Constructor local Spine = {} :: Impl_Constructor
Spine.__index = Spine Spine.__index = Spine
@@ -30,16 +33,14 @@ Spine.Running = false
local Storage = game:GetService("ReplicatedStorage") local Storage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players") local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Delta = require(Storage:WaitForChild("Delta")) local Delta = require(Storage:WaitForChild("Delta"))
local Player = Players.LocalPlayer function Spine.constructor(CharacterShared, CurrentCamera)
local CharacterShared = _G.include(script, "CharacterShared")
function Spine.constructor(CurrentCamera: CurrentCamera)
return setmetatable({ return setmetatable({
Remote = CharacterShared:WaitForChild("SpineStream"), Remote = CharacterShared:WaitForChild("SpineStream") :: UDP,
CurrentCamera = CurrentCamera CurrentCamera = CurrentCamera :: CurrentCamera
}, Spine) }, Spine)
end end

View File

@@ -2,62 +2,86 @@
--!native --!native
--!strict --!strict
type CharacterSharedFolder = Folder
type Character = Model
type TCP = RemoteEvent
type include<T> = (this: LuaSourceContainer, FunName: string, ...T) -> T
local CharacterModule = {}
CharacterModule.__index = CharacterModule
local RS = game:GetService("RunService") local RS = game:GetService("RunService")
local Storage = game:GetService("ReplicatedStorage") local Storage = game:GetService("ReplicatedStorage")
local ClientStorage = Storage:WaitForChild("Client") :: Folder local ClientStorage = Storage:WaitForChild("Client")
local BindModule = require(ClientStorage:WaitForChild("KeyBinds"))
local function client_preprocessor<T>(Character: Character): (include<T>, CharacterSharedFolder)
local preprocessor = {}
local CharacterShared = Character:WaitForChild("shared") :: CharacterSharedFolder
function preprocessor.CharacterShared(): CharacterSharedFolder
return CharacterShared
end
_G.include = function<T>(this: LuaSourceContainer, FunName: string, ...: T)
if this:IsDescendantOf(script) then --getfenv is being removed
local switch = preprocessor[FunName]
return type(switch) == "function" and switch(...) or switch
else
warn(`Preprocessor append failed "{FunName}"`, debug.traceback())
return nil
end
end
return _G.include, CharacterShared
end
function CharacterModule.constructor(Character)
local _, CharacterShared = client_preprocessor(Character)
local HumanoidRPSettings = require(script:WaitForChild("HumanoidRootPart")) local HumanoidRPSettings = require(script:WaitForChild("HumanoidRootPart"))
local CameraModule = require(script:WaitForChild("Camera")) local CameraModule = require(script:WaitForChild("Camera"))
local HumanoidModule = require(script:WaitForChild("Humanoid")) local HumanoidModule = require(script:WaitForChild("Humanoid"))
local SpineModule = require(script:WaitForChild("SpineKinematics")) local SpineModule = require(script:WaitForChild("SpineKinematics"))
local ActionsModule = require(script:WaitForChild("Actions"))
local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart") type Character = Model
local Humanoid = Character:WaitForChild("Humanoid") type HumanoidRootPart = BasePart
type TCP = RemoteEvent
type CurrentCamera = Camera
local self = {} type ClassConstructor = typeof(setmetatable({} :: Constructor_Return_Props, {} :: Impl_Constructor))
self.ActionsTCP = CharacterShared:WaitForChild("Actions") type Impl_Constructor = {
self.ActionsModule = require(script:WaitForChild("Actions")) __index: Impl_Constructor,
self.BindModule = require(ClientStorage:WaitForChild("KeyBinds")) constructor: Constructor_Fun,
--Class functions
CharacterKeyBinds: (self: ClassConstructor) -> (),
Crosshair: (self: ClassConstructor) -> RBXScriptConnection,
SetWalkSpeed: (self: ClassConstructor) -> (),
SetJumpHeight: (self: ClassConstructor) -> (),
DisableRobloxSounds: (self: ClassConstructor) -> (),
EnableCameraBobbing: (self: ClassConstructor) -> (),
EnableSpineMovement: (self: ClassConstructor) -> ()
} & Impl_Static_Props
type Impl_Static_Props = {
KeyBinds: {
Crouch: {Enum.KeyCode},
Walk: {Enum.KeyCode},
Flashlight: {Enum.KeyCode}
}
}
type Constructor_Fun = (Character: Character) -> ClassConstructor
type Constructor_Return_Props = {
ActionsTCP: TCP,
CurrentCamera: CurrentCamera,
HRPSettings: HumanoidRPSettings.HumanoidRPSettingsConstructor,
CameraConsturctor: CameraModule.CameraConstructor,
HumanoidSettings: HumanoidModule.HumanoidConstructor,
SpineMovement: SpineModule.SpineConstructor
}
local CharacterModule = {} :: Impl_Constructor
CharacterModule.__index = CharacterModule
CharacterModule.KeyBinds = {
Crouch = {
Enum.KeyCode.RightControl,
Enum.KeyCode.LeftControl
},
Walk = {
Enum.KeyCode.LeftAlt,
Enum.KeyCode.RightAlt,
Enum.KeyCode.LeftShift,
Enum.KeyCode.RightShift
},
Flashlight = {
Enum.KeyCode.F
}
}
function CharacterModule.constructor(Character)
local CharacterShared = Character:WaitForChild("shared") :: Folder
local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart") :: HumanoidRootPart
local Humanoid = Character:WaitForChild("Humanoid") :: Humanoid
local self = {} :: Constructor_Return_Props
self.CurrentCamera = workspace.CurrentCamera self.CurrentCamera = workspace.CurrentCamera
self.ActionsTCP = CharacterShared:WaitForChild("Actions") :: TCP
self.HRPSettings = HumanoidRPSettings.constructor(HumanoidRootPart) self.HRPSettings = HumanoidRPSettings.constructor(HumanoidRootPart)
self.CameraConsturctor = CameraModule.constructor(self.CurrentCamera, HumanoidRootPart, Humanoid) self.CameraConsturctor = CameraModule.constructor(self.CurrentCamera, HumanoidRootPart, Humanoid)
self.HumanoidSettings = HumanoidModule.constructor(Humanoid) self.HumanoidSettings = HumanoidModule.constructor(Humanoid)
self.SpineMovement = SpineModule.constructor(self.CurrentCamera) self.SpineMovement = SpineModule.constructor(CharacterShared, self.CurrentCamera)
pcall(table.clear, _G) pcall(table.clear, _G)
pcall(table.freeze, _G) pcall(table.freeze, _G)
@@ -68,37 +92,27 @@ function CharacterModule.constructor(Character)
end end
function CharacterModule:CharacterKeyBinds() function CharacterModule:CharacterKeyBinds()
local ClientBindMap = self.BindModule.constructor(false) local ClientBindMap = BindModule.constructor(false)
local Actions = self.ActionsModule.constructor(self.HumanoidSettings, self.CurrentCamera, self.ActionsTCP) local Actions = ActionsModule.constructor(self.HumanoidSettings, self.CurrentCamera, self.ActionsTCP)
--Crouch --Crouch
ClientBindMap:AddInputBegan({Enum.KeyCode.RightControl, Enum.KeyCode.LeftControl}, function(_KeyPressed) ClientBindMap:AddInputBegan(CharacterModule.KeyBinds.Crouch, function(_KeyPressed)
Actions:EnableCrouch() Actions:EnableCrouch()
end) end)
ClientBindMap:AddInputEnded({Enum.KeyCode.RightControl, Enum.KeyCode.LeftControl}, function(_KeyPressed) ClientBindMap:AddInputEnded(CharacterModule.KeyBinds.Crouch, function(_KeyPressed)
Actions:DisableCrouch() Actions:DisableCrouch()
end) end)
--Walk --Walk
ClientBindMap:AddInputBegan({ ClientBindMap:AddInputBegan(CharacterModule.KeyBinds.Walk, function(_KeyPressed)
Enum.KeyCode.LeftAlt,
Enum.KeyCode.RightAlt,
Enum.KeyCode.LeftShift,
Enum.KeyCode.RightShift
}, function(_KeyPressed)
Actions:EnableSneak() Actions:EnableSneak()
end) end)
ClientBindMap:AddInputEnded({ ClientBindMap:AddInputEnded(CharacterModule.KeyBinds.Walk, function(_KeyPressed)
Enum.KeyCode.LeftAlt,
Enum.KeyCode.RightAlt,
Enum.KeyCode.LeftShift,
Enum.KeyCode.RightShift
}, function(_KeyPressed)
Actions:DisableSneak() Actions:DisableSneak()
end) end)
--Flashlight --Flashlight
ClientBindMap:AddInputBegan({Enum.KeyCode.F}, function(KeyPressed: Enum.KeyCode) ClientBindMap:AddInputBegan(CharacterModule.KeyBinds.Flashlight, function(KeyPressed: Enum.KeyCode)
Actions:ToggleFlashlight(KeyPressed) Actions:ToggleFlashlight(KeyPressed)
end) end)
end end

View File

@@ -28,11 +28,16 @@ export type Math = {
OutBounce: EaseFunction, OutBounce: EaseFunction,
InQuad: EaseFunction, InQuad: EaseFunction,
RotationMatrix: (X: number, Y: number, Z: number) -> RotationMatrix, RotationMatrix: (X: number, Y: number, Z: number) -> RotationMatrix,
Scalar: (X1: number, Y1: number, X2: number, Y2: number) -> Scalar Scalar: (X1: number, Y1: number, X2: number, Y2: number) -> Scalar,
maxmin: (min: number, n: number, max: number) -> number
} }
local Math = {} :: Math local Math = {} :: Math
function Math.maxmin(min, n, max)
return math.max(min, math.min(n, max))
end
function Math.RotationMatrix(X: number, Y: number, Z: number): RotationMatrix function Math.RotationMatrix(X: number, Y: number, Z: number): RotationMatrix
return { return {
Ixx = math.cos(Z)*math.cos(X)-math.sin(Z)*math.sin(X)*math.sin(Y); Ixx = math.cos(Z)*math.cos(X)-math.sin(Z)*math.sin(X)*math.sin(Y);

View File

@@ -2,34 +2,51 @@
--!native --!native
--!strict --!strict
--I couldn't get ContextActionService to work how i wanted it to --Couldn't get ContextActionService to work how i wanted
local BindLink = {} type ClassConstructor = typeof(setmetatable({} :: Constructor_Return_Props, {} :: Impl_Constructor))
BindLink.__index = BindLink type Impl_Constructor = {
__index: Impl_Constructor,
constructor: Constructor_Fun,
--Class functions
CharacterKeyBinds: (self: ClassConstructor) -> (),
AddInputBegan: (self: ClassConstructor, Keys: {Enum.KeyCode}, Callback: CallbackFunction) -> (),
AddInputEnded: (self: ClassConstructor, Keys: {Enum.KeyCode}, Callback: CallbackFunction) -> (),
KeyHold: (self: ClassConstructor, Key: Enum.KeyCode) -> boolean
}
type Constructor_Fun = (gameProcessing: boolean) -> ClassConstructor
type Constructor_Return_Props = {
BindMap: KeyBindMap,
InputBegan: InputBegan,
InputEnded: InputEnded
}
type CallbackFunction = (KeyPressed: Enum.KeyCode) -> ()
export type KeyBindMap = { export type KeyBindMap = {
[string]: { [string]: {
[Enum.KeyCode]: (KeyPressed: Enum.KeyCode) -> () [Enum.KeyCode]: (KeyPressed: Enum.KeyCode) -> ()
} }
} }
type BindConstructor = {
BindMap: KeyBindMap,
InputBegan: InputBegan,
InputEnded: InputEnded
}
export type InputBegan = RBXScriptConnection export type InputBegan = RBXScriptConnection
export type InputEnded = RBXScriptConnection export type InputEnded = RBXScriptConnection
type CallbackFunction = (KeyPressed: Enum.KeyCode) -> ()
export type KeyBindsConstructor = ClassConstructor
local BindLink = {} :: Impl_Constructor
BindLink.__index = BindLink
local UIS = game:GetService("UserInputService") local UIS = game:GetService("UserInputService")
function BindLink.constructor(gameProcessing: boolean) --Allow multiple bindings of the same keys, no overwrites function BindLink.constructor(gameProcessing: boolean) --Allow multiple bindings of the same keys, no overwrites
local self = {} :: BindConstructor local self = {} :: Constructor_Return_Props
self.BindMap = { self.BindMap = {
Began = {}, Began = {},
Ended = {} Ended = {}
} }
--Return these for convenience --Return these for convenience
self.InputBegan = UIS.InputBegan:Connect(function(input, gameProcessedEvent) self.InputBegan = UIS.InputBegan:Connect(function(input, gameProcessedEvent)
if gameProcessing and gameProcessedEvent or not gameProcessedEvent then if gameProcessing and gameProcessedEvent or not gameProcessedEvent then
@@ -55,9 +72,9 @@ function BindLink.constructor(gameProcessing: boolean) --Allow multiple bindings
return setmetatable(self, BindLink) return setmetatable(self, BindLink)
end end
function BindLink:AddInputBegan(Keys: {Enum.KeyCode}, Callback: CallbackFunction) function BindLink:AddInputBegan(Keys, Callback)
for i = 1, #Keys do for n: number = 1, #Keys do
local Key = Keys[i] local Key = Keys[n]
if self.BindMap.Began[Key] then if self.BindMap.Began[Key] then
warn(`Key >began< "{Key.Name}" is already binded on this KeyBind map`, debug.traceback()) warn(`Key >began< "{Key.Name}" is already binded on this KeyBind map`, debug.traceback())
end end
@@ -65,9 +82,9 @@ function BindLink:AddInputBegan(Keys: {Enum.KeyCode}, Callback: CallbackFunction
end end
end end
function BindLink:AddInputEnded(Keys: {Enum.KeyCode}, Callback: CallbackFunction) function BindLink:AddInputEnded(Keys, Callback)
for i = 1, #Keys do for n: number = 1, #Keys do
local Key = Keys[i] local Key = Keys[n]
if self.BindMap.Ended[Key] then if self.BindMap.Ended[Key] then
warn(`Key >ended< "{Key.Name}" is already binded on this KeyBind map`, debug.traceback()) warn(`Key >ended< "{Key.Name}" is already binded on this KeyBind map`, debug.traceback())
end end
@@ -75,7 +92,7 @@ function BindLink:AddInputEnded(Keys: {Enum.KeyCode}, Callback: CallbackFunction
end end
end end
function BindLink:KeyHold(Key: Enum.KeyCode): boolean function BindLink:KeyHold(Key)
return UIS:IsKeyDown(Key) return UIS:IsKeyDown(Key)
end end