I’ve gotten a functional zombie in my game, he’ll chase me when I’m in range and I can shoot and kill him. However, when I saved him as a prefab and started dropping more into the scene, I got some problems.
1.) Shooting one zombie affects every zombie
2.) When I trigger the aggro cube for zombie (2), zombie (2) and (3) run in place while zombie (1) enables nav agent and runs toward me.
I think the problems might have to do with the health integer and aggro boolean being static, but if I remove the static part I can’t access them from other scripts, and I get the error “an object reference is required for the non-static field/method/property ‘zombie.Health’”
Main Zombie Code
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
using Random = UnityEngine.Random;
public class Zombie : MonoBehaviour
{
Animator Anim;
public AudioSource zombieDeath;
public AudioSource[] zombieDeathArray;
public bool neverDone = true;
bool neverAggro = true;
public int health = 5;
public static bool Aggro = false;
// Start is called before the first frame update
void Start()
{
Anim = GetComponent<Animator>();
zombieDeath = zombieDeathArray[Random.Range(0, zombieDeathArray.Length)];
}
// Update is called once per frame
void Update()
{
if (health <= 0) {
if (neverDone == true)
{
PlayRandomDeathAudio();
gameObject.GetComponent<NavMeshAgent>().enabled = false;
Aggro = false;
Anim.SetBool("Z_death_A", true);
neverDone = false;
}
}
if (Aggro == true && health >0)
{
if (neverAggro == true)
{
gameObject.GetComponent<NavMeshAgent>().enabled = true;
Debug.Log("ZombieAggro!");
Anim.SetBool("Z_run", true);
neverAggro = false;
}
}
}
void PlayRandomDeathAudio()
{
if (ZombieShotBody.zombieHurt.isPlaying)
{
ZombieShotBody.zombieHurt.Stop();
}
if (AggroBoxScript.zombieAggro.isPlaying)
{
AggroBoxScript.zombieAggro.Stop();
}
zombieDeath = zombieDeathArray[Random.Range(0, zombieDeathArray.Length)];
zombieDeath.Play();
}
}
The Damage Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ZombieShotBody : MonoBehaviour
{
public static AudioSource zombieHurt;
public AudioSource[] zombieHurtArray;
public int damage = 1;
// Start is called before the first frame update
void Start()
{
zombieHurt = zombieHurtArray[Random.Range(0, zombieHurtArray.Length)];
}
// Update is called once per frame
void Update()
{
}
void OnTriggerEnter(Collider bullet)
{
if (bullet.gameObject.tag == "bullet")
{
Zombie.health -= damage;
Debug.Log(Zombie.health);
Destroy(bullet.gameObject);
if (Zombie.health > 0)
{
PlayRandomHurtSound();
}
}
}
void PlayRandomHurtSound()
{
// if (zombieAttack.isPlaying)
// {
// zombieAttack.Stop();
// }
if (AggroBoxScript.zombieAggro.isPlaying)
{
AggroBoxScript.zombieAggro.Stop();
}
zombieHurt = zombieHurtArray[Random.Range(0, zombieHurtArray.Length)];
zombieHurt.Play();
}
}
Here’s the NPCmove script too, in case that’s where the nav problem is coming from
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class NPCMove : MonoBehaviour
{
[SerializeField] Transform _destination;
NavMeshAgent _navMeshAgent;
// Start is called before the first frame update
void Start()
{
_navMeshAgent = this.GetComponent<NavMeshAgent>();
if (_navMeshAgent == null)
{
Debug.LogError("Navmesh agent not attached to " + gameObject.name);
}
else
{
// SetDestination();
}
}
// Update is called once per frame
void Update()
{
if (Zombie.Aggro == true && Zombie.health > 0)
{
if (_destination.hasChanged)
{
_navMeshAgent.SetDestination(_destination.position);
_destination.hasChanged = false;
}
}
}
private void SetDestination()
{
if (_destination != null)
{
Vector3 targetVector = _destination.transform.position;
_navMeshAgent.SetDestination(targetVector);
}
}
}
My goal is to have every zombie behave independently, with separate health and navigation.