Forum rules - please read before posting.

Request: CharState.Changed event

edited December 2024 in Technical Q&A

If it exists, I couldn't find it - but could we possibly get a new event for CharState such as CharState.Changed? In my use case, I'm using an Animator trigger "EnterIdles" to transition into a substate containing a loop of different idle animations. Then transitioning back to the Locomotion state using "ExitIdles". For now at least, this is in a monoscript that checks like this:

void Update()
    {
        if(KickStarter.player.charState == CharState.Idle)
        {
            KickStarter.player.GetAnimator().ResetTrigger("ExitIdles");
            KickStarter.player.GetAnimator().SetTrigger("EnterIdles");

        }
        else
        {
            KickStarter.player.GetAnimator().ResetTrigger("EnterIdles");
            KickStarter.player.GetAnimator().SetTrigger("ExitIdles");
        }
    }

Subscribing to a CharState changed event would let me take this out of Update. I'm still learning how AC works under the hood so I'm open to a better way. (I don't want to use a blend tree for transitioning through the idles however)

Comments

  • What's the underlying issue being faced? To make the code cleaner by avoiding the need for an Update loop, or does the existing code not work?

    The charState variable really ought to be private, that's on me for exposing it. It's really only intended for internal calculations, and it's the character's movement speed that is the intended way of checking their movement state. A character can appear idle, but in fact is just moving very slowly as they decelerate to a standstill, which can take a few frames and would cause an apparent delay if you were checking for CharState.Idle.

    You can have your Animator's MoveSpeed parameter be a condition for e.g. your EnterIdles -> ExitIdles transition, which itself then transitions to your regular movement state(s). If you prefer to invoke things through code, however, this custom script ought to provide the events you can hook into:

    using UnityEngine;
    using UnityEngine.Events;
    using AC;
    
    public class IdleEvents : MonoBehaviour
    {
    
        public AC.Char character;
        public float moveSpeedThreshold = 0.1f;
        float lastFrameMoveSpeed;
        public UnityEvent onMove, onIdle;
    
        void Update ()
        {
            float moveSpeed = character.GetMoveSpeed ();
    
            if (moveSpeed > moveSpeedThreshold && lastFrameMoveSpeed <= moveSpeedThreshold)
            {
                onMove.Invoke ();
            }
            if (moveSpeed <= moveSpeedThreshold && lastFrameMoveSpeed > moveSpeedThreshold)
            {
                onIdle.Invoke ();
            }
    
            lastFrameMoveSpeed = moveSpeed;
        }
    
    }
    
  • "What's the underlying issue being faced? To make the code cleaner by avoiding the need for an Update loop, or does the existing code not work?"

    Overall goal with the request was to get it out of the Update. The code works, but yes do see (at times) noticeable animation slide due to transitioning to CharState.Idle while the character still has slight movement. You code will work perfectly for this case. Thanks!

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.