Invoking

Hi i need a bit of help… at the moment i have a script SHOOT.cs

using UnityEngine;
using System.Collections;

public class Shoot : MonoBehaviour
{
    public GameObject Shootpoint;
    private RaycastHit hit;

    private float range = 600f;
    private float fireRate = 0.6f;
    private float nextFire;
    private Enemy_AI enemy_aiScript;

    void Start()
    {
       
    }
    void Update()
    {
        CheckInput ();
        Invoke ("CheckZombie", 2);
    }
    void CheckZombie()
    {
        enemy_aiScript = GameObject.Find("Zombie").GetComponent<Enemy_AI>;
    }
    void CheckInput ()
    {
        //checking the button and firerate
        if (Input.GetButton ("Fire1")&&Time.time>nextFire)
        {
            //adding to firerate
            nextFire = Time.time + fireRate;
            //to see the raycast
            Debug.DrawRay (Shootpoint.transform.TransformPoint (0, 0, 1), Shootpoint.transform.forward, Color.green, 10);

            //creating raycast
            if (Physics.Raycast (Shootpoint.transform.TransformPoint (0, 0, 1), Shootpoint.transform.forward, out hit, range))
            {
                //checking if Zombie is hit
                if (hit.transform.CompareTag ("Zombie"))
                {
                    Debug.Log ("Zombie " + enemy_aiScript.ZomCurHealth);
                    enemy_aiScript.Damage (10);


                } else
                {
                    Debug.Log ("Not Zombie " + hit.transform.name);
                }
            }

        }
    }
}

what i am trying to do is access the zombie script. so that each time a raycast hits it does damge10

using UnityEngine;
using System.Collections;

public class Enemy_AI : MonoBehaviour
{
    public float enemyLookDistance;
    public float attackDistance;
    public float enemyMoveSpeed;
    public float enemyRotSpeed;

    //zombie health
    public float ZomMaxHealth = 100;
    public float ZomCurHealth = 100;


    //brainPrefab.
    public GameObject zombieBrain;
    //private static zombie instance;

    private Transform target;
    //private Renderer myRender;
    private Animator anim;


    void Awake()
    {
        anim = GetComponent<Animator> ();
        //myRender = GetComponent<Renderer> ();
        ZomCurHealth = ZomMaxHealth;
    }



    // Update is called once per frame
    void Update ()
    {
       
        //make sure the player exists
        if (target == null)
        {
            target = Player.GetTransform();

            if (target == null)
            {
                //default to wander aimlessly if there is no player
                Wander();
                return;
            }
        }

        float fpsTargetDistance = Vector3.Distance (target.position, transform.position);

        if (fpsTargetDistance < attackDistance)
        {
            ChasePlayer ();
            return;
        }

        if (fpsTargetDistance < enemyLookDistance)
        {
            Alerted();
            return;
        }
           
        //default to Wander mode
        Wander ();
    }

    public void Damage(float amount)
    {
        ZomCurHealth -= amount;

        if (ZomCurHealth <= 0)
        {
            GameObject brains = GameObject.Instantiate<GameObject> (zombieBrain);
            brains.transform.position = transform.position;
            brains.transform.rotation = Quaternion.identity;
            GameObject.Destroy(brains,20);


            Destroy (gameObject);
        }
    }

    void Alerted()
    {
        anim.Play ("Walk1", 0);
        //myRender.material.color = Color.yellow;
        Quaternion rotation = Quaternion.LookRotation (target.position - transform.position);
        transform.rotation = Quaternion.Slerp (transform.rotation, rotation, Time.deltaTime * enemyRotSpeed);
        transform.position += transform.forward * 1 * Time.deltaTime;

    }
    //chase the player
    void ChasePlayer ()
    {
        anim.Play ("Run2", 0);
        //myRender.material.color = Color.red;
        Quaternion rotation = Quaternion.LookRotation (target.position - transform.position);
        transform.rotation = Quaternion.Slerp (transform.rotation, rotation, Time.deltaTime * enemyRotSpeed);
        transform.position += transform.forward * enemyMoveSpeed * Time.deltaTime;

    }

    //wandering
    void Wander ()
    {
        //var
        float heading;
        Vector3 targetRotation;

        //script
        heading = Random.Range(0, 360);
        transform.eulerAngles = new Vector3(0, heading, 0);
        targetRotation = new Vector3(0, heading, 0);


        //Quaternion rotation = Quaternion.LookRotation (heading);
        //transform.rotation = Quaternion.Slerp (transform.rotation, rotation, Time.deltaTime * enemyRotSpeed);
        transform.eulerAngles = Vector3.Slerp(transform.eulerAngles, targetRotation, Time.deltaTime * 5);
        transform.position += transform.forward * 1 * Time.deltaTime;

        //Play The Animation
        anim.Play ("Idle", 0);
    }

}

Aren’t you doing that already on line 44?

Yes that is correct but… it keeps telling me, i have to invoke and its not working.

    Invoke ("CheckZombie", 2);
    }
    void CheckZombie()
    {
        enemy_aiScript = GameObject.Find("Zombie").GetComponent<Enemy_AI>;
    }

is the code that is giving me an issue

Does this even compile? I would expect it to fail on this line:

    enemy_aiScript = [URL='http://unity3d.com/support/documentation/ScriptReference/30_search.html?q=GameObject']GameObject[/URL].[URL='http://unity3d.com/support/documentation/ScriptReference/30_search.html?q=Find']Find[/URL]("Zombie").GetComponent<Enemy_AI>;

because you have left the () off your function call. It should be:

    enemy_aiScript = [URL='http://unity3d.com/support/documentation/ScriptReference/30_search.html?q=GameObject']GameObject[/URL].[URL='http://unity3d.com/support/documentation/ScriptReference/30_search.html?q=Find']Find[/URL]("Zombie").GetComponent<Enemy_AI>();

Next, I don’t understand what you’re trying to do here. The flow seems to be: check for input, which may make use of enemy_aiScript, and then 2 seconds later, call CheckZombie, which sets enemy_aiScript. This makes no sense.

So let’s take a step back. What are you trying to do here?

OK, I think I see what you’re doing. Delete the enemy_aiScript property, the CheckZombie method, and your Invoke call. Instead, when you detect a hit, just find the zombie script right there, on the thing that was hit:

                if (hit.transform.CompareTag ("Zombie")) {
                    Enemy_AI zom = hit.transform.GetComponent<Enemy_AI>();
                    Debug.Log ("Zombie " + zom.ZomCurHealth);
                    zom.Damage (10);

There are ways to make this more general, but I don’t want to be confusing, so try this for now and let us know how it goes!

What you are doing is very dangerous, Update is called in each frame, the function that you pass to the Invoke function is called after 2 seconds, then, if you have 30 frames per seconds will happen this

Frame 1: Update/Invoke is called
Frame 2: Update/Invoke is called

Frame 61: Update/Invoke and CheckZombie is called because passed 2 seconds and Invoke was called in Frame 1
Frame 62: Update/Invoke and CheckZombie is called because passed 2 seconds + 1 Frame and Invoke was called in Frame 2

I think that what you want is this:

void Start() {
    InvokeRepeating("CheckZombie", 0.0f, 2.0f);
}

Edit: The solution of JoeStrout make more sense.