Hi,
I am trying to get into making classes because I feel like it is easier to create and manage efficiently.
I don’t know if I am doing this correctly so can someone tell me if this is how I make classes?
--!strict
--/ services
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
--/ directories
local Modules = ReplicatedStorage.Source.Modules
local Classes = ReplicatedStorage.Source.Classes
local Packages = ReplicatedStorage.Packages
--/ requires
local Spring = require(Modules.Spring)
local Trove = require(Packages.Trove)
local CharacterLoadedWrapper = require(Classes.CharacterLoadedWrapper)
--/ class
local Camera = {}
Camera.__index = Camera
type self = {
CamPart: Part,
Player: Player,
CameraAngle: CFrame,
XOFFSET: number,
YOFFSET: number,
ZOFFSET: number,
Damper: number,
Speed: number,
Spring: any,
Tracking: any,
Connections: any,
Camera: any,
CharacterLoadedWrapper: any,
Character: any
};
export type Camera = typeof( setmetatable({} :: self, Camera) )
function Camera.new(Player: Player): Camera
local self = setmetatable({} :: self, Camera)
self.Player = Player
self.Tracking = {Player} -- stores the players that the camera is tracking
self.Connections = Trove.new() -- stores connections such as runservice
self.Camera = workspace.CurrentCamera
-- customizable settings
self.CameraAngle = CFrame.Angles(math.rad(0), math.rad(0),math.rad(0))
self.XOFFSET = 0
self.YOFFSET = 3
self.ZOFFSET = 10
self.Damper = 100
self.Speed = 10
self.Spring = Spring.new(Vector3.new())
self.CamPart = Instance.new("Part")
self.CamPart.Anchored = true
self.CamPart.Name = "CamPart"
self.CamPart.Parent = workspace
self.CamPart.CanCollide = false
self.CamPart.Transparency = 1
self.Character = self.Player.CharacterAdded:Wait() or self.Player.Character
self.CharacterLoadedWrapper = CharacterLoadedWrapper.new(self.Player)
self.Camera.CameraType = Enum.CameraType.Scriptable
self.Connections:Connect(Players.PlayerRemoving, function(player: Player)
self.PlayerRemoving(self)
end)
return self
end
function Camera.calculateAveragePosition(self: Camera)
local Total = Vector3.new()
for _, Track in pairs(self.Tracking) do
if Track:IsA("Player") and Track.Character then
local Root = Track.Character:FindFirstChild("HumanoidRootPart").Position
Total += Root
end
if Track:IsA("Part") then
Total += Track.Position
end
end
return Total / #self.Tracking
end
function Camera.calculateAverageMagnitude(self: Camera)
local Total = 0
for _, Track in pairs(self.Tracking) do
if Track:IsA("Player") then
local Root = Track.Character:FindFirstChild("HumanoidRootPart")
Total += (Root.Position - self.CamPart.Position).Magnitude
end
if Track:IsA("Part") then
Total += (Track.Position - self.CamPart.Position).Magnitude
end
end
return Total / #self.Tracking
end
function Camera.Update(self: Camera): ()
if not self.CharacterLoadedWrapper:isLoaded() then
self.CharacterLoadedWrapper.loaded:Wait()
end
for _, player in Players:GetPlayers() do
if not table.find(self.Tracking, player) then
table.insert(self.Tracking, player)
end
end
local Root = self.Character["HumnaoidRootPart"]
local AveragePos = self:calculateAveragePosition()
local AverageMagnitude = self:calculateAverageMagnitude() + self.ZOFFSET or self.ZOFFSET
local StartCF =
CFrame.new((Root.CFrame.Position))
* CFrame.Angles(0,math.rad(self.XOFFSET),0)
* CFrame.Angles(math.rad(self.YOFFSET),0,0)
local GoalCF = StartCF:ToWorldSpace(
CFrame.new(self.XOFFSET,self.YOFFSET , AverageMagnitude))
local CameraDirection = StartCF:ToWorldSpace(
CFrame.new(self.XOFFSET, self.YOFFSET, -10000))
* CFrame.new(self.CamPart.Position)
local CameraCF = CFrame.new(self.Spring.Position, CameraDirection.Position) * self.CameraAngle
self.Spring.Target = GoalCF.Position
self.CamPart.Position = AveragePos
self.Camera.CFrame = CameraCF
end
function Camera.PlayerRemoving(self: Camera)
Players.PlayerRemoving:Connect(function(player: Player)
if table.find(self.Tracking, player) then
for i = 1, #self.Tracking do
if self.Tracking[i] == player then
table.remove(self.Tracking, i)
end
end
end
end)
end
return Camera