- Home /
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
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
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.
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
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.
Answer by Leocesar · Aug 05, 2012 at 07:57 AM
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!
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.
Your answer
Follow this Question
Related Questions
Raycasr in my fps? 1 Answer
Best way to shoot physical bullets? 2 Answers
How to get bullets to hit crosshair 2 Answers
Random Raycast inside crosshairs 1 Answer
shooting problem with raycasting 1 Answer