Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Best approach for spawning and respawning units that die

Discussion in 'Scripting' started by SomeVVhIteGuy, May 16, 2023.

  1. SomeVVhIteGuy

    SomeVVhIteGuy

    Joined:
    Mar 31, 2018
    Posts:
    162
    Hi there! I'm making a game which is basically an rts.

    I'm starting to spawn units for players, my first time getting so far as spawning units at runtime with the netcode framework.

    So, I'm here to ask: What is the best approach for spawning in NetworkObject units, potentially in the hundreds, that die alot and will be replaced?

    So far what I'm doing is instantiating a large pool of gameobjects when the game starts, a part of loading in. Then when a unit is needed, I SpawnWithOwnership from a list of those instantiated GO's. The issue I'm running into is when a unit dies, I don't currently have a way to find that despawned unit in the list and respawn it when needed. Before I continue down this path by adding some sort of index marker to the unit itself, I want to see if there is a better approach to this situation.
     
  2. unUmGong

    unUmGong

    Joined:
    May 13, 2023
    Posts:
    11
    My suggestion would be 1. is an object necessary. Is the object necessary because the object is physically in the way. if an issue happens the object is still on your instance. With HP and data. On your instance. Do you want it there Is the question. That's the question do you want that object there? Well. Maybe sometimes you do. But realistically for the game design format large scale rts you should probably just pretend the object is there and render it as it would be. This way you can reduce the type of info sent over. This way it's just a reference to a mesh and then a reference position to put that mesh and an index to say hey this tile had a enemy unit on it it looked like this. So your units in your instance can know to damage that tile and send over damage data so the relevant tile occupier can receive the damage on his instance and kill his own units
     
  3. Draad

    Draad

    Joined:
    Feb 17, 2011
    Posts:
    325
    Hi,

    As part of ObjectPooling strategy, I would advice that you keep two list up to date.
    List<Unit> myPool is your pool of available objects.
    List<Unit> myActivesUnits is your currently used objects.

    When you spawn a new unit you should :
    • Check is myPool still has objects.
      • if not, create a new instance on the fly
      • if yes, pop an object from myPool.
    Add the object instance to the myActivesUnits list

    When an unit dies :
    • Remove it from myActivesUnits
    • Dispose any data you don't need anymore
    Add the object to myPool so you can fetch it again later.

    If you want to improve performance and not loop over the myActivesUnits list when removing a unit, you can use a Dictionary<string, Unit> instead, where key is a uniqueId given to the unit when you spawn it

    Hope it helps
     
    SomeVVhIteGuy likes this.
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,563
    I wouldn't TOUCH object pooling if I was doing a networking game.

    Reason 1: networking is far harder to "get right" than object pooling

    Reason 2: bugs in object pooling are often VERY SIMILAR to bugs in network code

    I would only even consider pooling if

    a) my network code was proven rock solid over some amount of time

    b) object instantiation / destruction actually HAS BEEN MEASURED as a bottleneck

    You have been warned.

    The costs and issues associated with object pooling / pools:

    https://forum.unity.com/threads/object-pooling.1329729/#post-8405055

    https://forum.unity.com/threads/object-pooling-in-a-tower-defense-game.1076897/#post-6945089
     
  5. Draad

    Draad

    Joined:
    Feb 17, 2011
    Posts:
    325
    @Kurt-Dekker I am not sure to understand your point here, could you explain further ?
    To me, object pooling is a display concern that is unrelated to the data sent on the network.
     
    unUmGong likes this.
  6. unUmGong

    unUmGong

    Joined:
    May 13, 2023
    Posts:
    11

    An object pool should only contain limited data

    Mesh information
    Position
    Rotation

    All this is in the transform. So a list of transforms with mesh renderers is all that's needed. This method is suitable if the objects are varied by a single script. Such as a generic enemy script or object script that defines the unique parameters of that object, movement speed, jump height, detection range etc. So you can pool a load of transforms that have an object or ai script attached. And put them in the positions you are looking at. Or implement consequence if the pool was of a certain size. A pool isn't always about revolving objects for rendering optimisation, it can be also about limiting max object count for optimal purposes.

    Multiple pools would likely exist in final solution. But a single pool as a rendering solution can work. But as you ask for disposal of relevant data attached to the object it is depending on how that data attached. If all objects had different scripts to each other you can't pool them effectively.
     
  7. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,043
    Yes, object pooling is a display concern. What he tries to say is that pooling is already introducing a technical debt to your project. It is not trivial to flawlessly maintain a pooling behavior, and if that was not enough, you're compounding that with another major concern which is networking. Now instead of having just one high-maintenance point of failure, you have two.

    His advice is basically: don't play smart if you're a noob knight who's going to get hurt by dragons, go easy, go chase some rats in the basement, run errands and don't venture too deep in the forest, especially not on a blood moon.

    I personally don't see pooling as something too complicated, but Kurt has seen all kinds of things on this forum over the years, and I have no doubt that his advice is in the OP's best interest.

    And btw if you read his links in much more depth, there are some very good arguments against pooling. Though this also partially answers why I don't see pooling as something too complicated -- it's because I'd never consider pooling as a silver bullet, nor I would ever overburden myself with physics on top of everything.
     
    Last edited: May 17, 2023
    Draad and Kurt-Dekker like this.
  8. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,563
    First, @orionsyndrome has characterized my feelings about pooling exactly and very colorfully.

    Second, when I wrote this:

    I mean that the report of the bug will be ambiguous as to where it could be.

    Yes, one is presentation and the other is data.

    But when the bug report is "Occasionally the orcs are missing their scimitars on one machine."

    Is that because the networking failed to move the data?

    Or is that because the pooling failed to reset the state of the scimitar and it's hidden now?

    Each machine would use the pooling uniquely so bugs and discrepancies could be completely ambiguous and hard to reproduce. HARD HARD HARD to reproduce.
     
    Draad likes this.