I am trying to create a game using UNET and i’ve hit a road block. It’s a tank game, in which the bullets are objects, so therefore I would like to object pool them. I simply cannot understand how to do that, and I’ve tried a couple of things. I’ve read that you can use the ClientScene.RegisterSpawnHandler function to override the spawn mechanism of an object, but I can’t seem to figure out what to do with it.
I hope that someone can help me, as I can’t really move on with the game before I figure out this problem. If you can, I would like you to explain most of the progress, and if you wan’t to see some of the code I’ve written, just ask, but at the moment, its very messy, and does not work.
Hello.
So first of all I haven’t tried it myself so I’m not sure if it’s going to work .
So first of all you need to add you bullet prefab to spawn prefabs list on your NetworkManager component.
Then you’ll need to instantiate those prefabs server side like this:
GameObject bullet =(GameObject)Instantiate(bulletPrefab, spawn.position, spawn.rotation );
NetworkServer.Spawn (bullet);
bulletList.Add(bullet);
I hope it was helpful.
Cheers
I’ve tried something like this, for creating the pool. The problem is how i can then “edit” the object, such as setting its name and if its enabled or not, on both the clients and the server. I have a script on the object, in which there is a “start” function that sets the velocity and direction. How would I go about doing that?
I kinda went to pseudocode by the end there but you get the idea. The server side just changes the vars and its client counterpart gets the right stuff.
First, I think there are multiple possible solutions to create objects like bullets in network (not considering any pooling so far). Below are 2 different basic approaches that came to my mind:
Solution #1:
The bullet is a networked object and it is created on the server and then spawned across the network via NetworkServer.spawn (as it is in your current approach).
Now you still need to sync some values on the clients, like position, rotation, etc.
As it has been previously mentioned, for example, you can do this by using SyncVars so that the necessary information are automatically transmitted from the server bullet to the clients bullets.
Solution #2:
When a player shoots, the server notices it (e.g. by a command send from the shooting player), and then the server calls a ClientRPC which is executed on all clients.
In the ClientRPC you pass all necessary parameters (like position, rotation etc.) and create the bullet for each client in the ClientRPC. In this case, you do not need NetworkServer.spawn, each bullet is just a local non-networked object on the client.
There might be other approaches as well.
Since you need to create the object first (before you need to care about syncing parameters), I guess you can use usual object pooling for this task as replacement for instantiate without any problems, at least using solution #2.
For solution #1, it might be necessary to deactivate network updates for inactive pooled objects in addition to the usual stuff.
Anyways, after a bullet has been created, either with or without pooling, you have to keep some values in sync. This, however, might not be an issue of the pooling itself but is just something you need to take care of within your network code.
What object pooling means, is that you have already spawned ( => instantiated over the network ) all the bullets you will ever need and keep them in a list. Then whenever you need a bullet you will take one out of the list, activate it ( if you have a list of 20 bullets and a player shoots 5, then those other 15 bullets are inactive, though still part of the scene and already loaded/instantiated ) and update its position etc. via a command send to the server, who then informs the clients via a client rpc.
Since bullets are probably flying, you also need to have their position synced with the server.
If you spawn something everytime you shoot a bullet, than that is not object pooling. Just to be clear on that.
Oh, I just realised, that I’ve linked some wrong code, some code that i just experimented with I know that object pooling i instantiating the objects in the beginning
Hi, I’m trying to implement a second solution but with no luck. Here is what I have:
Bullets are gameObjects in the scene, every player on spawn getting its array of existing bullets.
In player Shoot() function I’m setting bullet gameObject active state to true and call function on bullet to position it with bullet spawn position and add force to it.
Shooting:
if (Input.GetMouseButtonUp(0))
{
PlayerShoot();
}
void PlayerShoot()
{
for (int i = 0; i < availableBullets.Count; i++)
{
if (!availableBullets[i].gameObject.activeSelf)
{
availableBullets[i].gameObject.SetActive(true);
availableBullets[i].SetUpBullet(Gun.position, Gun.rotation, bulletDamage, bulletSpeed);
break;
}
}
}