Animations
概要
Fusion Animationsサンプルでは、Fusionを使ったアニメーションネットワーク処理の6つの異なるアプローチを紹介しています。
サンプル1~5はレンダーアキュレートアプローチを使い、サンプル6はティックアキュレートアプローチを使っています。それぞれのサンプルでは、およそ1秒間隔で脚と腕のヒットボックスを描画することで、サーバーキャラクターとプロキシキャラクターの間の結果の精度を示しています。アニメーションの精度は、ゲームがラグ補償を使っている場合に特に重要です。
ダウンロード
バージョン | リリース日 | ダウンロード | |
---|---|---|---|
2.0.10 | Dec 19, 2024 | Fusion Animations 2.0.10 Build 742 |
フォルダ構造
プロジェクトは、6つの小さな独立したサンプルで構成されています。
/01_AnimatorSimple | サンプル 1 - アニメーションを伴うネットワーク状態 |
/02_AnimatorInterpolated | サンプル 2 - アニメーションを伴う内挿ネットワーク状態 |
/03_AnimatorStateSync | サンプル 3 - アニメーターでの状態同期 |
/04_NetworkMecanimAnimator | サンプル 4 - ネットワークメカニムアニメーター |
/05_AnimancerFSM | サンプル 5 - AでのnimancerでのネットワークFSM |
/06_FusionAnimationController | サンプル 6 - Fusionアニメーションコントローラー |
/Common | 全てのサンプルに共通するプレハブ、スクリプト、マテリアル |
/ThirdParty | サードパーティアセット(モデル、アニメーション、Animancer Lite) |
方法
ゲームを開始する
それぞれのサンプルは、開いて再生することができる独自のシーンファイルを持っています。または、すべてのサンプルは、Start シーン(/Common/Start)から開始することができます。
デモには、ホストとクライアント2件を有するマルチピアモードを推奨します(Start Host + 2 Clients ボタン)。これにより、状態権限、入力権限、プロキシの結果をエディタで確認し、比較することができます。
コントロール
すべてのサンプルでは、3つのアニメーション状態だけを使用しています。デフォルトではアイドルアニメーションが再生され、Up Arrow キーを押すとキャラクターランアニメーションが開始され、Space キーを押すとジャンプアニメーションが開始されます。
複数のピアとプレイしているときは、Num 0、1、2、3 キーで切り替えることができます。また、Runner Visibility Controls ウィンドウ(トップメニュー Fusion > Windows > Runner Visibility Controls)からも切り替えられます。
アニメーションの精度を理解する
ピア間の正確なアニメーション同期は、正確なラグ補償など、特定のゲームアプリケーションにとって非常に重要です。アニメーションが完全に同期していれば、あるクライアントで認識されたヒットがサーバーでも認識されることが保証され、結果として良いプレイヤー体験が得られます。もちろん、これはキャラクターのヒットボックスがアニメーションの影響を受けている場合にのみ適用されます。Fusionマニュアルのアニメーションページで、重要なコンセプトについて詳しく説明しています。
すべてのサンプルは、ローカルプレイヤーから見た足と腕のヒットボックスの予想される位置(プロキシ*キャラクターのヒットボックスは青で表示されます)と、サーバー上で表示される位置(緑で表示されます)を示しています。アニメーションの精度が高ければ高いほど、ボックスはより密接に揃います。
ヒットボックスの描画は、プレイヤーのプレハブに置かれた HitboxDraw
スクリプトによって行われます。違いの比較のため、ヒットボックスは50ティック間隔(およそ1秒)で描画されます。
*プロキシオブジェクト = 入力権限(ローカルプレイヤーによってコントロールされていない)も状態権限(インスタンスがネットワーク状態に対する権限を持っていない、通常はサーバー上のインスタンス)も持っていないネットワークオブジェクトのインスタンス。簡単に言うと、クライアントとしてプレイする場合、プロキシキャラクターはプレイヤーが見ることができる他のプレイヤーとなる。
### ネットワーク状況のシミュレーション
アニメーションの精度を高めるためのいくつかの変更(内挿データの使用など)は、ネットワーク状況が悪い場合によりよく観察されます。このような状況を素早くシミュレートするには、Clumsyのようなツールを使うことも良いでしょう。詳しくは、ネットワーク状況のシミュレーション セクションを参照してください。
サンプル 1 - アニメーターを伴うネットワーク状態
レンダーアキュレートアプローチ
このサンプルでは、最新のネットワーク状態を使用してアニメータのパラメータを制御する、最も単純なソリューションを示します。
通常であれば、既存のネットワーク状態(_controller.Speed
など)を使用してアニメーションを制御できます。正確なアニメーションをレンダリングするには、Render
メソッドまたは OnChanged
コールバックで、ネットワーク上のデータに基づいて設定します。
C#
private CharacterController _controller;
private Animator _animator;
public override void Render()
{
if (_lastVisibleJump < _controller.JumpCount)
{
_animator.SetTrigger("Jump");
}
_lastVisibleJump = _controller.JumpCount;
_animator.SetFloat("Speed", _controller.Speed);
}
サンプル 2 - アニメーターを伴う内挿ネットワーク状態
レンダーアキュレートアプローチ
このサンプルでは、最新のネットワークデータだけでなく、内挿されたネットワークデータを使用することで、前のサンプルからステップアップしています。内挿されたデータを使用することで、アニメーションがより正確になり、ネットワーク状況が理想的でない場合でもこの正確さが保たれます(ネットワーク状況のシミュレーションのセクションを参照)。
C#
private CharacterController _controller;
private Animator _animator;
public override void Render()
{
int jumpCount = _useInterpolation == true ? _controller.InterpolatedJumpCount : _controller.JumpCount;
if (_lastVisibleJump < jumpCount)
{
_animator.SetTrigger("Jump");
}
_lastVisibleJump = jumpCount;
float speed = _useInterpolation == true ? _controller.InterpolatedSpeed : _controller.Speed;
_animator.SetFloat("Speed", speed);
}
内挿されたデータと最新のデータの使用量を比較するために、Player コンポーネントに簡単なチェックボックスがあります。Player_AnimatorInterpolated*プレハブを見つけ、Use Interpolationをオフにします。2つのクライアントを追加してゲームを開始し、ネットワークの悪さ(Clumsy - Lag 100 ms, Drop 20%) をシミュレートし、その違いを比較してください。
サンプル 3 - アニメーターを伴う状態同期
レンダーアキュレートアプローチ
このサンプルでは、特別なコンポーネント AnimatorStateSync
を追加し、現在のプレイヤーのアニメーターの状態とその時間を定期的に同期させます。状態同期は、プレイヤーがゲームに参加した後や、プロキシオブジェクトが関心領域に入った後でも、プロキシのアニメーションが同期していることを保証します。
状態の同期は、長時間のアニメーション(ロコモーションなど)や、レンダーアキュレートアプローチで起こりうるミスの修正に特に重要です。
例:ローカルプレイヤーがゲームに参加したとき、リモートプレイヤーはすでに10秒間アニメーションを実行しています。しかし、アニメーションの時間が同期されていない場合、ローカルプレーヤーのマシンのプロキシキャラクターは、最初からランニングアニメーションを開始するため、アニメーションのタイミングが異なります。このタイミングは、次のアニメーションアクション(ジャンプなど)で自動的に修正されますが、それまではアニメーションは同期していません。
サンプル4 - ネットワークメカニムアニメーター
レンダーアキュレートアプローチ
Fusion SDKに搭載されているNetworkMecanimAnimator
(NMA)コンポーネントを使ってアニメーションを同期するシンプルなソリューションです。
ネットワークメカニムアニメーター(NMA)は内挿されたネットワークデータを使用しないため、アニメーションの精度はサンプル3のソリューションによるものよりも低くなります。NMAは既存のネットワークデータを使用せず、現在のAnimatorパラメータを独自のネットワークデータ構造にコピーするため、特に同期パラメータが大量に変更される場合は、帯域幅を消費します。
ネットワークメカニムアニメーターについて詳細はアニメーション のドキュメントを参照してください。
C#
private CharacterController _controller;
private NetworkMecanimAnimator _networkAnimator;
public override void FixedUpdateNetwork()
{
if (IsProxy == true)
return;
if (Runner.IsForward == false)
return;
if (_controller.HasJumped == true)
{
_networkAnimator.SetTrigger("Jump", true);
}
_networkAnimator.Animator.SetFloat("Speed", _controller.Speed);
}
サンプル 5 - Animancerを伴うネットワークFSM
レンダーアキュレートアプローチ
このサンプルでは、人気のサードパーティ製アニメーションアセット Animancer と、現在プレビュー中のネットワークFSM アドオンを使用しています。Animancerは、最初のサンプルと同様に、FSMなしで使用することもできます。
ネットワークFSMでは、StateMachineController
コンポーネントをゲームオブジェクトに配置し、ステートマシンを保持し、IStateMachineOwner
インターフェイスを実装するユーザースクリプト(Playerなど)が必要です。StateMachineController
は、すべてのピアに必要なデータを自動的に同期し、登録されたマシンを更新します。
C#
public class Player : NetworkBehaviour, IStateMachineOwner
{
private PlayerBehaviourMachine _fullBodyMachine;
void IStateMachineOwner.CollectStateMachines(List<IStateMachine> stateMachines)
{
var states = GetComponentsInChildren<PlayerStateBehaviour>();
var animancer = GetComponentInChildren<AnimancerComponent>();
_fullBodyMachine = new PlayerBehaviourMachine("Full Body", _controller, animancer, states);
stateMachines.Add(_fullBodyMachine);
}
}
アニメーションは、ステートの変化に基づいて再生されます。ステートはプレーヤーの1つの動作を表し、プレーヤー階層内のオブジェクトに StateBehaviour
スクリプトがアタッチされているか (例: Jump State、Locomotion State)、または State
スクリプトを継承したプレーンなクラス (このサンプルでは紹介していません) です。
C#
public override void FixedUpdateNetwork()
{
if (IsProxy == true)
return;
if (_controller.HasJumped == true)
{
_fullBodyMachine.TryActivateState<PlayerJumpState>();
}
}
C#
public class PlayerJumpState : PlayerStateBehaviour
{
[SerializeField]
private ClipTransition _jumpClip;
protected override void OnEnterStateRender()
{
Animancer.Play(_jumpClip);
}
protected override void OnFixedUpdate()
{
if (Machine.StateTime >= _jumpClip.Length * _jumpClip.Speed)
{
// Jump animation should be finished, let's leave this state
Machine.TryDeactivateState(StateId);
}
}
}
親ステートから制御されるサブステートマシン(子マシン)を作成し、HFSM(階層型有限ステートマシン)を効果的に作成することができます。例えば、子マシンは、Airborneの親ステートから制御される、ジャンプ、転ぶ、着陸 などのステートを持つAirborneマシンになります。このような分離は、多くのステートを持つ複雑なアニメーション設定を制御するときに便利です。
ネットワークFSMはデフォルトで、内挿されたデータに基づいてプロキシのステートを切り替え、Renderコールからチェックされたときに内挿された現在のステートの時間(Machine.StateTime
)を提供します。これにより、手間をかけずにアニメーションの精度を高めることができます。
C#
public class PlayerLocomotionState : PlayerStateBehaviour
{
[SerializeField]
private LinearMixerTransition _moveMixer;
protected override void OnEnterStateRender()
{
Animancer.Play(_moveMixer);
// Update the animation time based on the state time
_moveMixer.State.Time = Machine.StateTime;
}
protected override void OnRender()
{
_moveMixer.State.Parameter = Controller.InterpolatedSpeed;
}
}
サンプル 6 - Fusionアニメーションコントローラー
ティックアキュレートアプローチ
Fusion Animation Controllerは、Unityの低レベルのPlayables API上に直接構築されたティックアキュレートアニメーションソリューションです。
Similarly to Mecanim, Fusion Animation Controller operates with Animation Layers. Every layer contains one or more Animation States. Both layers and states are simply represented by objects in the object hierarchy (see Player_FusionAnimationController
prefab). Animations are controlled from code via the AnimationController
component.
メカニム と同様に、Fusionアニメーションコントローラーは、アニメーションレイヤー で動作します。各レイヤーには、1つ以上の アニメーションステート が含まれます。レイヤーとステートは、オブジェクト階層のオブジェクトで表現されます(プレハブ Player_FusionAnimationController
を参照)。アニメーションは AnimationController
コンポーネントを通してコードから制御されます。
C#
private CharacterController _controller;
private PlayerLocomotionState _locomotionState;
private PlayerJumpState _jumpState;
public override void FixedUpdateNetwork()
{
if (IsProxy == true)
return;
if (_controller.HasJumped == true)
{
_jumpState.Activate(0.15f);
}
else if (_jumpState.IsPlaying() == false || _jumpState.IsFinished(-0.15f, false) == true)
{
_locomotionState.Activate(0.15f);
}
}
FusionアニメーションコントローラーはBR200で使用されたアニメーションコントローラーの改善版です。
サードパーティアセット
アニメーションサンプルには、それぞれのクリエイターのご好意により提供されたいくつかのアセットが使用されています。完全なパッケージは、それぞれのサイトで皆さんのプロジェクト用に入手することができます。
- Animancer LITE by Kybernetik
重要:商用プロジェクトで使用するには、それぞれのクリエイターからライセンスを購入する必要があります。
Back to top