Ahh…I see.
So, the one thing that you might want to take into consideration is why we don’t allow changing ownership of despawned NetworkObjects:
The reason why you can’t change ownership of despawned NetworkObjects is that the spawn process assigns a NetworkObjectId to the NetworkObject when spawned but when not spawned there is no “associated” NetworkObjectId assigned/tracked for the NetworkObject. The NetworkObjectId tells NGO how to route messages…so if you want to change ownership of a NetworkObject then the message includes the NetworkObjectId of the spawned NetworkObject that is changing its ownership. When a NetworkObject is not spawned, there is no way to know “which instance” you are referring to.
If you use NetworkObjectReference, then you are basically creating a wrapper that serializes the NetworkObjectId. For any client instance trying to deserialize/resolve the NetworkObjectReference it will try to look for the NetworkObjectId within the NetworkSpawnManager.SpawnedObjects table. Which…if the NetworkObject is not spawned then it will not be in that table and the NetworkObjectReference will fail to resolve.
Even if you were to disable Recycle Network Ids in order to assure you aren’t pointing to a re-assigned NetworkObjectId, the NetworkObjectId stored within the NetworkObjectReference will not be “valid” since NetworkObjectReference will not resolve to a spawned object.
There are a couple of paths I could see you taking. The first one would be to have an “inactive” state for the minion and projectiles that doesn’t mean it isn’t spawned but does mean it is spawned but not active and when “inactive” the visuals, colliders, and such are disabled (when “active” they are enabled). However, if you plan on having a bunch of minions and projectiles this could become a large initial synchronization for late joining clients having to spawn a bunch of things that might not be “active” for a period of time.
Another way to handle this would be to create minion and projectile “state” structs (or a single “ObjectState” struct) that implements INetworkSerializable and contains the base information for the object to spawn, team, client it is assigned to (a form of ownership), and things of that nature. Then when you need to spawn a minion or projectile for any given ObjectState you just pull from the pool and spawn it. Having this separation from the actual spawned object and the “Object State” would allow you to handle the assignment of “ownership” for minion(x) and projectile(y) without having to try and assign a despawned object (not recommended).
The “ObjectState” could include a unique identifier you assign to each ObjectState instance which you could then create something like a NetworkVariable<Dictionary<ulong, Dictionary<short, ObjectState>> property that signifies: [ClientId][ObjectId][ObjectState] that would automatically synchronize amongst all clients (or something along those lines) so a client is provided all of the “minions” and “projectiles” assigned to them without having to actually assign an instantiated but despawned instance per minion and projectile.
However, trying to assign a specific instance from a pool to a specific client will be tricky since the INetworkPrefabInstanceHandler.Instantiate method only passes in the client identifier that is the owner of the NetworkObject to pull from the pool…in other words… while you could get the client-owner side to spawn a specific despawned instance, the rest of the non-owner clients would not use that specific instance when they spawn its clone instance locally.
I would recommend thinking about separating the actual pooled object from a data set that represents the “yet to be spawned” network prefab as you shouldn’t really need to worry about “which network prefab instance” you are using to represent a specific minion or minion’s projectile…but…based on what I can tell… you are more concerned about assigning “pre-assigned minion and projectile slots” to a specific client that is on a specific team.
Let me know if any of this helps?