Help With Creating A Simple Ai Enemy System!

  1. What do you want to achieve? Keep it simple and clear!

I am trying to create an RPG game that will have lots of enemies!!

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

I have decided not to use Humanoids as they cause a lot of lag if you have many enemies!
I am planing to Implement a system where ai thinking is frozen if no player is near
I have already added hitboxsystems!
And lastly i have decided to run animations of the enemies on the client side for optimization

What i need help with (Listed):

  1. I am having trouble with the different states the enemy ai will have! Should i use a while loop?
  2. How should i handle respawning?
    (Enemy states: Idle, Roaming, Following Player, Attacking)
  3. Also how could i make the enemy move to a specific spot without using humanoid?
1 Like

For moving the enemies i could recommend adding a linear velocity using ApplyImpulse() on the primary part of each enemy

1 Like

but then how would i make it stop at a spesific point ?

give each NPC a simple state field "Idle", "Roam", "Chase", "Attack"
and in one RunService.Heartbeat callback check it each frame, no while loops needed.

local RunService = game:GetService("RunService")
RunService.Heartbeat:Connect(function(dt)
    if npc.state == "Roam" then roamFunc(npc, dt) end
-- etc
end)

when an NPC dies wait your respawn delay then.

local newnpc = template:Clone()
newnpc.Parent = workspace
newnpc:SetPrimaryPartCFrame(spawnCFrame)

:Clone() copies a model and all descendants,
see also using .AncestryChanged or simple wait() loops for auto respawn

for moving & stopping at a target, pick a PrimaryPart, anchor it, then

local tween = TweenService:Create(
    npc.PrimaryPart,
    TweenInfo.new(time, Enum.EasingStyle.Linear),
    { CFrame = targetCFrame }
)
tween:Play()
tween.Completed:Connect(function() tween:Destroy() end)

TweenService can interpolate CFrame directly and will end exactly at targetCFrame

1 Like

But if you are using tween service then the enemy will not respond to the environment and just go in a straight line. How should i go about this problem?

A basic system like this for handling states would work (what I’ve used):

local Maid = require(path.to.maid)

local deathEvent = path.to.DeathEvent

local currentState
local currentStateMaid = Maid.new()

local function changeState(newState)
	currentStateMaid:Clean() -- End the current state
	currentState = newState
end

function attackPlayer(player)
	changeState("attacking")
	
	-- Attack the player
end

function followPlayer(player)
	changeState("following")
	
	currentStateMaid:Add(task.spawn(function()
		while true do
			-- Follow player until close enough, then attack them:
			attackPlayer(player)
			-- Or if they leave follow range, then go back to roaming:
			roam()
		end
	end))
end

function roam()
	changeState("roaming")
	
	currentStateMaid:Add(task.spawn(function()
		while true do
			-- Roam until a player is found, then follow them:
			followPlayer(player)
		end
	end))
end

local function startAutoRespawn()
	deathEvent:Connect(function()
		changeState("dead")
		
		-- Destroy them, respawn them
	end)
end

startAutoRespawn()
roam()

As @jeuhari30 said, use forces (and a while loop to check distance to target).

Alright thanks everybody i got a rough idea on what to do now thanks for everything :slight_smile:

2 Likes