Hello
I’m making a Bullet Hell Game. But I have trouble making the spawners Framerate Independent.
If I Pause and Frame Advance The spawners spawn more, But In Realtime it spawns less.
A clear Indicator that It depends on frame rate.
I Tried Time.deltaTime But that doesn’t work.
Here’s the Code Snippet In charge of the spawning:
// Fire Bullets
if (fireNumber >= rateOfFire)
{
SpawnBullet();
fireNumber = 0;
bulletCount++;
}
else
fireNumber += Time.deltaTime;
My guess is that if the amount Time.deltaTime is bigger than the spawn rate it skips over them.
I can’t just spawn more bullets if Time.deltaTime is bigger than the spawn rate because they would just be on top of each other.
This is a big problem for the game and I would appreciate any answers.
Edit: Full Script. Warning Messy and unreadable:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BulletSpawn : MonoBehaviour
{
//Spawn Controls
public GameObject spawnObject;
public float rateOfFire;
public float bulletSpeed = 0.1f;
public bool randomBulletSpeed;
public bool aimAwayFromBoss = false;
public Sprite Colour;
public float offset = 0;
public bool patterned = false;
public int everyBullet = 10;
public float waitTime = 100;
public float speedAdd = 0f;
public float curveTimeAdd = 0f;
public int rotationOffset = 0;
public bool spawningSpawns = false;
public AudioClip clip = null;
public bool lazer = false;
public float lazerTime = 1;
public float lazerWait = 1;
public Animation playedAnimation;
public moveObj_Aim aimer;
public moveObj_RandomRotation randomRotation;
public bool ignoreFirst = false;
public bool randomOffset;
public bool easeIn = false;
public bool easeOut = false;
public bool curve = false;
public bool reSet = false;
public float curveRate = 0.1f;
public float curveTime = 1f;
public float newSlow = 0.5f;
public float[] changeTimes;
public float[] rotationAdd;
public float[] newSpeed;
public float changeEase = 0.05f;
public bool affector = false;
public bool affectorEnter = false;
public bool aimAtPlayer = false;
public bool randomRot = false;
public bool follow = false;
public float changeSpeed = 0f;
public bool destroyEnter;
public float min;
public float max;
public GameObject objChange;
public int rofChange;
public bool ssChange = false;
public float speedChange = 0;
public float bSpeedChange = 0.1f;
public bool homingChange = false;
public bool homingCChange = false;
public Color tintChange;
public int offsetChange = 0;
public AudioClip clipChange = null;
public bool easeInChange = false;
public bool easeOutChange = false;
public bool curveChange = false;
public float curveRateChange = 0.1f;
public float curveTimeChange = 1f;
public float newSlowChange = 0.5f;
//Movement Controls
public float speed = 0;
public bool homing = false;
public bool homingContinuous = false;
float fireNumber;
float bulletWait = 0;
int bulletCount = 0;
float originalSpeed;
float originalCurve;
float offsetCount;
public Quaternion initialRotation;
GameObject tempObj;
// Use this for initialization
void Start()
{
originalSpeed = bulletSpeed;
originalCurve = curveTime;
if (homing)
{
Vector2 dir = GameObject.Find("Player").transform.position - transform.position;
float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
angle -= 90;
angle += rotationOffset;
transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
}
if (aimAwayFromBoss)
{
Vector2 dir = GameObject.Find("BossInitialPosition").transform.position - transform.position;
float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
angle -= -90;
angle += rotationOffset;
transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
}
fireNumber = rateOfFire;
//offset += (float)Random.Range(-1f,1f);
offsetCount = 0;
}
// Update is called once per actual frame
void Update()
{
//Move if Possible
gameObject.transform.Translate(new Vector2(0, speed), Space.Self);
if (offsetCount < offset)
{
offsetCount += Time.deltaTime;
return;
}
if (homingContinuous)
{
initialRotation = gameObject.transform.rotation;
Vector2 dir = GameObject.Find("Player").transform.position - transform.position;
float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
angle -= 90;
transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
}
if (patterned && bulletCount >= everyBullet)
{
bulletWait += Time.deltaTime;
if(bulletWait >= waitTime)
{
bulletCount = 0;
bulletWait = 0;
bulletSpeed = originalSpeed;
curveTime = originalCurve;
}
else
return;
}
// Fire Bullets
if (fireNumber >= rateOfFire)
{
SpawnBullet();
fireNumber = 0;
bulletCount++;
}
else
fireNumber += Time.deltaTime;
if (homingContinuous)
gameObject.transform.rotation = initialRotation;
}
private void LateUpdate()
{
if (fireNumber >= rateOfFire)
{
if (randomRotation != null)
randomRotation.RandomRotation();
}
}
void SpawnBullet()
{
tempObj = Instantiate(spawnObject);//ObjectPooler.SharedInstance.GetPooledObject(spawnObject.name);
tempObj.transform.position = transform.position;
tempObj.transform.rotation = transform.rotation;
//tempObj.SetActive(true);
if(aimer != null)
aimer.Aim();
BulletManager.sharedInstance.GetSpawnSound(clip).Play();
if(playedAnimation != null)
playedAnimation.Play();
if (spawningSpawns)
{
BulletSpawn bulletSpawn = tempObj.GetComponent<BulletSpawn>();
bulletSpawn.spawnObject = objChange;
bulletSpawn.rateOfFire = rofChange;
bulletSpawn.spawningSpawns = ssChange;
bulletSpawn.speed = speedChange;
bulletSpawn.bulletSpeed = bSpeedChange;
bulletSpawn.homing = homingChange;
bulletSpawn.homingContinuous = homingCChange;
bulletSpawn.offset = offsetChange;
bulletSpawn.clip = clipChange;
bulletSpawn.fireNumber = tempObj.GetComponent<BulletSpawn>().rateOfFire;
if (easeInChange || easeOutChange || curveChange)
{
bulletSpawn.enabled = true;
bulletSpawn.easeIn = easeInChange;
bulletSpawn.easeOut = easeOutChange;
bulletSpawn.curve = curveChange;
bulletSpawn.curveRate = curveRateChange;
bulletSpawn.curveTime = curveTimeChange;
bulletSpawn.newSlow = newSlowChange;
}
}
else if (!lazer)
{
if (randomBulletSpeed)
{
RandomizeBulletSpeed();
}
tempObj.GetComponent<Bullet>().speed = bulletSpeed;
tempObj.GetComponent<Bullet>().ignoreFirst = ignoreFirst;
if(Colour != null)
tempObj.GetComponent<SpriteRenderer>().sprite = Colour;
}
else if (lazer)
{
tempObj.GetComponent<Lazer>().waitTime = lazerWait;
tempObj.GetComponent<Lazer>().time = lazerTime;
tempObj.transform.parent = gameObject.transform;
tempObj.transform.localRotation = Quaternion.identity;
}
if (easeIn || easeOut || curve || reSet || affectorEnter || affector)
{
tempObj.GetComponent<BulletEffects>().enabled = true;
tempObj.GetComponent<BulletEffects>().easeIn = easeIn;
tempObj.GetComponent<BulletEffects>().easeOut = easeOut;
tempObj.GetComponent<BulletEffects>().curve = curve;
tempObj.GetComponent<BulletEffects>().curveRate = curveRate;
tempObj.GetComponent<BulletEffects>().curveTime = curveTime;
tempObj.GetComponent<BulletEffects>().newslow = newSlow;
tempObj.GetComponent<BulletEffects>().reSet = reSet;
tempObj.GetComponent<BulletEffects>().changeTimes = changeTimes;
tempObj.GetComponent<BulletEffects>().rotationAdd = rotationAdd;
tempObj.GetComponent<BulletEffects>().newSpeed = newSpeed;
tempObj.GetComponent<BulletEffects>().initialSpeed = bulletSpeed;
tempObj.GetComponent<BulletEffects>().time = 0;
tempObj.GetComponent<BulletEffects>().changeNumber = 0;
tempObj.GetComponent<BulletEffects>().finished = false;
tempObj.GetComponent<BulletEffects>().affectorEnter = affectorEnter;
tempObj.GetComponent<BulletEffects>().affector = affector;
tempObj.GetComponent<BulletEffects>().aimAtPlayer = aimAtPlayer;
tempObj.GetComponent<BulletEffects>().randomRotation = randomRot;
tempObj.GetComponent<BulletEffects>().followDirection = follow;
tempObj.GetComponent<BulletEffects>().changeEase = changeEase;
tempObj.GetComponent<BulletEffects>().changeSpeed = changeSpeed;
tempObj.GetComponent<BulletEffects>().destroy = destroyEnter;
}
bulletSpeed += speedAdd;
curveTime += curveTimeAdd;
}
void RandomizeBulletSpeed()
{
bulletSpeed = Random.Range(min, max);
}
}