Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Invoking

Discussion in 'Scripting' started by Custardcs, Mar 10, 2016.

  1. Custardcs

    Custardcs

    Joined:
    Aug 26, 2015
    Posts:
    57
    Hi i need a bit of help.. at the moment i have a script SHOOT.cs

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Shoot : MonoBehaviour
    5. {
    6.     public GameObject Shootpoint;
    7.     private RaycastHit hit;
    8.  
    9.     private float range = 600f;
    10.     private float fireRate = 0.6f;
    11.     private float nextFire;
    12.     private Enemy_AI enemy_aiScript;
    13.  
    14.     void Start()
    15.     {
    16.        
    17.     }
    18.     void Update()
    19.     {
    20.         CheckInput ();
    21.         Invoke ("CheckZombie", 2);
    22.     }
    23.     void CheckZombie()
    24.     {
    25.         enemy_aiScript = GameObject.Find("Zombie").GetComponent<Enemy_AI>;
    26.     }
    27.     void CheckInput ()
    28.     {
    29.         //checking the button and firerate
    30.         if (Input.GetButton ("Fire1")&&Time.time>nextFire)
    31.         {
    32.             //adding to firerate
    33.             nextFire = Time.time + fireRate;
    34.             //to see the raycast
    35.             Debug.DrawRay (Shootpoint.transform.TransformPoint (0, 0, 1), Shootpoint.transform.forward, Color.green, 10);
    36.  
    37.             //creating raycast
    38.             if (Physics.Raycast (Shootpoint.transform.TransformPoint (0, 0, 1), Shootpoint.transform.forward, out hit, range))
    39.             {
    40.                 //checking if Zombie is hit
    41.                 if (hit.transform.CompareTag ("Zombie"))
    42.                 {
    43.                     Debug.Log ("Zombie " + enemy_aiScript.ZomCurHealth);
    44.                     enemy_aiScript.Damage (10);
    45.  
    46.  
    47.                 } else
    48.                 {
    49.                     Debug.Log ("Not Zombie " + hit.transform.name);
    50.                 }
    51.             }
    52.  
    53.         }
    54.     }
    55. }
    56.  
    what i am trying to do is access the zombie script. so that each time a raycast hits it does damge10

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Enemy_AI : MonoBehaviour
    5. {
    6.     public float enemyLookDistance;
    7.     public float attackDistance;
    8.     public float enemyMoveSpeed;
    9.     public float enemyRotSpeed;
    10.  
    11.     //zombie health
    12.     public float ZomMaxHealth = 100;
    13.     public float ZomCurHealth = 100;
    14.  
    15.  
    16.     //brainPrefab.
    17.     public GameObject zombieBrain;
    18.     //private static zombie instance;
    19.  
    20.     private Transform target;
    21.     //private Renderer myRender;
    22.     private Animator anim;
    23.  
    24.  
    25.     void Awake()
    26.     {
    27.         anim = GetComponent<Animator> ();
    28.         //myRender = GetComponent<Renderer> ();
    29.         ZomCurHealth = ZomMaxHealth;
    30.     }
    31.  
    32.  
    33.  
    34.     // Update is called once per frame
    35.     void Update ()
    36.     {
    37.        
    38.         //make sure the player exists
    39.         if (target == null)
    40.         {
    41.             target = Player.GetTransform();
    42.  
    43.             if (target == null)
    44.             {
    45.                 //default to wander aimlessly if there is no player
    46.                 Wander();
    47.                 return;
    48.             }
    49.         }
    50.  
    51.         float fpsTargetDistance = Vector3.Distance (target.position, transform.position);
    52.  
    53.         if (fpsTargetDistance < attackDistance)
    54.         {
    55.             ChasePlayer ();
    56.             return;
    57.         }
    58.  
    59.         if (fpsTargetDistance < enemyLookDistance)
    60.         {
    61.             Alerted();
    62.             return;
    63.         }
    64.            
    65.         //default to Wander mode
    66.         Wander ();
    67.     }
    68.  
    69.     public void Damage(float amount)
    70.     {
    71.         ZomCurHealth -= amount;
    72.  
    73.         if (ZomCurHealth <= 0)
    74.         {
    75.             GameObject brains = GameObject.Instantiate<GameObject> (zombieBrain);
    76.             brains.transform.position = transform.position;
    77.             brains.transform.rotation = Quaternion.identity;
    78.             GameObject.Destroy(brains,20);
    79.  
    80.  
    81.             Destroy (gameObject);
    82.         }
    83.     }
    84.  
    85.     void Alerted()
    86.     {
    87.         anim.Play ("Walk1", 0);
    88.         //myRender.material.color = Color.yellow;
    89.         Quaternion rotation = Quaternion.LookRotation (target.position - transform.position);
    90.         transform.rotation = Quaternion.Slerp (transform.rotation, rotation, Time.deltaTime * enemyRotSpeed);
    91.         transform.position += transform.forward * 1 * Time.deltaTime;
    92.  
    93.     }
    94.     //chase the player
    95.     void ChasePlayer ()
    96.     {
    97.         anim.Play ("Run2", 0);
    98.         //myRender.material.color = Color.red;
    99.         Quaternion rotation = Quaternion.LookRotation (target.position - transform.position);
    100.         transform.rotation = Quaternion.Slerp (transform.rotation, rotation, Time.deltaTime * enemyRotSpeed);
    101.         transform.position += transform.forward * enemyMoveSpeed * Time.deltaTime;
    102.  
    103.     }
    104.  
    105.     //wandering
    106.     void Wander ()
    107.     {
    108.         //var
    109.         float heading;
    110.         Vector3 targetRotation;
    111.  
    112.         //script
    113.         heading = Random.Range(0, 360);
    114.         transform.eulerAngles = new Vector3(0, heading, 0);
    115.         targetRotation = new Vector3(0, heading, 0);
    116.  
    117.  
    118.         //Quaternion rotation = Quaternion.LookRotation (heading);
    119.         //transform.rotation = Quaternion.Slerp (transform.rotation, rotation, Time.deltaTime * enemyRotSpeed);
    120.         transform.eulerAngles = Vector3.Slerp(transform.eulerAngles, targetRotation, Time.deltaTime * 5);
    121.         transform.position += transform.forward * 1 * Time.deltaTime;
    122.  
    123.         //Play The Animation
    124.         anim.Play ("Idle", 0);
    125.     }
    126.  
    127. }
     
  2. Boz0r

    Boz0r

    Joined:
    Feb 27, 2014
    Posts:
    419
    Aren't you doing that already on line 44?
     
  3. Custardcs

    Custardcs

    Joined:
    Aug 26, 2015
    Posts:
    57
    Yes that is correct but.. it keeps telling me, i have to invoke and its not working.


    Code (CSharp):
    1.     Invoke ("CheckZombie", 2);
    2.     }
    3.     void CheckZombie()
    4.     {
    5.         enemy_aiScript = GameObject.Find("Zombie").GetComponent<Enemy_AI>;
    6.     }
    is the code that is giving me an issue
     
  4. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,848
    Does this even compile? I would expect it to fail on this line:

    Code (csharp):
    1.     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:
    Code (csharp):
    1.     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?
     
  5. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,848
    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:

    Code (CSharp):
    1.                 if (hit.transform.CompareTag ("Zombie")) {
    2.                     Enemy_AI zom = hit.transform.GetComponent<Enemy_AI>();
    3.                     Debug.Log ("Zombie " + zom.ZomCurHealth);
    4.                     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!
     
  6. dfsantos

    dfsantos

    Joined:
    Mar 3, 2016
    Posts:
    6
    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:

    Code (CSharp):
    1.  
    2. void Start() {
    3.     InvokeRepeating("CheckZombie", 0.0f, 2.0f);
    4. }
    5.  
    Edit: The solution of JoeStrout make more sense.
     
    Last edited: Mar 10, 2016