I’m not sure I quite understand the issue? You want your enemies to look like this going down the path:
but not like this
I’m not sure I quite understand the issue? You want your enemies to look like this going down the path:
but not like this
I want them to be staggered rather then n a straight line.
They seem staggered to me? Could you show a simple example maybe of what you are trying to achieve?
Tower Defense Simulator. That’s the best example.
Similar yes. To where they stagger and fill the path rather then all be right by each other.
How often do you call the move method?
every time they spawn.
local success, err = pcall(function()
coroutine.wrap(EntityService.Move)(Enemy, EntityData)
end)
One idea I could say that might work is to do a magnitude check around each enemy and apply some external “force” on enemies that are too close to one another. Doing so will keep them spaced and staggered like you’re hoping for. You may have to do some extra checks so they dont go past the wall either.
how would i do that?
local workspace = game:GetService("Workspace")
local ServerStorage = game:GetService("ServerStorage")
local PhysicsService = game:GetService("PhysicsService")
local ServerScriptService = game:GetService("ServerScriptService")
local EntitiesFolder = ServerStorage:WaitForChild("Entities")
local EntityData = ServerScriptService:WaitForChild("Modules"):WaitForChild("EntityData")
local EntityService = {}
local MapName = nil
function EntityService.Move(Entity, EntityData)
if not EntityData.humanoid then
warn("Entity is missing Humanoid!")
return
end
if MapName then
local Map = workspace:FindFirstChild(MapName)
if Map then
local waypoints = Map:FindFirstChild("Waypoints")
if waypoints then
for i = 1, #waypoints:GetChildren() do
local position = Map["Waypoints"][i].Position
local spacing = EntityData.offsetSpacing/(i - 0.5)/1.35
local targetPosition = position + Vector3.new(EntityData.offset.X * math.random(-spacing,spacing),0,0)
EntityData.humanoid:MoveTo(targetPosition)
EntityData.humanoid.MoveToFinished:Wait()
end
Entity:Destroy()
else
warn("Waypoints don't exist!")
return "Waypoints don't exist!"
end
else
warn("Map does not exist!")
return "Map does not exist!"
end
end
end
function EntityService:Spawn(HordeData)
for i, v in pairs(HordeData["Entities"]) do
if EntitiesFolder:FindFirstChild(v) and EntityData:FindFirstChild(v) then
local DataModule = require(EntityData[v])
local Enemy = EntitiesFolder[v]:Clone()
local Health = DataModule.Health
local MaxHealth = DataModule.MaxHealth
local isBoss = DataModule.Boss
local walkSpeed = DataModule.Speed
local isStealth = DataModule.Stealth
print("Entity Name: " .. v)
print("Health: " .. tostring(Health))
print("Max Health: " .. tostring(MaxHealth))
print("Is Boss: " .. tostring(isBoss))
print("Walk Speed: " .. tostring(walkSpeed))
print("Is Stealth: " .. tostring(isStealth))
if MapName == nil then
for _, child in pairs(workspace:GetChildren()) do
if child:IsA("Folder") and child.Name ~= "Data" and child:FindFirstChild("Map") then
print("Found a Map folder: " .. child.Name)
MapName = child.Name
break
end
end
else
print("Map name is not nil!")
end
Enemy.Humanoid.WalkSpeed = walkSpeed
Enemy.Humanoid.MaxHealth = MaxHealth
Enemy.Humanoid.Health = Enemy.Humanoid.MaxHealth
Enemy:SetAttribute("Boss", isBoss)
Enemy:SetAttribute("Stealth", isStealth)
Enemy.Parent = game.Workspace.Data.Entities
local spacing = 1.25
local maxOffset = 1.25
local EntityData = {}
EntityData.data = DataModule
EntityData.humanoid = Enemy:WaitForChild("Humanoid")
EntityData.offset = CFrame.new((math.random(-maxOffset * 100, maxOffset * 100) / 100) * spacing, 0, 0)
EntityData.offsetSpacing = spacing
EntityData.offsetMaxOffset = maxOffset
Enemy.Humanoid:SetStateEnabled(Enum.HumanoidStateType.Dead, false)
-- Enemy.Humanoid:SetStateEnabled(Enum.HumanoidStateType.None, false)
Enemy.Humanoid:SetStateEnabled(Enum.HumanoidStateType.Flying, false)
Enemy.Humanoid:SetStateEnabled(Enum.HumanoidStateType.Landed, false)
Enemy.Humanoid:SetStateEnabled(Enum.HumanoidStateType.Seated, false)
Enemy.Humanoid:SetStateEnabled(Enum.HumanoidStateType.Jumping, false)
Enemy.Humanoid:SetStateEnabled(Enum.HumanoidStateType.Physics, false)
Enemy.Humanoid:SetStateEnabled(Enum.HumanoidStateType.Ragdoll, false)
Enemy.Humanoid:SetStateEnabled(Enum.HumanoidStateType.Climbing, false)
Enemy.Humanoid:SetStateEnabled(Enum.HumanoidStateType.Swimming, false)
Enemy.Humanoid:SetStateEnabled(Enum.HumanoidStateType.Freefall, false)
Enemy.Humanoid:SetStateEnabled(Enum.HumanoidStateType.GettingUp, false)
Enemy.Humanoid:SetStateEnabled(Enum.HumanoidStateType.FallingDown, false)
Enemy.Humanoid.NameDisplayDistance = 0
Enemy.Humanoid.HealthDisplayDistance = 0
Enemy.Humanoid.DisplayName = " "
Enemy.HumanoidRootPart.CFrame = game.Workspace[MapName].Start.CFrame * EntityData.offset-- game.Workspace.Map[map].Start.CFrame
local success, err = pcall(function()
for _, obj in pairs(Enemy:GetChildren()) do
if obj:IsA("Part") or obj:IsA("MeshPart") then
obj:SetNetworkOwner(nil)
obj.CollisionGroup = "Entity"
end
end
end)
if success then
print("Success!")
local success, err = pcall(function()
coroutine.wrap(EntityService.Move)(Enemy, EntityData)
end)
if success then
print()
else
warn("Error:", err)
end
else
warn("Nuh uh! Error mate:", err)
end
task.wait(HordeData["TimeBetween"])
else
print("Entity or Data not found for: " .. v)
end
end
end
return EntityService
whats the problem just to add wait before spawning another enemy
and instead of storing entityydata in a module just store it inisde the enitities itself
They just stagger pack into the straight line.
Are you still having issues with performance? If so I’d request you take a look at the microprofiler so we can get a better idea at what’s taxing everything.
As for ensuring zombies aren’t all in a straight line, you could add a horizontal offset value that gets +/-'d every time a zombie reaches a waypoint, that way instead of walking towards CFrame.new(10, 0, 0) they could be walking towards CFrame.new(10, 0, 0) * CFrame.new(horizontalOffset, 0, 0).
They’d still move roughly in the same place but with just enough subtle differences so that it looks more organic.
How can I do that? Referring to the movement I don’t understand entity movement as I don’t often deal with that. Let me get home and I’ll send you a photo
I presume the reason why it’s taking up so much is actually rendering the entities; especially since you are still using humanoids. (forgive my ignorance, I haven’t really read through all of this, especially the code.)
For the entity movement, I’d suggest using bones instead. Transforming bones are very free to render, saving up resources. For the entity offset, you can multiply the CFrame (Bone Transform is a CFrame) by the offset on the X axis.
However, since you are using :MoveTo, you’re gonna have to rewrite the entity movment.
You can read this devforum post for more details regarding bones, and other optimization tactics you can use: here
However (thank you so much for that, I will definetly look into it and optimizing the game hardcore)
But my main question is, how can I fix it from all going into one linear line, when i want them to all be like how tower defense simulator has their systems: (Image Below)
Everything works decent, but I need to figure out a way to add space between the enemies so they are not all hogging each other’s spot as-well making it so they all follow the TDS movement system, rather then staying linear (I don’t understand the correct terms for it rn, its late and i’m tired lol…)
You can use CFrames to offset your entity’s position.
However, you’ll need to rewrite how your entities move Good thing is, I’ve already incorporated this style of movement into my own TD game.
I’ll be giving you a place file of a snippet of my code; this includes the movement and the offsetting. Comments are already provided for your own benefit.
For smooth cornering, you can use beziers or do some math to calculate the turning angle.
entityoffset.rbxl (82.4 KB)
this is a way for me to not overexplain things lol
I’d also suggest starting to move to client-sided rendering and making the entities non-humanoid. Since you’re basically rewriting the code for your entities, now should be a good time to move to client-sided rendering.
My bad, I missed your reply. If you click on the “mode” tab you should be able to switch to detailed view which will give you a full breakdown of everything happening under the hood each frame. The yellow bars represent how long it takes for a frame to process, the taller the bar the worse.
If you click on a bar it’ll scrub the timeline to when that frame was processed. You can then drag the view around, scroll up/down to zoom in/out, etc.
If you need more info, take a look at microprofiler documentation. You’ll be able to figure out exactly what’s pushing those yellow bars all the way to the top lagging your game.