主にプログラミング関連のメモ帳 ♪(✿╹ヮ╹)ノ
書いてあるコードは自己責任でご自由にどうぞ。記事本文の無断転載は禁止です。
2020/04/26
朝のラジオ体操に出かけてから毎日が楽しい私、みかです (VRChat の話です)。
VRChat でも使えるちょっとしたギミックを作ったので、
忘れないうちに仕組みを書いておきます。
なお、このギミック自体は Animation Override を使用していません。
(Particle System と Animation はそこそこ大量に使用します。)
前書き:
作ろうとした動機:
前提環境:
リポジトリはこちらです:
GitHub - mika-archived/VRChat-InventorySystem
動きとしてはこんな感じになります。
最近作ったやつ (一瞬ちらつくのはなんとか直したい) pic.twitter.com/iTfr3nlSDl
— みか@かわいいを求めて (@MikazukiFuyuno) 2020 年 4 月 26 日
どんな仕組み?というと、意外と単純で、以下の動作を組み合わせたものになります。
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 を見てもらえれば理解できると思います。
ではでは~ヾ(๑╹◡╹)ノ"