Hello, I’ve gone through various different approaches to this problem and spent a lot of time researching as well as testing. My AI is not quite the same as a “typical” one. I know exactly when and where the AI will be because the path is predetermined and on flat terrain.
My goal is to maximize efficiency.
There could be potentially hundreds of AI in a small area so just simply creating a humanoid on the server and going through that route is out of the picture as this would be very taxing on the server.
Another route I tried was creating an object to follow the AI’s track and have the client create the humanoid which definitely helps but is still very rough on the server as seen in this video below:
note: I didn’t fully complete this as I could see from just the plain object this wouldn’t work either
I then thought of a different approach that doesn’t involve any server creation of parts and still can’t be exploited. Since I know the exact route that the AI’s will be taking and I know their walkspeed, then based off of how long it’s been since the creation of the AI I could calculate the AI’s position. So I did exactly this and the server’s performance is phenomenal:
note: all damage is being done by the server and then shown to the client through events
However, there are some drawbacks to this. Mainly there is no .Touched with this route. This is the main reason I am writing this. I can pretty much see each individual AI’s position and that’s about it. This means the only way to see if an object is being touched would be to loop through the table of every AI, check its position, see if that position is within a certain radius to the part, deal damage and repeat. This seems pretty inefficient and taxing.
Examples of needed .Touched
Below I’ve pasted some of my code. If you have any suggestions on how to replicate the .Touched through this process please let me know! Also, if you’ve found a better way of handling mass AI’s I would love to hear that too, anything can help.
--global enemy table filled with each enemy object
_G.enemies = {}
--EX when creating 5 new enemies I would do something like this:
for i = 1, 5, 1 do
local enemy = Enemy.new() --There are arguments passed into the constructor but redundant for this example
enemies[i] = enemy
--Fireclient to create this enemy visually
wait(.5) --Time between each enemy
end
--Get Position function within enemy object module script
--Birth = tick() when object is first created
--Route is a table of vector3's where each value is the change from the last
function Enemy:GetPos()
local t = tick() - self.Birth --time since creation
local dist = t * self.Speed --distance to be traveled
local pos = self.Route[1] --start pos
for i = 2, #self.Route, 1 do
local change = self.Route[i].Magnitude
if dist - change <= 0 then
pos = pos - (self.Route[i] * dist / change)
break
else
dist = dist - change
pos = pos - self.Route[i]
end
end
return pos
end