x


How should I handle masses of bullets?

I'm making a top down shooter and I face a problem which is significant slow down (320fps down to 140fps) when firing an infinite clip automatic weapon.

the bullet at the moment is a cylinder of 18 polys (easily lowered) and I noticed not a single one of them is batched, if that is the issue, how could I get this to work?

Another thing that may be the issue is on firing it creates a new bullet prefab which on creation gets its rotation, does a raycast as far as its range, sets the bullet length (stopping it when it hits a wall and stopping it at its range if it does not) the materials alpha is then decreased for a second until the bullets alpha is less than or equal to zero at which point it destroys its containing object.

Is this poor practice? if so how can I improve its efficiency? I'd like to make it as fast as possible so it can run on lower end machines.

Any and all help is greatly appreciated,

Thanks in advanced, Bombshell

more ▼

asked Aug 05 '12 at 04:28 AM

Bombshell93 gravatar image

Bombshell93
22 3 5 9

I would start by removing the bullet code, and the alpha material code, in turn, just to see how they affect framerate individually, to pinpoint the issue.. I assume there is not an outrageous number of bullets on the screen, so my best guess is either you've something in the Update function that should be in the Start, or maybe the alpha channel part is the cause

Aug 05 '12 at 05:34 AM Seth Bergman

I just removed all the initial code and only left the countdown to the object end. I also changed the shader from a custom alpha Fresnel shader to the unlit/texture. I gain 20 FPS but that means I've still 130 or so FPS, the amount alive at any one time with maximum rate of fire and the current bullet life time, about 50. I think the problem is the creating and destroying of those objects in so short a time frame, but I'm not sure how I'd fix that.

Aug 05 '12 at 06:33 AM Bombshell93

well, can you actually see the bullets? do you need to be able to? just doing a direct raycast without instantiating so many bullets would probably do it. seems like they must be going pretty fast if there're that many.. maybe you could just do fewer or none actual objects, and just raycast from the weapon itself

Aug 05 '12 at 07:17 AM Seth Bergman

the bullets dont really move, they're there so you can see the shot mainly, the many raycast could easily be done in firing object but I dont know how I would draw the various shots without them rotating with the firing object. Hence why I made their own objects to host the bullets, so they could have independent transforms.

Aug 05 '12 at 07:48 AM Bombshell93
(comments are locked)
10|3000 characters needed characters left

1 answer: sort voted first

You must use object pooling for the projectiles.

In a nutshell it instantiate all the bullets when the scene loads, and then it reuses those GameObjets over and over again without the need to instantiate new ones.

Here is the code I wrote to tackle such issue:

ObjectPooling.cs (Attach it to an empty GameObject):

using UnityEngine;
using System.Collections;

public class ObjectPooling : MonoBehaviour
{
 public GameObject prefab;
 public int poolSize;

 private GameObject[] pool;

 void Start ()
 {
 pool = new GameObject[poolSize];

 for (int i = 0; i < poolSize; i++) {
 pool[i] = (GameObject)Instantiate (prefab, transform.position, Quaternion.identity);
 pool[i].SetActiveRecursively (false);
 }
 }

 public GameObject RetrieveInstance ()
 {
 foreach (GameObject go in pool) {
 if (!go.active) {
 go.SetActiveRecursively(true);
 return go;
 } 
 }

 return null;
 }

 public void DevolveInstance (GameObject go)
 {
 go.SetActiveRecursively (false);
 }
}

SpawnPool.cs (Attach it to a GameObject that will spawn the bullets, in your case the ship or soldier holding the gun):

using UnityEngine;
using System.Collections;

public class SpawnPool : MonoBehaviour
{
 private ObjectPooling pool;
 private GameObject go;
 private int contador = 2;

 void Start ()
 {
 pool = GameObject.FindGameObjectWithTag ("BulletPool").GetComponent<ObjectPooling> ();
 }

 void Update ()
 {
 //Debug.Log(contador);
 //contador++;

 //if (contador > 2) {
 go = pool.RetrieveInstance ();

 if (go) {
 go.transform.position = transform.position;
 }

 // contador = 0;
 //}
 }
}

AutoDevolvePool.cs (Attach it to a bullet Prefab):

using UnityEngine;
using System.Collections;

public class AutoDevolvePool : MonoBehaviour
{
 public int time = 2;

 private float seconds = 0;
 private ObjectPooling pooling;

 void Start ()
 {
 pooling = GameObject.FindGameObjectWithTag ("BulletPool").GetComponent<ObjectPooling> ();
 }

 void Update ()
 {
 seconds += Time.deltaTime;

 if (seconds >= time) {
 //Debug.Log("devolvido");
 pooling.DevolveInstance (gameObject);
 seconds = 0;
 }
 }
}

Hope that helps!

more ▼

answered Aug 05 '12 at 07:57 AM

Leocesar gravatar image

Leocesar
98 1 2 4

it did help plenty by cleaning up my code and saving another 20FPS but the FPS drop still occurred. So I looked into how the gun was handled and there were some issues with rate of fire being limitless which was a drain of 40-60FPS, I'm pretty much back to optimal now.

Aug 05 '12 at 07:21 PM Bombshell93
(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x1534
x309
x275
x115
x59

asked: Aug 05 '12 at 04:28 AM

Seen: 645 times

Last Updated: Aug 05 '12 at 07:21 PM