- Home /
How to handle entity management
I apologize in advance for the wall of text, I would add code but I don't see it relevant to the question - I can add if requested.
Condensed version of the question:
I want a list of IEnities (interface I created) in my entity controller for easy access. The entity itself should handle it's spawning/despawning, damage, etc. However without being from MonoBehaviour I can't use the methods to check for these, update, etc. But if I make it of type MonoBehaviour I can't have a list of IEntities, only a list of GameObjects. I could have the entity controller loop over all entities in the lists each update, calling their own updates - but this would be slow and unwanted right? So how do I handle spawning, do I create a SpawnController for the scene, but then I believe I still have the same problem?
A quick flow of what is currently happening in the game:
Preload stores EntityHolder, GameObjects with all prefabs that will be needed later
MainScene loads, has an EntityController that holds a list of GameObjects for easy access
EntityController Spawns new Entity -> Gets added to the list
Entity gets damaged and killed, it destroys the Entity
Entity has no way of re-spawning as it is supposed to handle that itself
What I want to happen:
Preload stores EntityHolder, this holds GameObjects with all prefabs that will be needed later
MainScene loads, has an EntityController that holds a list of IEntities for easy access
EntityController adds a new entity to the list Entity spawns itself (Holds it's own GameObject)
Entity gets damaged and killed, it destroys the GameObject
Entity continues updating hits re-spawn time
Instantiates new GameObject Entity is still in list within EntityController
Longer version with more detail:
I currently have a persistent EntityHolder that holds all prefabs that will be used in that scene, is there a better way to go about doing it? I am only doing this as it is said to be good to avoid Resources.Load.
I have a list of GameObjects, one for npcs, players, and resources, however I am wanting to have the npcs/players list be of type IEntity that I created as to be able to handle collisions/damage/etc. but I am unable to find a way to do so. Is this even what I want, or do I want to stick with having GameObjects and when I need to access the IEntity part, use GetComponent to do so?
I am attempting to have each entity handle it's respawning - but that would mean either I only disable the entity while it's "dead" (what I'm currently doing, stopping all actions and disabling the spriterenderer), or have it hold it's own gameobject which it then destroys on death and re-instantiates on spawn - then how would It handle it's update as it needs to inherit MonoBehaviour, but this breaks having the list of type IEntity. Should I be having an external script be handling the re-spawning aspects? Currently my entity manager does the initial spawn but then lets the entity itself handle the respawns. Should I be having another controller such as spawn controller that handles this? If so, how does the entity controller get the spawned entities?
Answer by juicyz · Jan 30, 2017 at 07:49 PM
The way I handle spawning is that I make a SpawnerObject that has a spawner script. The script takes in a generic enemy prefab. I store all my enemy data in xml so I load that in at the start of the game. Before an enemy gets spawned, depending on what spawner and other various conditions, I find the enemy I want then load the data into the prefab. The enemy only handles itself. It only cares about what it needs to be doing. The spawner handles the respawning.
When an enemy dies, it tells the spawner "hey I died", then the spawner can take whatever action defined when that event happens.
How does the enemy send the message? It doesn't know what the spawner instance is right?
This would address one aspect, however I am still in need of a way to store the entities themselves in the entitycontroller.
The enemies can have a variable that holds the spawner instance. On instantiation, set the enemies spawner instance and then when the enemy dies, make a call to the spawner instance so that it knows it's dead.
List enityList = new List(); Then store the enities in there. How are you storing the entity data or is that your question?
Pretty decent start if you want to look at some code. You will likely need to change a bit of it so it fits your needs but it has a lot of good things in it. http://wiki.unity3d.com/index.php?title=Enemy_Spawner
I guess I'm confused on how the enemy gets created.
It's my understanding that the enemy is a prefab, so when it is created you have to instantiate it, which returns a game object. So now you have a game object. You can set the instance of the game objects spawner now, that's fine. Game object does its thing, dies, tells the spawner, and destroys itself.
Is that how it's done? Because if that's the case, then how do you add the entity to the list in the controller? Do you have to get component? Which would be bad per my understanding. Or if you get it another way, since you're in the spawner, how do you send it to the entitycontroller? Same way you send the message from the entity to the spawner?
The way I currently handle storage is, I have a JSON file that stores the entities data, I instantiate a new enemy, then apply the entity data. But since when the enemy is instantiated it's as type gameobject, but I need it to use it as type IEntity (which it interfaces from). I have no idea how to do this as I can't just convert from game object to IEntity right?
Ins$$anonymous$$d of holding it in the entity controller, would I ins$$anonymous$$d be better off holding them in the spawner? If so, the part about the entitycontroller getting the new enemy is irrelevant, but the part about getting a list of IEntities still stands
Thank you for the response, it made me think more about how I implement my entities and found that the way I currently was, wasn't sustainable. Also, the think you supplied and the code example were very helpful in that it allowed me to implement what I was looking for, but realize it wasn't sustainable. I will definitely implement it once I rework my implementation.