一人称のプレイヤーに人型の影をつけて、立ち/しゃがみの歩きモーションをつけてみました。
モデルとアニメーション
まずBlenderでキャラクターモデルに「歩く」と「しゃがみながら歩く」のアニメーションを付けました。
アニメーションに移動が含まれている場合は、該当するキーフレームを削除します。
一人称プレイヤーにキャラクターを配置
キャラクターをUnityでインポートして、スターターアセットのFirstPersonControllerのプレハブの子にします。
目の高さにカメラが来るようにスケールを調節しました。
体のSkinned Mesh RendererコンポーネントのCast Shadowsを「Shadows Only」にすると影だけが表示されます。
アニメーターコンポーネント
インポート設定でアバターを作ると自動でアニメーターコンポーネントが追加されます。アニメーターコンポーネントに、歩きとしゃがみ歩きのモーションを追加します。
floatとbool型のパラメーターを作ります。
boolのパラメーターによって2つのステートを行き来します。
スクリプトでステートの切り替え
スクリプトでプレイヤーをしゃがませるときに、アニメーターにbool値をセットしてステートを切り替えます。
// 現在のキーボード情報
var current = Keyboard.current;
// キーボード接続チェック
if (current == null)
{
// キーボードが接続されていないと
// Keyboard.currentがnullになる
return;
}
// Cキーの入力状態取得
var cKey = current.cKey;
// Cキーが押された瞬間かどうか
if (cKey.wasPressedThisFrame)
{
if (!(crouch.IsCrouching && !CanStandUp))
{
crouch.Toggle();
if(shadowIsOn)
{
// bool値を設定
animator.SetBool("IsCrouching", crouch.IsCrouching);
}
}
}
ステートのTransition Durationを調節して、カメラと影の動きを合わせました。
プレイヤーの移動とモーションを合わせる
2つのステートのMotion Timeにfloat型のパラメーターを設定しています。
これでパラメーターの0~1の値で、どの時点のモーションを再生するか指定できます。値が変わらなければその時点から動きません。
まず、FirstPersonControllerクラスを少し修正して、キャラクターコントローラーのvelocityの大きさを他のクラスに公開します。
// 水平方向の速度
public float currentHorizontalSpeed { get; private set; }
// キャラクターコントローラー
private CharacterController _controller;
// Move()
currentHorizontalSpeed = new Vector3(_controller.velocity.x, 0.0f, _controller.velocity.z).magnitude;
そして、プレイヤーにつけた他のスクリプトのUpdateメソッドで距離を毎フレーム足していき、0-1の範囲にしてAnimatorコンポーネントにセットします。モーションが2歩分なので、2歩進んだら距離を0にリセットします。
FirstPersonController fps;
[SerializeField] float strideLength = 3f;
// Update()
// 1フレームで進んだ距離
var distancePerFrame = fps.currentHorizontalSpeed * Time.deltaTime;
// 影がオンのとき
if (shadowIsOn)
{
// 距離を累積
walkCycleProgress += distancePerFrame;
// 2歩分進んだらリセット
if (walkCycleProgress >= strideLength * 2)
{
walkCycleProgress = 0f;
}
// 0-1の範囲にしてAnimatorに設定
animator.SetFloat("MotionTime", walkCycleProgress / (strideLength * 2f));
}
歩幅はインスペクターで設定しています。
音とモーションのタイミングはアニメーションのインポート設定の「Cycle Offset」でも調節できます。
影の位置を調節
キャラクターのローカル位置を0にすると影が浮いて見えました。
なので、キャラクターの位置を少し調節しています。
スターターアセットでは、カメラの回転を制限することもできます。
ライトレイヤーの設定
懐中電灯をつけると不自然な影ができたので、キャラクターの体のSkinnedメッシュレンダラーのライトレイヤーを変更しました。
懐中電灯にはデフォルトのライトレイヤーだけが設定されているので、影を落としません。
キャラクターの影を落としたいライトには、体と同じライトレイヤーを設定しています。