All enemies taking damage rather than the single instance (csh

Hey all,

I’ve got a script which shoots a RayCast at an enemy, this is then meant to reduce a set amount of damage from the health script associated with that enemy. However currently, it is reducing the health of all enemies and I can’t see why (from what I can tell I am telling it to damage only the instance of the object).

Weapon Shooting script (You’ll want to look at the “private void fire()” section:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

[RequireComponent(typeof(AudioSource))]

public class WeaponShooting : MonoBehaviour
{

    private Animator animate;

    public int bulletsPerMag = 30;
    public int maxBullets = 300;
    public int bulletsLeft = 200;
    public int currentBullets;

    public int shootDamage = 5;

    public float range = 50f;
    public float fireRate = 0.1f;

    public Transform shootPoint;
    public GameObject flash;
 
    float fireTimer;

    public AudioClip akshoot;      
    public AudioClip akreload;
    public AudioSource AudioSource;
    public bool reloadisrunning;

    public Text ammoRemaining;

    public EnemyHealth enemyHealthScript;



    // Use this for initialization
    void Start()
    {

        animate = GetComponent<Animator>();
        currentBullets = bulletsPerMag;
        AudioSource = GetComponent<AudioSource>();
        SetInitialReferences();
  
  
    }

    void SetInitialReferences() {

        ammoRemaining = GameObject.Find("Ammo Remaining").GetComponent<Text>();

    }


    // Update is called once per frame
    void Update()
    {

         if(Input.GetKeyDown(KeyCode.Mouse0))

        {
            Fire(); // Executes the fire function if the mouse button is pressed or held.
        }

        if (fireTimer < fireRate)
            fireTimer += Time.deltaTime;

        if (currentBullets <= 0 || Input.GetKey(KeyCode.R) && reloadisrunning == false)
        {
            if (bulletsLeft >= 1 && currentBullets != 30)
            {
                PlayReloadSound();
            }
            StartCoroutine(reloadWait());

        }

        ammoCountUI();


    }


    void ammoCountUI()
    {
        string bulletsLeftS = bulletsLeft.ToString();
        string currentBulletsS = currentBullets.ToString();
        ammoRemaining.text = currentBulletsS + "/" + bulletsLeftS;
    }


    void FixedUpdate()
    {
        AnimatorStateInfo info = animate.GetCurrentAnimatorStateInfo(0);

        if (info.IsName("Fire")) animate.SetBool("Fire", false);
    }



    /// ----------------------------------- Firing the Gun -------------------------------------------------


    private void Fire()

    {
        if (fireTimer < fireRate) return; // This returns to the update



     [B]  if (currentBullets >= 1 && reloadisrunning == false)
        {

            StartCoroutine(flashOn());
            RaycastHit hit;

            if (Physics.Raycast(shootPoint.position, shootPoint.transform.forward, out hit, range))
            {
                if (hit.rigidbody.gameObject.layer == LayerMask.NameToLayer("Enemy"))
              
                        {

                    enemyHealthScript = hit.collider.gameObject.GetComponent<EnemyHealth>();

                    if (enemyHealthScript != null)
                    {
                        enemyHealthScript.dtak47();
                    }[/B]



                        }
              
      
            }

            currentBullets--;
            animate.CrossFadeInFixedTime("Fire", 0.01f); // Play the fire animation
            animate.SetBool("Fire", true);      


        }


        fireTimer = 0.0f; // This resets the fire timer
    }

    private void PlayShootSound()
    {
        AudioSource.clip = akshoot;
        AudioSource.Play();
    }


    IEnumerator flashOn() //Muzzle Flash
    {
            flash.SetActive(true);
            Debug.Log("flashOff");
        PlayShootSound();
        yield return new WaitForSeconds(0.15f);
            Debug.Log("Timeup");
            flash.SetActive(false);
        if (Input.GetButton("Fire1"))
        {
            Fire();
        }
 
    }

    /// ----------------------------------- Reloading the Gun -------------------------------------------------

    private void PlayReloadSound()
    {
        AudioSource.clip = akreload;
        AudioSource.Play();
    }

    IEnumerator reloadWait() //wait timer so that gun is not reloaded before the sound effectends
    {
        Debug.Log("wait start");
        reloadisrunning = true;
        yield return new WaitForSeconds(2f);
        reloadisrunning = false;
        Debug.Log("wait end");
        Reload();
    }

    private void Reload()
    {
        if (bulletsLeft >= bulletsPerMag)
        {
            if (currentBullets == 0)
            {

                bulletsLeft = (bulletsLeft -= bulletsPerMag);
                currentBullets = bulletsPerMag;
            }

            else if (currentBullets != 0)
            {
                bulletsLeft = (bulletsLeft - (bulletsPerMag - currentBullets));
                currentBullets = bulletsPerMag;
            }

      
        }


        else if (bulletsLeft <= bulletsPerMag)

        {

            if (currentBullets == 0)
            {
                currentBullets = bulletsLeft;
                bulletsLeft = 0;
          

            }

            if (currentBullets != 0)
            {

                int dif = currentBullets + bulletsLeft;
                bulletsLeft = (bulletsLeft - (bulletsPerMag - currentBullets));
                currentBullets = dif;

            }

            if (bulletsLeft <= 0)
            {
                bulletsLeft = 0;
            }

            if (currentBullets >= bulletsPerMag)

            {
                currentBullets = bulletsPerMag;

            }

            if (currentBullets <= 0)
            {
                currentBullets = 0;
            }



        }
    }
}

Health Script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemyHealth : MonoBehaviour {

    public float health;
    public int ak47damage = 10;
    public EnemyHealth Instance;


    // Use this for initialization
    void Start()
    {

        SetInitialReferences();
        health = 100;

    }

    // Update is called once per frame
    void Update()
    {

        if (health < 1)
        {
            health = 0;
        }

        if (health > 99)
        {
            health = 100;
        }

    }

    void SetInitialReferences()
    {
        Instance = this;
    }

    public void dtak47()
    {
        this.health -= ak47damage;
    }

}

Any help would be appreciated.

OK, I’m not sure on this, but your code basically looks all right, so I wonder if it’s when you declare an instance for EnemyHealth. Maybe it’s making a singleton. I don’t know a lot about singletons so maybe that’s a mile off. This is the code for a singleton, but the singleton code is sometimes hidden.

    public static EquipmentManager instance;

    private void Awake()
    {
        instance = this;
    }
1 Like

I think @fire7side is on the right track. You are setting up a single instance of EnemyHealth (singleton pattern) which is getting applied to all enemies.

I do not think that is the problem. Actually, I cannot be sure how this script is affecting every enemy.
I can say this, though… your ‘Instance’ variable on the enemyscript doesn’t appear to be doing anything that I can see. Unless that is being called somewhere I didn’t see, you may as well remove it.

An additional note: you’d be better off moving your health > 99 and < 0 to the method that takes damage, and deleting your update function , until there is actual code to run there.

note: his declaration isn’t ‘static’ , so it’s not really a singleton in design. The variable instance, as a member (which isn’t static), doesn’t make a lot of sense, because you’d first have to find the instance, then accessing that member would be the same thing (you already had, with the instance).

Thanks everyone, and thanks methos5k for the code tidy up, that makes a lot more sense.

I’m still trying to rack my head around why on earth it’s deducting from all scripts, as you mentioned it’s not static and I’m retrieving the script component each time the RayCast hits and enemy.

I agree with @methos5k . I couldn’t figure out from what was posted that anything was off in this script, so I thought I may have just overlooked something.

Do you have any other scripts on the enemies? Or even anything else in the scene that may create issues.

You may just have to start inserting debug statements and seeing what you’re hitting, (see what hit.gameobject is for example). Insert one in the damage log, see how many times it prints out, etc. Best way to start tracking it down.

What may be happening is in the weapon script you have:

 public EnemyHealth enemyHealthScript;

If you dragged the script from project into that slot in the inspector, it might not change when you accessed it from the component. I’m not sure if that would even work, though.

I would get rid of the instance code in EnemyHealth, it doesn’t make sense.