Heya Everyone!!
I’m working on an entity script and all I’m looking for is what I can do to improve the entity system such as readability, better practices, and so on. I’d like to also mention that self.EntityBehaviors part will be separated to a data ModuleScript for better maintenance.
--[[SERVICES]]--
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local PathfindingService = game:GetService("PathfindingService")
local RunService = game:GetService("RunService")
--[[FOLDERS]]--
local EntityFolder = ServerStorage:WaitForChild("Entities")
local RegularFolder = EntityFolder.Regular
local SpecialFolder = EntityFolder.Special
--[[MODULE]]--
local BaseEntity = {}
BaseEntity.__index = BaseEntity
--//Creating the entity
function BaseEntity:CreateEntity(EntityName)
--//Finding entity
local RequestedEntity = RegularFolder:FindFirstChild(EntityName) if not EntityName then
RequestedEntity = SpecialFolder:FindFirstChild(EntityName) if not EntityName then
warn("CANNOT FIND ENTITY: "..EntityName)
return
end
end
--//Creating entity
local self = setmetatable({}, BaseEntity)
self.Entity = RequestedEntity:Clone()
self.Humanoid = self.Entity:FindFirstChildWhichIsA("Humanoid")
self.EntitySettings = require(self.Entity.EntitySettings)
self.Entity.Parent = game.Workspace
--//List of entity behaviors & assinging them to their respective entity.
--//EntityBehaviors will be in a seperate module for better maintenance.
self.EntityBehaviors = {
["Starvlud"] = {
["Behavior"] = function()
self:SearchAndChaseTarget()
self:Wander()
end,
}
}
task.wait(2)
self.EntityBehaviors.Starvlud.Behavior()
return self
end
--//Default functions
function BaseEntity:Wander()
self.Humanoid.WalkSpeed = self.EntitySettings.WanderingSpeed
local NewPath = PathfindingService:CreatePath()
while task.wait() do
if self.EntitySettings.IsChasing then return end
--//Getting random walkpoints. This might be bad practice.
local Walkpoints = workspace:WaitForChild("Walkpoints"):GetChildren()
local RandomWalkPoint = Walkpoints[math.random(1,#Walkpoints)]
NewPath:ComputeAsync(self.Entity.PrimaryPart.Position, RandomWalkPoint.Position)
if NewPath.Status == Enum.PathStatus.Success then
local Waypoints = NewPath:GetWaypoints()
for _, Waypoint in pairs(Waypoints) do
if self.EntitySettings.IsChasing then
break
end
self.Humanoid:MoveTo(Waypoint.Position)
local Timeout = self.Humanoid.MoveToFinished:Wait(2)
if not Timeout then
warn("Entity got stuck on something. Repathfinding.")
self:Wander()
end
end
end
end
end
function BaseEntity:InvestigateNoise()
--//TBA
end
function BaseEntity:SearchAndChaseTarget()
local Target = nil
local NewPath = PathfindingService:CreatePath()
RunService.Heartbeat:Connect(function()
if not self.EntitySettings.IsChasing then
local SightDirection = self.Entity.PrimaryPart.CFrame.LookVector
local Raycast = workspace:Raycast(self.Entity.PrimaryPart.Position, SightDirection * self.EntitySettings.SightLength)
if not Raycast then return end --//Little check to see if the raycast hit anything.
local RaycastInstance = Raycast.Instance
if RaycastInstance then
self.EntitySettings.IsChasing = true
self.Humanoid.WalkSpeed = self.EntitySettings.ChasingSpeed
Target = Raycast.Instance.Parent
end
else
--//Creating a thread for the ChaseDuration
local Coro = coroutine.create(function()
local Timer = self.EntitySettings.ChaseDuration
repeat
Timer -= 1
task.wait(0.5)
until Timer <= 1
self.EntitySettings.IsChasing = false
self.Humanoid.WalkSpeed = self.EntitySettings.WanderingSpeed
end)
coroutine.resume(Coro)
--//Pathfinding
NewPath:ComputeAsync(self.Entity.PrimaryPart.Position, Target.PrimaryPart.Position)
if NewPath.Status == Enum.PathStatus.Success then
local Waypoints = NewPath:GetWaypoints()
for i, Waypoint in pairs(Waypoints) do
if i <= 2 then continue end
if Waypoints[4] then
if not self.EntitySettings.IsChasing then
break
end
self.Humanoid:MoveTo(Waypoints[4].Position)
local Timeout = self.Humanoid.MoveToFinished:Wait(2)
if not Timeout then
warn("Entity got stuck on something. Repathfinding.")
self:SearchAndChaseTarget()
end
end
end
end
end
end)
end
function BaseEntity:TryJumpscare()
--//TBA
end
return BaseEntity