【Unity】一人称プレイヤーに動く人型の影をつける

投稿者: | 2023-11-17

一人称のプレイヤーに人型の影をつけて、立ち/しゃがみの歩きモーションをつけてみました。

モデルとアニメーション

まずBlenderでキャラクターモデルに「歩く」と「しゃがみながら歩く」のアニメーションを付けました。

アニメーションに移動が含まれている場合は、該当するキーフレームを削除します。

移動が含まれている
キーフレームを削除

一人称プレイヤーにキャラクターを配置

キャラクターをUnityでインポートして、スターターアセットのFirstPersonControllerのプレハブの子にします。

目の高さにカメラが来るようにスケールを調節しました。

体のSkinned Mesh RendererコンポーネントのCast Shadowsを「Shadows Only」にすると影だけが表示されます。

On
Off
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メッシュレンダラーのライトレイヤーを変更しました。

懐中電灯にはデフォルトのライトレイヤーだけが設定されているので、影を落としません。

懐中電灯

キャラクターの影を落としたいライトには、体と同じライトレイヤーを設定しています。

コメントを残す

メールアドレスが公開されることはありません。