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. SkinnyNegativeChuckwalla
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CustomDropDown : MonoBehaviour {
public GameObject SubMenu;
[HideInInspector]
public int State = 0;
Animator AniPlayer;
public void BtnDropDown()
{
if (AniPlayer.GetInteger("MenuState") == 0)
{
AniPlayer.SetInteger("MenuState", 1);
}
else if (AniPlayer.GetInteger("MenuState") == 1)
{
AniPlayer.SetInteger("MenuState", 0);
}
}
// Use this for initialization
void Start() {
AniPlayer = this.GetComponent<Animator>();
}
}
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 :-
public class CustomDropDown : MonoBehaviour
{
public int State { get; private set; }
public void BtnDropDown()
{
State = 1 - State;
m_aniPlayer.SetInteger("MenuState", State);
}
void Start()
{
State = 0;
m_aniPlayer = this.GetComponent<Animator>();
}
#pragma warning disable 649
[SerializeField] GameObject SubMenu;
#pragma warning restore 649
Animator m_aniPlayer;
}
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?
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.
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.
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.
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).