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. Voting for the Unity Awards are OPEN! We’re looking to celebrate creators across games, industry, film, and many more categories. Cast your vote now for all categories
    Dismiss Notice
  3. Dismiss Notice

Drop down list issue

Discussion in 'Scripting' started by davejones1, Aug 16, 2018.

  1. davejones1

    davejones1

    Joined:
    Jan 19, 2018
    Posts:
    183
    I have a UI drop down list that uses an animation state machine to drop down/fold up a submenu. The issue I am having is that when the list has been dropped down, and the GameObject is set inactive and than reactive the drop down doesn't work like it did before the GameObject was set inactive.

    I have listed below the issue in points

    - press UI button that plays drop down animation clip
    - press same UI button again and fold up animation clip is played
    - press UI button and drop down plays again
    - set GameObject active to false when the drop down clip has been played
    - Set GameObject to true whilst the list is dropped down
    - press button to try and fold up but doesn't work like before GameObject was set to false.

    I have attached the class used OnClick of the UI button below. I want the same behaviour that was apparent before the GameObject was set to false. The link is to a video that shows the issue.


    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class CustomDropDown : MonoBehaviour {
    6.  
    7.     public GameObject SubMenu;
    8.     [HideInInspector]
    9.     public int State = 0;
    10.  
    11.     Animator AniPlayer;
    12.  
    13.     public void BtnDropDown()
    14.     {
    15.         if (AniPlayer.GetInteger("MenuState") == 0)
    16.         {
    17.             AniPlayer.SetInteger("MenuState", 1);
    18.         }
    19.  
    20.  
    21.         else if (AniPlayer.GetInteger("MenuState") == 1)
    22.         {
    23.             AniPlayer.SetInteger("MenuState", 0);
    24.         }
    25.     }
    26.         // Use this for initialization
    27.         void Start() {
    28.             AniPlayer = this.GetComponent<Animator>();
    29.         }
    30.  
    31.     }
     
  2. Doug_B

    Doug_B

    Joined:
    Jun 4, 2017
    Posts:
    1,596
    From looking at your video, the animator is resetting after you re-enable it. The code you have above is taking the 'menu state' value from the animator.

    There is already a "state" int in the code. Could you not use that instead- would that fix the problem? Something like this maybe :-
    Code (CSharp):
    1. public class CustomDropDown : MonoBehaviour
    2. {
    3.     public int State { get; private set; }
    4.  
    5.     public void BtnDropDown()
    6.     {
    7.         State = 1 - State;
    8.         m_aniPlayer.SetInteger("MenuState", State);
    9.     }
    10.  
    11.     void Start()
    12.     {
    13.         State = 0;
    14.         m_aniPlayer = this.GetComponent<Animator>();
    15.     }
    16.  
    17. #pragma warning disable 649
    18.     [SerializeField] GameObject SubMenu;
    19. #pragma warning restore 649
    20.  
    21.     Animator m_aniPlayer;
    22. }
     
  3. davejones1

    davejones1

    Joined:
    Jan 19, 2018
    Posts:
    183
    I have tried this but the state machine seems to work the same as with the original code I have posted. When I disable/enable the GameObject the animator resets, rather than staying on the state it was in before it was disabled. Why is it you have added the pragma warning?
     
  4. Doug_B

    Doug_B

    Joined:
    Jun 4, 2017
    Posts:
    1,596
    Do you need to add a link in the controller from the default entry point directly to the "opened" state, or does the state machine have to go through the "closed" state first?

    I use it when dealing with values that will, or may, be set in the Editor. It keeps the compilation clean by preventing that particular warning. The warning suppression is restricted to only those lines with such variables (by disabling and then immediately restoring the warning) as it is generally advisable to not ignore warning messages.
     
  5. davejones1

    davejones1

    Joined:
    Jan 19, 2018
    Posts:
    183
    I don't want the state machine to go though the closed state first. I believe I want a link from the entry point to the opened state.
     
  6. Doug_B

    Doug_B

    Joined:
    Jun 4, 2017
    Posts:
    1,596
    Thinking about it, you may want to add an
    OnEnable()
    that sets the value of
    State
    in the animator to correctly restore its value.
     
  7. davejones1

    davejones1

    Joined:
    Jan 19, 2018
    Posts:
    183
    I have tried this but it didn't manage to solve the problem.
     
  8. davejones1

    davejones1

    Joined:
    Jan 19, 2018
    Posts:
    183
    Psuedocode

    onEnable

    menu state = current state

    OnDisable

    menu state = current state



    I suppose its just a case of finding out how to do this because I believe the issue is that the animation state machine resets on disabling/ re enabling of the GameObject.
     
  9. Doug_B

    Doug_B

    Joined:
    Jun 4, 2017
    Posts:
    1,596
    I agree. Try removing the
    OnDisable
    . There is no need for it if you are using code similar to that in post #2.
     
  10. davejones1

    davejones1

    Joined:
    Jan 19, 2018
    Posts:
    183
    It is recommended to use the Unity animation state for this. Or you could just check that the animation state is always equal to the class state.

    I am also looking into the state machines trigger parameter. The idea is that it is always checking the states to see if it can move to the next state. I am thinking of using the trigger parameter to check which state is currently being played and controlling this through a script.
     
  11. Doug_B

    Doug_B

    Joined:
    Jun 4, 2017
    Posts:
    1,596
    I think that, as a general rule, you would want your code to be driving the animation (state machine) rather than the other way round. Note, this sentiment is driven more by my own personal opinion than any cold hard facts. :)

    If you really want to drive the code from the animation, you can do so using Animation Events.

    However, in the case as stated above (I'm presuming here your animation sequence is, in fact, no more complicated than described), it would seem sufficient to drive the animation from the code. Simply set the trigger (I would use a trigger rather than an int) in code and have the animation act on that trigger. You should not need to read the trigger back as you would already know it directly from the code (in
    State
    as per my example in post #2).

    The omission in my post #2 was that it was not writing the value of
    State
    back to the animator when being enabled (which I mentioned in post #6 which should work if the change described in post #5 is added).
     
    davejones1 likes this.