FPS Slowly reduces over time with multi-object pool
I have two turret types in my game, a missile turret and a machine gun turret. They fire missiles and bullets respectively. The bullets have a trail renderer attached, the missile object has a particle trail and spawns an explosion on collision.
I've created a multi-object object pool to go easy on the multiple Instantiate/Destroy calls I would have to make with lots of projectiles.
Here's my object pool script: using UnityEngine; using System.Collections; using System.Collections.Generic;
public class ObjectPool : MonoBehaviour {
public static ObjectPool instance;
public GameObject[] objectPrefabs;
public int defaultPoolSize = 40;
private Dictionary<string, List<GameObject>> objectPool;
protected GameObject containerObject;
void Awake(){
instance = this;
}
void Start(){
objectPool = new Dictionary<string, List<GameObject>> ();
containerObject = new GameObject ("ObjectPool");
foreach (GameObject obj in objectPrefabs) {
List<GameObject> objects = new List<GameObject>();
for(int i = 0; i < defaultPoolSize; i++){
GameObject newObj = Instantiate(obj);
newObj.transform.parent = containerObject.transform;
newObj.SetActive(false);
objects.Add(newObj);
}
objectPool.Add(obj.name, objects);
}
}
public GameObject GetPooledObject(string name){
List<GameObject> objs = objectPool[name];
foreach (GameObject obj in objs) {
if(!obj.activeInHierarchy){
return obj;
}
}
foreach (GameObject currentObj in objectPrefabs) {
if(currentObj.name == name){
GameObject newObj = Instantiate(currentObj);
newObj.transform.parent = containerObject.transform;
newObj.SetActive(false);
objectPool[name].Add(newObj);
return newObj;
}
}
return null;
}
}
Bullets and missiles have the following script attached:
Bullets:
using UnityEngine;
using System.Collections;
public class BulletController : MonoBehaviour {
public float speed = 25f;
public float life = 5f;
public ParticleSystem bulletHit;
private Rigidbody rb;
private TrailRenderer trailRenderer;
private MeshRenderer mesh;
void Awake(){
rb = GetComponent<Rigidbody> ();
trailRenderer = GetComponent<TrailRenderer> ();
mesh = GetComponent<MeshRenderer> ();
}
private void OnEnable(){
mesh.enabled = true;
trailRenderer.enabled = true;
rb.velocity = speed * transform.forward;
Invoke ("Remove", life);
}
private void OnDisable(){
CancelInvoke ();
}
private void Remove(){
transform.rotation = Quaternion.identity;
trailRenderer.enabled = false;
mesh.enabled = false;
rb.velocity = Vector3.zero;
rb.angularVelocity = Vector3.zero;
transform.position = transform.parent.position;
Invoke ("WaitTime", 0.5f);
}
private void OnCollisionEnter(Collision other){
Remove ();
}
private void WaitTime(){
gameObject.SetActive (false);
}
}
Missiles:
using UnityEngine;
using System.Collections;
public class MissileController : MonoBehaviour {
public float speed = 30f;
public float turnSpeed = 15f;
public float life = 4f;
public string explosionName;
[HideInInspector]
public Transform target;
private ParticleSystem missileTrail;
private float particleEmissionRate;
private bool alive;
private Rigidbody rb;
private Light light;
private MeshRenderer mesh;
void Awake(){
mesh = GetComponent<MeshRenderer> ();
light = GetComponentInChildren<Light> ();
rb = GetComponent<Rigidbody> ();
missileTrail = GetComponentInChildren<ParticleSystem> ();
particleEmissionRate = missileTrail.emissionRate;
}
private void OnEnable(){
rb.isKinematic = false;
mesh.enabled = true;
light.enabled = true;
alive = true;
missileTrail.emissionRate = particleEmissionRate;
missileTrail.transform.position = transform.position;
missileTrail.transform.parent = transform;
Invoke ("Remove", life);
}
private void OnDisable(){
CancelInvoke ();
}
private void Remove(){
target = null;
mesh.enabled = false;
light.enabled = false;
alive = false;
missileTrail.emissionRate = 0;
transform.position = transform.parent.position;
rb.isKinematic = true;
}
private void WaitForTrail(){
gameObject.SetActive (false);
}
private void OnCollisionEnter(Collision other){
GameObject explosion = ObjectPool.instance.GetPooledObject ("Explosion");
explosion.transform.position = transform.position;
explosion.SetActive (true);
Remove ();
Invoke ("WaitForTrail", 2f);
}
void FixedUpdate () {
if (target && alive) {
transform.Translate(Vector3.forward * speed * Time.deltaTime);
Quaternion rot = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(target.position - transform.position), turnSpeed * Time.deltaTime);
transform.rotation = rot;
}
}
}
Bullets and missiles are instantiated with the following lines:
GameObject bullet = ObjectPool.instance.GetPooledObject("Bullet");
bullet.transform.position = t.position;
bullet.transform.rotation = Quaternion.LookRotation(dir);
bullet.SetActive(true);
The issue I'm getting is that my fps lowers over time, in the Unity editor and standalone .exe file. I've looked at the profiler and the WaitTime() & WaitForTrail() methods cause occasional spikes which seem to increase in duration over time. The overdraw seems to be high as well.
Your answer
