朝のラジオ体操に出かけてから毎日が楽しい私、みかです (VRChat の話です)。
VRChat でも使えるちょっとしたギミックを作ったので、
忘れないうちに仕組みを書いておきます。
なお、このギミック自体は Animation Override を使用していません。
(Particle System と Animation はそこそこ大量に使用します。)
前書き:
- Animation も Particle も初めて触ったから変なところあっても許してね
作ろうとした動機:
- Particle Inventory System が販売停止になっていたけど欲しかった
- URL は跡地です
前提環境:
- Unity 2018.4.20f1 Personal
- VRChat 2020.1.1p4
リポジトリはこちらです:
GitHub - mika-archived/VRChat-InventorySystem
どんな仕組み?というと、意外と単純で、以下の動作を組み合わせたものになります。
- Particle System の Triggers と SubEmitters
- Unity の Animation Controller の State の仕組み
- Object を Activate/Deactivate で Entry に戻る
- Animator を Activate/Deactivate で状態を保存
keepAnimatorControllerStateOnDisable
で Disable でも状態を保存
各 GameObject の構造は下のような感じで、
Inventory(XXX)
と Slot[X]_Object(XXX)
の 2 つ GameObject ツリーからなります。
Inventory(XXX)
は、当たり判定を行っています。
こちらの仕組みは単純で、最低限以下の 2 つの GameObject さえあれば良いです。
Inventory(XXX)
Collider
(中間の Slot[X]_Inventory
は適当な当たり判定可視化用 3D Object です。)
Inventory
は以下の Animation Controller が設定された
Animator Component のみがアタッチされています。
Animation Controller
中身は 1 サイクルで孫の Collider
を Activate/Deactivate しているだけです。
これは、孫の Collider
が死んでもまた復活して、再度当たり判定が
有効になるようにしています。
次は Collider
GameObject です。
こちらには Particle System がくっついていて、以下のような設定です。
Particle System の設定
重要なのが Triggers
の項目で、ここである Object が Particle 内部に入ったら、
自身を殺して、 Sub Emitters で Slot[X]_Object(X)
の子にいる Trigger
を呼び出します。
次は Slot[X]_Object(X)
の方にはいります。
こちらは少し複雑で、一番下の Object
とその子以外は全て Animator がくっついています。 まずは先ほど親から飛ばされてきた Trigger
から見ていきます。
Triggers
は下のような Particle System がついています。
Triggers の設定
Play On Awake
を外すことと、 Stop Action
を Disable
にするのが重要です。
Stop Action
を Disable
に設定することで、生存期間が終了すると、
このパーティクルは自動的に Deactivate されます。
Deactivate されると、親にいる Enabler
が再度この GameObject を Activate し、
結果的には死んだタイミングで Entry に設定された Animation が再生されるようになります。
次は Trigger
の孫にいる ObjectProxy
です。
これは、keepAnimatorControllerStateOnDisable = true
が設定されています。
この GameObject に設定された Animator は以下のようになります。
Animation Controller
ObjectProxy
の子の状態にも寄りますが、初め Disabled の場合は、
上記のような Animation State を持っています。
Activate/DeactivateObject
は名前のままの処理を、
SuspendAsActivated/Deactivated
は自身の Animator を無効にしています。
Animator を Disabled にすることで、現在の状態を維持しているわけです。
ただし、そのままだと親の Particle が死んだ段階で状態が失われるので、
keepAnimatorControllerStateOnDisable
も有効にしているのです。
ということで、コアな部分の解説はこんな感じでした。
残りの部分は、実際の Prefab を見てもらえれば理解できると思います。
ではでは~ヾ(๑╹◡╹)ノ"