Bolt 106 - アニメーション
Boltはネットワーク上のMecanimアニメーションの複製をサポートしています。この章では、ネットワーク上で適切にアニメーションを動かす方法を詳細に見ていきましょう。
最初に、モデルとアニメーションが含まれているパッケージをダウンロードしてください。アセットストアからのUnityの'Stealth' サンプルから取得できます。または、アセットストアから'Stealth'パッケージをダウンロードし、そのキャラクターを自身でエクスポートするか、以下のパッケージをダウンロードすることもできます:
ここから先は上記のパッケージをダウンロードしたものとして進みます。パッケージをTutorialプロジェクトにインポートしてください。
新しいフォルダRobotを作成し、関連するすべてのファイルをドラッグします。
Tutorial/Robot/Done/DonePrefabs/char_robotGuardプレハブを見つけ、それをTutorial/Prefabs'のフォルダにドラッグしてRobotとリネームしてください。
Bolt Assetsのウィンドウを開いて新たな状態を作成し、RobotStateと名前をつけてください。状態の作成と名前の設定が完了したら、その状態のImport Mecanim Parameters設定を開きます。
Robot のMecanimコントローラーをスロットにドラッグすると、Tutorial/Robot/DoneAnimations/DoneEnemyAnimatorに表示されるようになります。
Importボタンをクリックします。
BoltはMecanimコントローラー内の全てのパラメーターを、状態に自動的にインポートします。
アニメーションコントローラーからパラメータをインポートした後、新たな設定(Mecanim (State Wide))が状態上に開きます。これにより、アニメーター値の変更にanimator.SetFloatやanimator.SetBoolといった通常のMecanimメソッドを用いるか、 Boltの状態プロパティを用いるかを選択できます。
Boltを、アニメーションコントローラーに関するパラメータ設定の一標準的なMecanimの方法を使用する既存のゲームに追加する場合には、デフォルトのUsing Animator Methods設定のままにしておくのが最適です。新たなゲームをBoltでビルドする場合には、この後行うとおりUsing Bolt Propertiesオプションを選択してください。
インポートで追加された全てのパラメーターが、Using Bolt Propertiesに変更されることを確認してください。また、Mecanimの値の減衰時間を制御する追加オプションが得られます。任意でBoltを Mixed Mode で稼働することもできます。このモードでは、いくつかのプロパティがUsing Animator Methodsに設定されており、またいくつかはUsing Bolt Propertiesに設定されています。発生する可能性のある混乱を防ぐため、これは用いないことを一般に推奨しています。
最後に、TransformプロパティをRobotStateに追加します。以前にCubeStateに対して行ったのと同じ要領です。
- 最上部の'New Property'をクリックします。
- 作成したプロパティの名前を'Transform'と設定します。
- プロパティのタイプを'Transform'と設定します。
- Smoothing Algorithm'を'Interpolation'に設定します。
先に進む前に、Mecanimパラメータに関する設定も行っておきましょう。まず、Shot とAimWeight パラメータに対するネットワーク複製を無効にしてください。これらはアニメーション内のカーブによりコントロールされ、ユーザーによる直接的な制御を受けないためです。これらのパラメータを例の中で実際に用いることはありませんが、これらを無効にしないと、Bolt がそれらを設定しようとする際にMecanimからエラーが発生します。
無効にするには2つの方法があります。最も簡単なのは、取り除いてしまうことです。もう1つは、Mecanim設定をUsing Animator Methodsに設定し、ReplicationをLocalに設定することです。こうすることで、Boltは値をカーブから出力し、それをプロパティに放出しますが、ネットワーク上には何も送信しません。
設定が必要な2つ目のオプションは、SpeedとAngularSpeedのプロパティのDamping Timeです。これをどちらも、0.1 に設定してください。
重要: ロボットキャラクターの状態について設定を完了したら、先に進む前にBoltをコンパイルするのを忘れないでください。
ここで、RobotプレハブをBolt Entityとして設定しましょう。Tutorial/Prefabsフォルダのプレハブを選択し、Bolt Entity のコンポーネントを追加してください。
Bolt EntityコンポーネントのState設定をIRobotStateに変更し、Boltを再度コンパイルしてRobotプレハブを選択してください。
ワールド内でロボットをスポーンする前に、 Boltに古いCubeのものではなく、新たなRobotプレハブのインスタンスを作成させる必要があります。NetworkCallbacks スクリプトでBoltNetwork.Instantiateコールを変更し、BoltPrefabs.Robotを参照してください。
C#
// ...
public override void SceneLoadLocalDone(string map)
{
// randomize a position
var spawnPosition = new Vector3(Random.Range(-8, 8), 0, Random.Range(-8, 8));
// instantiate cube
BoltNetwork.Instantiate(BoltPrefabs.Robot, spawnPosition, Quaternion.identity);
}
// ...
ゲームを作成し2つのインスタンスを開始すると、以下のような画面を確認できます。また、Boltは続くエラーのレポートを送信します。このエラーは、Boltに対して用いたい'Animator'を適切に割り当てることができていないために起こります。
You have not assigned a mecanim animator to the state on Robot(Clone), but you have properties set to use mecanim.
新たなC#スクリプトであるRobotBehaviourをTutorial/Scriptsフォルダ内に作成し、CubeBehaviourのときと同様にデフォルトのUnityメソッドを削除し、クラスをBolt.EntityBehaviour<IRobotState>から継承してください。
C#
using System.Collections;
using UnityEngine;
public class RobotBehaviour : Bolt.EntityBehaviour<IRobotState>
{
}
Attached メソッドをオーバーライドし、 Transform プロパティを設定して Bolt が用いる状態にアニメーターを割り当てます。
変換は、CubeTransform プロパティに行ったように、state.SetTransforms(state.Transform, transform)に割り当てられます。アニメーターの割り当ては、state.SetAnimator の呼び出しと、プレハブからの既存のAnimator コンポーネントへの受け渡しによって行われます。
また、自身がオーナーの場合には'root motion'のみが用いられていることを確認してください。これは、自身がオーナーでない場合、それにより適用されるモーションが1つのエンティティを見ている全てのリモートピア上で重複するためです。entity.isOwner をstate.Animator.applyRootMotionプロパティに割り当ててください。
C#
using UnityEngine;
using System.Collections;
public class RobotBehaviour : Bolt.EntityBehaviour<IRobotState>
{
public override void Attached()
{
state.SetTransforms(state.Transform, transform);
state.SetAnimator(GetComponent<Animator>());
state.Animator.applyRootMotion = entity.isOwner;
}
}
また、作成したばかりのRobotBehaviour コンポーネントも、実際のRobot プレハブに割り当ててください。
この時点でゲームをビルドし開始すると、ロボットが立っている状態になりますが、警告は表示されません。最後に、ルートモーションを制御するためのコードを追加する必要があります。もう一度RobotBehaviourを開き、SimulateOwnerメソッドを実装してください。このメソッドにおけるコードは、最初は複雑に見えるかもしれませんが、実際には非常にシンプルです。
- Wが下のとき、スピードを加速させる(最大+1.5)
- Wが下になって いない とき、スピードを0まで減速させる
Aが下になっているとき、角速度をマイナスにする(最大-1)Dが下になっているとき、角速度をプラスにする(最大+1)AもDも下に なっていない とき、角速度を0に向けて移動する
C#
// ...
public override void SimulateOwner()
{
var speed = state.Speed;
var angularSpeed = state.AngularSpeed;
if (Input.GetKey(KeyCode.W))
{
speed += 0.025f;
}
else
{
speed -= 0.025f;
}
if (Input.GetKey(KeyCode.A))
{
angularSpeed -= 0.025f;
}
else if (Input.GetKey(KeyCode.D))
{
angularSpeed += 0.025f;
}
else
{
if (angularSpeed < 0)
{
angularSpeed += 0.025f;
angularSpeed = Mathf.Clamp(angularSpeed, -1f, 0);
}
else if (angularSpeed > 0)
{
angularSpeed -= 0.025f;
angularSpeed = Mathf.Clamp(angularSpeed, 0, +1f);
}
}
state.Speed = Mathf.Clamp(speed, 0f, 1.5f);
state.AngularSpeed = Mathf.Clamp(angularSpeed, -1f, +1f);
}
// ...
メソッドの開始時に、state.Speedとstate.AngularSpeedを読み込み、それらを2つのローカルの変数に保存します。その方が作業が簡単なためです。メソッドの終了時、それを状態に再度割り当ててspeedを0.0 から 1.5fの間に、angularSpeedを-1から+1の間に固定してください。
ゲームを再度ビルドすると、WADキーを使ってロボットのキャラクターと共に動き回ることができます。
以下に結果のデモを表示します。
以上で、「はじめに」チュートリアルが完了しました。次に、高度なチュートリアルに進み、Boltの強力な機能をさらに詳しく習得しましょう。