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

Trigger is not working

Discussion in 'Animation' started by tarzanno, Jun 4, 2015.

  1. tarzanno

    tarzanno

    Joined:
    Apr 23, 2015
    Posts:
    58
    Hi
    I have problem with triggers and scripting the object, so the animator work as I want it to.
    This is the script:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.UI;
    4.  
    5. public class EnemyHealth : MonoBehaviour {
    6.  
    7.     public  int startingHealth = 10;
    8.     public int currentHealthEnemy;
    9.     public Image damageImage;
    10.     public AudioClip deathClip;
    11.     public float flashSpeed = 5f;
    12.     public Color flashColour = new Color(1f, 0f, 0f, 0.1f);
    13.     public int scoreValue = 10;
    14.  
    15.     AnimationClip clip;
    16.     Animator anim;
    17.     AudioSource enemyAudio;
    18.     ParticleSystem hitParticles;
    19.     BoxCollider2D boxCollider2D;
    20.     public Sword sword;
    21.     PolygonCollider2D polygonCollider2D;
    22.     GameObject enemy;
    23.     bool isDead;
    24.     bool damaged;
    25.     private Animator animator;
    26.  
    27.  
    28.     void Awake ()
    29.     {
    30.         //Seeting up the references
    31.         enemy = GameObject.FindGameObjectWithTag ("Enemy");
    32.         boxCollider2D = GetComponent <BoxCollider2D> ();
    33.         currentHealthEnemy = startingHealth;
    34.  
    35.  
    36.         anim = GetComponent <Animator> ();         //można przenieść do start()
    37.         enemyAudio = GetComponent <AudioSource> ();
    38.         hitParticles = GetComponentInChildren <ParticleSystem>();
    39.      
    40.      
    41.  
    42.     }
    43.  
    44.     void OnTriggerEnter2D(Collider2D other)
    45.     {
    46.         if(other.name== "sword")
    47.         {
    48.             polygonCollider2D = sword.GetComponent <PolygonCollider2D>();
    49.             damageImage.color = flashColour;
    50.             damaged=true;
    51.  
    52.         }
    53.  
    54.         else{
    55.             return;
    56.         }
    57.     }
    58.  
    59.     void Start()
    60.     {
    61.         //setting up initial health
    62.  
    63.         Debug.Log(enemy);
    64.         Debug.Log(this);
    65.         if (boxCollider2D.isTrigger == true){
    66.         GameObject go = GameObject.FindWithTag("DamageImage");
    67.         damageImage = go.GetComponent<Image>();
    68.      
    69.         }
    70.         else{
    71.             return;
    72.         }
    73.  
    74.     }
    75.     void Update()
    76.     {
    77.  
    78.  
    79.         //if the enemy has just been damaged...
    80.         if(damaged)
    81.         {
    82.             damageImage.color = flashColour;
    83.  
    84.      
    85.         }
    86.  
    87.         else
    88.         {
    89.             damageImage.color = Color.Lerp (damageImage.color, Color.clear, flashSpeed * Time.deltaTime);
    90.         }
    91.  
    92.  
    93.         damaged = false;
    94.  
    95.     }
    96.  
    97.     public void TakeDamage (int amount)
    98.     {
    99.         damaged = true; //błyskanie
    100.         currentHealthEnemy -= amount;
    101.  
    102.         enemyAudio.Play ();
    103.  
    104.  
    105.         if(currentHealthEnemy <= 0 && isDead)
    106.         {
    107.             Death ();
    108.         }
    109.     }
    110.  
    111.     void Death ()
    112.     {
    113.         Destroy (enemy.gameObject);
    114.         isDead = true;
    115.         //boxCollider2D.isTrigger = true;
    116.         anim.SetTrigger ("enemyDead");
    117.         enemyAudio.clip = deathClip;
    118.         enemyAudio.Play ();
    119.  
    120.  
    121.      
    122.     }
    123.  
    124.     public Animator GetAnimator()
    125.     {
    126.         return animator;
    127.     }
    128.  
    129. }
    130.  
    As you can see, when the Death() method is being run, it should trigger the "enemyDead" animation, but it didn't.
    This is how it looks inside the animator:



    The Game Object. Is Active is being active in next frame of animation, so the other sprite is visible.


    I bet there is some simple solution for that, but none tutorial helped me with it.

    enemyIdle state is running, but when the enemy is killed, the enemyDead state is not triggered.
     
  2. Mecanim-Dev

    Mecanim-Dev

    Unity Technologies

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    Your transition is setup with an Exit time, which mean that you can only enter enemyDead state when you trrigger is set to true and you idle animation current time is greater than this exit time. Uncheck 'Has Exit Time' to allow this transition to occur at any moment while playing enemyIdle.
     
    bmayaux and hallarazad like this.
  3. tarzanno

    tarzanno

    Joined:
    Apr 23, 2015
    Posts:
    58
    Unfortunately, it makes enemyDead animation start when I'm starting the game. EnemyIdle is starting and is being played just once, and enemyDead animation keeps playing on and on (and is starting when the enemyIdle is starting).
     
  4. Mecanim-Dev

    Mecanim-Dev

    Unity Technologies

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    Maybe because your trigger default value is set to true?
     
  5. tarzanno

    tarzanno

    Joined:
    Apr 23, 2015
    Posts:
    58
    1. I don't know why this script is not running Death() method. It just don't work.
    2. When I put "anim.SetTrigger ("enemyDead");" into Update() -> if (damaged) { _here_ }, then the animation is running.
    3. Method TakeDamage() is working, because I can see that the currentHealth is changing, but
    Code (CSharp):
    1.     if(currentHealthEnemy <= 0 && isDead)
    2.         {
    3.             Death ();
    4.         }
    is not working. I don't know why.
    4. Can I make the animation enemyDead play just once, then destroy the object Enemy, but leave some (let's call it EnemyCorpse) sprite on a ground withing animation?
     
  6. Swearsoft

    Swearsoft

    Joined:
    Mar 19, 2009
    Posts:
    1,632
    if(currentHealthEnemy <= 0 && isDead)

    to

    if(currentHealthEnemy <= 0 && !isDead)

    In start put

    isDead = false;
     
    tarzanno likes this.
  7. Swearsoft

    Swearsoft

    Joined:
    Mar 19, 2009
    Posts:
    1,632
    4. Ofcourse, you can create a state with the desired corpse 'animation' that loops after leaving enemyDead (so enemyDead should be enemyDying) or you can trigger or time the destruction of the current object and the creation of a new one. There are countless ways to set this up.
     
    tarzanno likes this.
  8. tarzanno

    tarzanno

    Joined:
    Apr 23, 2015
    Posts:
    58
    Thank you for this solution. It works perfectly, but I have further problem.

    Everything works fine with object, that I put in the scene myself, but for a prefab the currentHealthEnemy is not shrinking, when collider triggers it (collider from another object triggers it, I checked).

    Looks like it shouldn't be public int, only private (because if public, then this variable is the same for every "clone" of a prefab that is spawned?) but I need it to be public, because other scripts are using this variable.

    If I am right, is there any way to solve this?