見出し画像

【Unity】【VRChat】サブステートマシンを使ってみる

Animatorのステート群を整頓する



概要

この記事の対象

・2022年11月時点
・Unity 2019.4.31f1

完成形(目標)

縦長のAnimator。これを…
サブステートマシン2個に分解して整頓
サブステートマシン1個目(a=1~8)
サブステートマシン2個目(a=9~16)

要点

 Int型の変数(=aとします)を0から変化させる時に、a=10 位までなら良いですが、20 や 30 など増えてくるとステート遷移が縦長になったり遷移矢印が重なったりしてAnimatorが見づらくなる(デバッグの時にわかりにくくなる)為、サブステートマシンを用いてステート群をある程度の塊に分け、Animatorを見やすく整頓するのが目的です。


作成方法

 今回は例として、Int型変数a(=0~16)へのステート遷移をサブステートマシン2個(1~8と9~16)に分割するレイヤーを組みます。

1. サブステートマシン(1個目)の作成

生成したサブステートマシンに遷移を引く

 六角形のマークがサブステートマシンになります。今回は a=1~8 の時にサブステートマシン1へ入る様に遷移させる為、遷移条件は a > 0 and a < 9です。サブステートマシンは左ダブルクリックで展開します。

レイヤーにおけるサブフォルダのようなもの

 サブステートマシン無しの時に加え、オレンジ色の遷移ステートが増えています。上の階層に戻る用のステートになります。

Entryの先の入口ステート(空ステート)はあった方が安定する…気がする

通常通りa=1~8への遷移を引きます。

サブステートへ入った時と同じステートに戻す

 a=1から0に戻る遷移を引く時に、(Up)と書いてあるオレンジ色のステートを選択します。するとどこに戻すかの選択肢が現れる為、戻すステートを選択します。

a=2~8も同様に抜ける遷移を引きます。

サブステートに誤って侵入してしまった場合にすぐ抜けるバイパスをつける

 保険として、サブステートマシン入口から直通で上層へ抜ける遷移を付けます(a=1~8以外の状態でこのサブステートへ誤侵入してしまった時にすぐ抜ける遷移)。このサブステートマシンに入る際にa=1~8の遷移条件があれば理論的には誤侵入は無いはずですが、誤侵入したことが実際にあったので、保険として付けた方が(おそらく)安定します。

2. サブステートマシン(2個目)の作成

 上の階層に戻り、サブステートマシン1の所で右クリック、Copyを選択します。

 何もない所で右クリック、Pasteを選択するとサブステートマシンが複製されます。

StateMachineの方を選択

 名前をサブステートマシン2へリネームして、a=0 のステートからサブステートマシン2への遷移を引きます。するとどこに遷移するかの選択肢が現れますので、StateMachine→サブステートマシン2 と選択します。
 StateMachineを選択した場合、そのサブステートマシン内のEntryに遷移します。Statesを選択した場合、サブステートマシン内の特定のステートに直接遷移します。

 サブステートマシン1と同じ構造のものが複製されているので、ステート名や遷移条件を書き換えていきます。この時他のサブステートマシンで使われているものと同一のステート名が使用できますが、ステート名はレイヤー内の全サブステートマシン通して独立したものにリネームしましょう。デバッグの際にどこのステートに問題があるかわかりやすくなります。

ワープ遷移はお勧めしない(入った場所に戻るのが無難)

 また、上の階層に戻る遷移を引く時に、上の階層の任意のステートに遷移することができます(上の階層にある違うサブステートマシン内のステートにも遷移可能)。…が、遷移の制御が非常に難しくなり、バグが発生した際に原因を突き止めるのが困難になります。基本的にはサブステートマシンに入った時と同じステートに返した方が無難です。

16個の遷移を2グループに纏めることができました

 これで完成です。a = 30 や 40 等増えてくるとサブステートマシン無しではAnimatorの遷移が非常に見づらくなるので、サブステートマシンを使って適度にグループ分けするのをお勧めします。

a = 64 をサブステートマシン無しの場合。マンションかな?
遷移矢印が1本抜けててもぱっと見わからない


補足:Any StateとExitの扱い

サブステートマシン内のAny StateとExitはなるべく使わない方が良いかも

 Any Stateについて:置かれてるサブステートマシン内に限らず、レイヤー全体が効果範囲です。上の階層の違うサブステートマシン内に居たとしても強制的に引き抜いて遷移します。使うと遷移制御が非常に難しいです。だいたい意図しない遷移のもとになります。筆者はサブステートマシン内では基本使ってません。効果範囲がそのサブステートマシン内だけ、であったら使い道あったんですが…
 Exitについて:通常はExitに接続するとその後Entryから入りなおすのでExit→Entryという遷移矢印が引いてある、という認識で問題ないんですが、サブステートマシンを使用するとレイヤー内全体でEntryが複数存在します(上の階層のEntryとサブステートマシン内のEntry)。そしてExitの先どのEntryに戻るかよくわかってません(画面上も遷移矢印が無いから見た目で分からない)。Any Stateと同じく筆者はサブステートマシン内のExitは使用していません(オレンジ色の上層に返すステートを使用しています)。矢印の引いてない遷移はバグ修正の時に気づきにくいんで…



まとめ

 サブステートマシンは、それそのものは無くてもAnimatorは作成可能ですが、数十個も遷移が重なると遷移矢印が重なって非常に見づらくなり、保守が大変になります。適度にグループ分けして格納すれば見やすいAnimatorになり、バグが発生した際の修正も楽になるので、使用をお勧めします。


この記事が気に入ったらサポートをしてみませんか?