In the following code there are three script ExpSpawner, ExpEnemy and ExpScore. The ExpSpawner spawn enemy and ExpEnemy move the enemy game object. At the start of the game the enemies will be spawned at every 2.5 sec and enemies also move at every 2.5 sec. During game play that timer will be reduced depends on the score. I’m counting timer in FixedUpdate() and compare it with a static variable that exist inside the ExpSpawner. Let’s assume 30 enemies are spawned and moving every 2 seconds. And when the timer change a few numbers of enemies got wrong timer value and move at different speed but all the rest are doing well. If there’s no timer changing feature or if I reset timer to zero ( not timer -= ExpSpawner.movSpawnTime; ), there is no such problem. And it doesn’t happen everytime the game is played. It’s very rare to happen. Didn’t FixedUpdate() get the correct value of ExpSpawner.movSpawnTime whenever the time change or is the logic wrong?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ExpSpawner : MonoBehaviour
{
public static float movSpawnTime = 2.5f;
public GameObject pfbEnemy;
public int poolSz;
public float initialXpos;
public float initialYPos;
public int spawnCount;
private int spawnCounter;
private float spawnTimer;
private float reducer = 0.25f;
private List<GameObject> pool;
void Awake()
{
pool = new List<GameObject>();
for (int i = 0; i < poolSz; i++)
{
GameObject obj = Instantiate(pfbEnemy);
obj.SetActive(false);
pool.Add(obj);
}
}
void OnEnable()
{
ExpScore.LevelUp += OnLevelUp;
}
void FixedUpdate()
{
if (spawnCount != -1 && spawnCounter > spawnCount) return;
if (spawnTimer < movSpawnTime)
{
spawnTimer += Time.fixedDeltaTime;
return;
}
for (int i = 0; i < 8; i++)
{
GameObject obj = GetFromPool();
obj.transform.position = new Vector3(initialXpos + i, initialYPos);
obj.SetActive(true);
}
++spawnCounter;
spawnTimer -= movSpawnTime;
}
GameObject GetFromPool()
{
foreach (GameObject obj in pool)
{
if (!obj.activeInHierarchy) return obj;
}
GameObject enemy = Instantiate(pfbEnemy);
enemy.SetActive(false);
pool.Add(enemy);
return enemy;
}
void OnDisable()
{
ExpScore.LevelUp -= OnLevelUp;
}
void OnLevelUp()
{
movSpawnTime -= reducer;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class ExpEnemy : MonoBehaviour
{
public static event Action EnemyLost;
public float timer;
// public float movSpTime;
// public List<string> movSpList = new List<string>();
public static int serial = 0;
public Rigidbody2D rb2d;
void Awake()
{
gameObject.name = "Enemy_" + ++serial;
}
void FixedUpdate()
{
if (timer < ExpSpawner.movSpawnTime)
{
timer += Time.fixedDeltaTime;
return;
}
rb2d.MovePosition(rb2d.position + Vector2.down);
timer -= ExpSpawner.movSpawnTime;
// movSpTime = ExpSpawner.movSpawnTime;
// movSpList.Add("Spawn time : " + ExpSpawner.movSpawnTime + " at " + Time.frameCount + ", timer = " + timer);
// print("Reset time : " + timer);
}
void OnCollisionEnter2D(Collision2D other)
{
gameObject.SetActive(false);
EnemyLost?.Invoke();
}
void OnDisable()
{
timer = 0f;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class ExpScore : MonoBehaviour
{
public static event Action LevelUp;
private int score;
private int level;
private int[] levelUpScore = { 10, 20, 30, 40, 50, 60 };
void OnEnable()
{
ExpEnemy.EnemyLost += OnEnemyLost;
}
void OnDisable()
{
ExpEnemy.EnemyLost -= OnEnemyLost;
}
void OnEnemyLost()
{
++score;
if (level >= levelUpScore.Length) return;
if (score >= levelUpScore[level])
{
++level;
LevelUp?.Invoke();
}
}
}