hello chat,
i have recently came up with the idea to port some of my code to use self
(bad idea),
but you see, i have encountered an issue
i do not know what self is, i mean, i do know what it is,
all the popular posts do not really show me how i could take use of it in pathfinding, for example
so i figured i might aswell just make a post asking for help
i wanna make the pathfinding vary depending on enemy behavior (Which is a number inside a third-party module script) and depending on enemy ranged state (boolean)
but uhmmmmm, i don’t know how!
i guess i’ll drop the code to give you an idea of what i’m supposed to do
(please tell me what to do )
the pathfinding module:
local sScriptService = game:GetService("ServerScriptService")
local pfService = game:GetService("PathfindingService")
local dService = game:GetService("Debris")
-- Path to modules;
local enemies = sScriptService:WaitForChild("Enemies")
-- Modules;
local enemyStats = require(enemies.EnemyStats)
-- Path parameters!!
local pathParameters = {
AgentRadius = 2,
AgentHeight = 2,
AgentCanJump = true,
AgentCanClimb = false
}
-- Functions;
function VisualizePath(waypoint: PathWaypoint)
local pathVisualizer = Instance.new("Part")
pathVisualizer.Shape = Enum.PartType.Ball
pathVisualizer.Parent = workspace
pathVisualizer.Position = waypoint.Position
pathVisualizer.Color = Color3.fromRGB(255,255,255)
pathVisualizer.Material = Enum.Material.Neon
pathVisualizer.Size = Vector3.new(2,2,2)
pathVisualizer.CanCollide = false
pathVisualizer.Anchored = true
dService:AddItem(pathVisualizer, 2)
end
function RandomWander(part: BasePart)
local minBound = part.Position - part.Size / 2
local maxBound = part.Position + part.Size / 2
-- Calculate bounds;
local minX = part.Position.X - part.Size.X / 2
local maxX = part.Position.X + part.Size.X / 2
local minZ = part.Position.Z - part.Size.Z / 2
local maxZ = part.Position.Z + part.Size.Z / 2
-- Randomize positions;
local randomX = math.random() * (maxX - minX) + minX
local randomZ = math.random() * (maxZ - minZ) + minZ
local fixedY = part.Position.Y
return Vector3.new(randomX, fixedY, randomZ)
end
function CreatePath(startPos: Vector3, targetPos: Vector3)
local path: Path = pfService:CreatePath(pathParameters)
local success, result = pcall(function()
path:ComputeAsync(startPos, targetPos)
end)
local waypoints = path:GetWaypoints()
if path.Status == Enum.PathStatus.Success and #waypoints > 0 then
return waypoints
end
end
function MoveTo(waypoints, humanoid: Humanoid)
for i = 1, #waypoints do
local waypoint: PathWaypoint = waypoints[i]
if waypoint.Action == Enum.PathWaypointAction.Jump then
humanoid.Jump = true
end
VisualizePath(waypoint)
humanoid:MoveTo(waypoint.Position)
humanoid.MoveToFinished:Wait()
end
end
-- Runtime;
local pathfinding = {}
function pathfinding.Wander(humanoid: Humanoid) -- Generates a random position and pathfinds to it (if player is not in LoS)
local char: Model = humanoid.Parent
local humanoidRootPart: BasePart = char:FindFirstChild("HumanoidRootPart")
local detectionPart: BasePart = char:FindFirstChild("DetectionPart")
local startPos = humanoidRootPart.Position
local targetPos = RandomWander(detectionPart)
char:SetAttribute("Wandering", true)
local waypoints = CreatePath(startPos, targetPos)
if not waypoints then
char:SetAttribute("Wandering", false)
return
end
humanoid.WalkSpeed = enemyStats[char.Name]["WANDER_SPEED"]
MoveTo(waypoints, humanoid)
local cooldown = math.random(5,10)
char:SetAttribute("Wandering", false)
char:SetAttribute("WanderCooldown", true)
task.wait(cooldown)
char:SetAttribute("WanderCooldown", false)
end
function pathfinding.Chase(Humanoid, targetPosition) -- Chase the player;
if not Humanoid then return end
if not targetPosition then return end
local pfModifier = Instance.new("PathfindingModifier")
pfModifier.PassThrough = false
pfModifier.Parent = Humanoid.Parent.CollisionGroupPart
local path: Path = pfService:CreatePath(pathParameters)
local humanoidRootPart = Humanoid.Parent:FindFirstChild("HumanoidRootPart")
local startPosition = humanoidRootPart.Position
local success, errorMessage = pcall(function()
path:ComputeAsync(startPosition, targetPosition)
end)
if not success then
warn("Pathfinding failed: " .. errorMessage)
return
end
local waypoints = path:GetWaypoints()
if path.Status == Enum.PathStatus.Success and #waypoints > 0 then
Humanoid.WalkSpeed = enemyStats[Humanoid.Parent.Name]["CHASE_SPEED"]
for i = 2, #waypoints do
local waypoint = waypoints[i]
if waypoint.Action == Enum.PathWaypointAction.Jump then
Humanoid.Jump = true
end
VisualizePath(waypoint)
Humanoid:MoveTo(waypoint.Position)
local moveFinished = Humanoid.MoveToFinished:Wait()
pfModifier:Destroy()
end
Humanoid.Parent:SetAttribute("Chasing", false)
return path
end
end
return pathfinding
as you can see, self
is not used anywhere because idk how to use it
enemy stats module (only 1 enemy D:)
-- Atlas of behaviors;
-- 0: Passive-Aggressive (will run from the player on low health)
-- 1: Aggressive (will attack regardless of health)
-- Atlas of death events;
-- 0: None
-- 1: Explosion
-- 2: Buff enemies in a specified radius
local enemyStats = {
Shambler = {
CHASE_SPEED = 14,
WANDER_SPEED = 8,
HEALTH = 80,
SIPHON = 15,
COMBO_DAMAGE = 14,
HEAVY_DAMAGE = 28,
RANGED = false,
COMBO_FIRST_SWING = 0.200,
COMBO_SECOND_SWING = 0.650,
COMBO_THIRD_SWING = 0.700,
COMBO_FINISH = 0.250,
HEAVY_SWING = 1.050,
HEAVY_FINISH = 0.150,
DEATH_EVENT = 0,
BEHAVIOR = 1
},
}
return enemyStats