Decrementing a variable in a script in which it was not declared.
I am trying to control the number of enemies that can be in my game at any given time. Within the script that controls spawning I have a public static variable named enemyCount (the script is attached to multiple objects) that is incremented by 1 every time an enemy is spawned, and when enemyCount reaches the maximum allowed enemies then enemies stop spawning. How can I decrement this variable by 1 within my script that controls when an enemy loses health and ultimately dies? Everything I have tried up to this point has given me a NullReferenceException: Object reference not set to an instance of an object.
I have left in an example of what I tried to decrement the value, and that gave me the exception.
Script that controls enemy spawn: public class SpawnerManager : MonoBehaviour { public PlayerHealth playerHealth; public GameObject enemy; public Transform spawnPoint;
public float spawnTime;
private static int enemyCount = 1;
public int EnemyCount
{
get { return enemyCount; }
set { enemyCount += value; }
}
private void OnEnable()
{
StartCoroutine(ExecuteAfterTime());
}
IEnumerator ExecuteAfterTime()
{
spawnTime = Random.Range(3, 7);
yield return new WaitForSeconds(spawnTime);
if (enemyCount < 5)
{
Instantiate(enemy, spawnPoint.position, spawnPoint.rotation);
enemyCount++;
}
StartCoroutine(ExecuteAfterTime());
}
}
Script that controls enemy health, death, etc: public class EnemyHealth : MonoBehaviour { public int startingHealth = 100; public int currentHealth; public float sinkSpeed = 2.5f; public int scoreValue = 10;
public AudioClip deathClip;
Animator anim;
AudioSource enemyAudio;
ParticleSystem hitParticles;
CapsuleCollider capsuleCollider;
SpawnerManager spawnerManager;
private bool isDead;
private bool isSinking;
void Awake ()
{
anim = GetComponent <Animator> ();
enemyAudio = GetComponent <AudioSource> ();
hitParticles = GetComponentInChildren <ParticleSystem> ();
capsuleCollider = GetComponent <CapsuleCollider> ();
spawnerManager = GetComponent<SpawnerManager>();
currentHealth = startingHealth;
}
void Update ()
{
if(isSinking)
{
transform.Translate (-Vector3.up * sinkSpeed * Time.deltaTime);
}
}
public void TakeDamage (int amount, Vector3 hitPoint)
{
if(isDead)
return;
enemyAudio.Play ();
currentHealth -= amount;
hitParticles.transform.position = hitPoint;
hitParticles.Play();
if(currentHealth <= 0)
{
Death ();
}
}
public void Death ()
{
isDead = true;
capsuleCollider.isTrigger = true;
anim.SetTrigger ("Dead");
enemyAudio.clip = deathClip;
enemyAudio.Play ();
spawnerManager.EnemyCount = -1;
}
public void StartSinking ()
{
GetComponent <UnityEngine.AI.NavMeshAgent> ().enabled = false;
GetComponent <Rigidbody> ().isKinematic = true;
isSinking = true;
ScoreManager.score += scoreValue;
Destroy (gameObject, 2f);
}
}
Answer by UnityCoach · Mar 01, 2017 at 08:55 PM
As this is a static property, you need to access it at class level, not instance level. You probably meant to write :
SpawnerManager.EnemyCount = -1;
instead of
spawnerManager.EnemyCount = -1;
as spawnerManager
is obviously an instance of SpawnerManager
Sorry, I misread you code.
In fact, what appears odd to me is this :
public int EnemyCount
{
get { return enemyCount; }
set { enemyCount += value; }
}
I would expect that :
public int EnemyCount
{
get { return enemyCount; }
set { enemyCount = value; }
}
And then :
spawner$$anonymous$$anager.EnemyCount -= 1;
Thank you! This fixed it.
I have set { enemyCount += value; } so that the value that the variable enemyCount is set to has 1 subtracted from it when an enemy dies. If set { enemyCount = value; } then enemyCount becomes -1 and will essentially allow infinite enemy spawns as long as the player keeps killing them because enemyCount will never reach the value for the maximum number of enemies.