はじめに
この記事はHamster Output Advent Calendar 2024の21日目の記事です!
今回はStateBehaviourの紹介をしたいと思います。
実はAnimatorのステートにはスクリプトをアタッチすることができる
といっても、MonoBehaviourをアタッチできるという訳ではないですが...
代わりに、StateBehaviourを継承したスクリプトをアタッチすることができます。手動で作ると少し面倒なので、Animatorのステートを選択した後に、インスペクタからスクリプトを作るのが楽です。
作成されるとスクリプトがアタッチされます。
そして作られたソースコードはこちら。ほとんどコメントアウトされてます。下にメソッドの内容をまとめています。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class IdleState : StateMachineBehaviour
{
// OnStateEnter is called when a transition starts and the state machine starts to evaluate this state
//override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
//{
//
//}
// OnStateUpdate is called on each Update frame between OnStateEnter and OnStateExit callbacks
//override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
//{
//
//}
// OnStateExit is called when a transition ends and the state machine finishes evaluating this state
//override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
//{
//
//}
// OnStateMove is called right after Animator.OnAnimatorMove()
//override public void OnStateMove(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
//{
// // Implement code that processes and affects root motion
//}
// OnStateIK is called right after Animator.OnAnimatorIK()
//override public void OnStateIK(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
//{
// // Implement code that sets up animation IK (inverse kinematics)
//}
}
それぞれのメソッドの内容は以下の通りです。
メソッド名 | 内容 |
---|---|
OnStateEnter | Stateの開始時に一度だけ呼ばれる |
OnStateUpdate | State中に毎フレーム呼ばれる(UnityのUpdate) |
OnStateExit | ステートが終了した時に呼ばれる |
OnStateMove | RootMotionに関する処理を実行する場所 |
OnStateIK | IKに関する処理を実行する場所 |
MoveとIKに関しては使ったことが無かったので、今回初めて内容を知りました💦
そして、IdleStateの中身をこのように変更しました。
using UnityEngine;
public class IdleState : StateMachineBehaviour
{
override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
Debug.Log("Enter Idle State");
}
override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
if (Input.GetKeyDown(KeyCode.Space))
{
animator.CrossFadeInFixedTime("Walk", 0.3f);
}
}
override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
Debug.Log("Exit Idle State");
}
}
そして実行するとしっかりとStartのログが出ています。
そして、スペースキーを押すと、Animationが遷移してExitのログが出てることが分かります。このようにステート内で処理を実行してAnimationの変更など様々なことができます。
いつも何気に使っているAnimatorは実はStateMachineだった
設計とかを考えるようになって初めてステートマシンについて勉強をしましたが、実は身近に使っていたAnimator自体がステートマシンだったんですよね...
公式リファレンスにも書いてあります。
ステートマシンを触りたいなという人におすすめしたい
AnimatorはGUIベースのステートマシンなので視覚的に見やすいところから使いやすいです。まだ、ステートマシン使ったことが無いけど興味がある...という人や、ステートマシン勉強したいなという人はぜひ触って見てください。
ただ、遷移条件をGUIで沢山作ると滅茶苦茶になるのでAnimationCrossFadeを使ったり、Exit用のステートを作ってStartStateに戻す処理を作ると見やすくなると思います。