I seem to be having issues with this code. It’s just not working the expected way, and I’ve tried multiple different ways.
What it’s basically suppose to do is:
- Start off by roaming (gets a random point within the monsters zone)
- Move to that random point
- if at any time a player is detected within it’s range, start moving to that player, and keep checking if the player is in range
- if a player is not detected, resume to roaming
- if the monster is at anytime within the damage range of the monster, it should attack (as long as the monsters target it a player)
Note: I am using this pathfinding module: Getting Started - SimplePath
Current code:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local PathfindingService = game:GetService("PathfindingService")
local Knit = require(ReplicatedStorage.Packages.knit)
local Component = require(ReplicatedStorage.Packages.component)
local ZonesComponent = require(ServerScriptService.Components.Zones)
local SimplePath = require(ReplicatedStorage.Packages.SimplePath)
local Monster = Component.new({ Tag = "Monster" })
function Monster:Construct()
self.status = ""
self.playerDetectionRange = 25
self.playerDamageRange = 3
self.path = nil
self.playerDetected = false
self.target = nil
end
local function getRoamPoint(self)
local comp = ZonesComponent:FromInstance(self.Instance.Parent.Parent)
local monsterZone = comp:GetZoneFromMonster(self.Instance)
local point = monsterZone:getRandomPoint()
return point
end
function Monster:Attack()
print("Monster Attacked")
local check = self:CheckForDamageDistance()
if check then
self:Attack()
end
end
function Monster:CheckForDamageDistance()
local closestPlayer = SimplePath.GetNearestCharacter(self.Instance.PrimaryPart.Position)
if closestPlayer then
if
(closestPlayer.PrimaryPart.Position - self.Instance.PrimaryPart.Position).Magnitude
<= self.playerDamageRange
then
return true
end
end
end
function Monster:CheckForPlayer()
local closestPlayer = SimplePath.GetNearestCharacter(self.Instance.PrimaryPart.Position)
if closestPlayer then
if
(closestPlayer.PrimaryPart.Position - self.Instance.PrimaryPart.Position).Magnitude
<= self.playerDetectionRange
then
self.target = closestPlayer:GetPivot().Position
+ (self.Instance:GetPivot().Position - closestPlayer:GetPivot().Position).Unit * 3
self.playerDetected = true
end
end
end
function Monster:SetState(newState)
self.status = newState
if self.path.Status == "Active" then
self.path:Stop()
end
self:CheckForPlayer()
if self.target then
self.path:Run(self.target)
else
self.target = getRoamPoint(self)
self.path:Run(self.target)
end
end
function Monster:Start()
local _, size = self.Instance:GetBoundingBox()
local pathParams = {
["AgentHeight"] = size.Y,
["AgentRadius"] = size.X / 2,
["AgentCanJump"] = false,
}
self.path = SimplePath.new(self.Instance, pathParams)
self.path.Visualize = true
self:SetState("roaming")
self.path.WaypointReached:Connect(function()
self.playerDetected = false
self:CheckForPlayer()
if self.playerDetected then
self:Attack()
self:SetState("following")
end
end)
self.path.Reached:Connect(function()
self:CheckForPlayer()
if self.playerDetected then
self:Attack()
self:SetState("roaming")
else
self.playerDetected = false
self.target = nil
self:SetState("roaming")
end
end)
self.path.Blocked:Connect(function()
self.playerDetected = false
self.target = nil
self:SetState("roaming")
end)
end
function Monster:Stop() end
return Monster