Search Unity

SetActive won't work

Discussion in 'Scripting' started by VTepes, Jun 13, 2018.

  1. VTepes

    VTepes

    Joined:
    Jun 13, 2018
    Posts:
    2
    I have some code that activates attack collision when certain sprites are played during the attack animation. The code works with the player character (attack hitboxes appear), but not with enemies (attack hitboxes don't appear at all) . There are no error messages in the console. Here is the code:

    Code (CSharp):
    1. public GameObject spriteObject;
    2. public GameObject attack1Box, attack2Box, attack3Box;
    3. public Sprite attack1SpriteHitFrame, attack2SpriteHitFrame, attack3SpriteHitFrame;
    4. void Awake ()
    5.      {
    6.          navMeshAgent = GetComponent<NavMeshAgent> ();
    7.          enemySight = GetComponent<EnemySight> ();
    8.          enemyWalk = GetComponent<EnemyWalk> ();
    9.          enemyState = GetComponent <EnemyState> ();
    10.          animator = spriteObject.GetComponent<Animator> ();
    11.      }
    12.      void Update ()
    13.      {
    14.          currentSprite = spriteObject.GetComponent<SpriteRenderer> ().sprite;
    15.          if (enemyState.currentState == EnemyState.currentStateEnum.attack)
    16.              Attack ();
    17. void Attack()
    18.      {
    19.          navMeshAgent.ResetPath ();
    20.          if (attack1SpriteHitFrame == currentSprite)
    21.          {
    22.              attack1Box.gameObject.SetActive (true);
    23.          }
    24.          else if (attack2SpriteHitFrame == currentSprite)
    25.          {
    26.              attack2Box.gameObject.SetActive (true);
    27.          }
    28.          else if (attack3SpriteHitFrame == currentSprite)
    29.          {
    30.              attack3Box.gameObject.SetActive (true);
    31.          }
    32.          else
    33.          {
    34.              attack1Box.gameObject.SetActive (false);
    35.              attack2Box.gameObject.SetActive (false);
    36.              attack3Box.gameObject.SetActive (false);
    37.          }
    38.      }
    This question on Unity Answers: https://answers.unity.com/questions/1517781/setactive-wont-work.html
     
  2. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,196
    First, calling GetComponent within Update is pretty expensive. It's probably not causing your issue, but it's something to avoid doing. Instead, in Start, you should set a private property's value to `spriteObject.GetComponent<SpriteRenderer> ()`, and then access the `sprite` of that object in your Update loop.

    Put some breakpoints or debug statements into your code. Maybe you're never calling Attack. Maybe currentSprite isn't what you think it will be.

    Also, that 'else' looks a bit off to me. Although perhaps unlikely in your case, that code would allow attack1Box to remain active while attack2Box if currentSprite changes from 1 to 2 in a single frame. I assume you don't want multiple attack boxes active at once? Maybe something like this is better?

    Code (CSharp):
    1. attack1Box.gameObject.SetActive (attack1SpriteHitFrame == currentSprite);
    2. attack2Box.gameObject.SetActive (attack2SpriteHitFrame == currentSprite);
    3. attack3Box.gameObject.SetActive (attack3SpriteHitFrame == currentSprite);
    That would ensure the boxes are only active when the current sprite is the one you're expecting.
     
  3. VTepes

    VTepes

    Joined:
    Jun 13, 2018
    Posts:
    2
    Thank you for your help, but, as it turns out, the problem was in an entierly different script.You see, I have several AI scripts, united by a state machine script. In it I have an enum variable, that determines the logical state of the enemy:

    Code (CSharp):
    1. public enum currentStateEnum { idle=0, walk=1, attack=2};
    2.      public currentStateEnum currentState;
    3.      public GameObject spriteObject;
    4.      SpriteRenderer currentSprite;
    When I checked the Inspector I saw that "idle" and "walk" state do activate with proper animations, but when the enemy got in range, attack animations play in "idle" state without activating the "attack" state, and thus, not activating the hitboxes. I think this is the part of the code I need to fix:

    Code (CSharp):
    1. void Update ()
    2.     {
    3.         if (enemySight.playerInSight == true && enemySight.targetDistance < enemyAttack.attackRange && navMeshAgent.velocity.sqrMagnitude < enemyAttack.attackStartDelay)
    4.         {
    5.             animator.SetBool ("Attack", true);
    6.             animator.SetBool ("Walk", false);
    7.         }
    8.  
    9.         else if (enemySight.playerInSight == true)
    10.         {
    11.             animator.SetBool ("Attack", false);
    12.             animator.SetBool ("Walk", true);
    13.         }
    14.         else if (enemySight.playerInSight == false)
    15.         {
    16.             animator.SetBool ("Attack", false);
    17.             animator.SetBool ("Walk", false);
    18.         }
    19.  
    20.         if (currentAnimState == idleState)
    21.         {
    22.             currentState = currentStateEnum.idle;
    23.         }
    24.         else if (currentAnimState == walkState)
    25.         {
    26.             currentState = currentStateEnum.walk;
    27.         }
    28.         else if (currentAnimState == attack1State)
    29.         {
    30.             currentState = currentStateEnum.attack;
    31.         }
    32.  
    33.         currentStateInfo = animator.GetCurrentAnimatorStateInfo (0);
    34.         currentAnimState = currentStateInfo.fullPathHash;
    35.     }
     
  4. Riukensay

    Riukensay

    Joined:
    Jan 16, 2018
    Posts:
    49
    you can use a breakpoint to see the values into "ifs". it can help you to see the problem
     
    Doug_B likes this.