【ダークソウル風ゲームを作りたい(Unity)。その7】

今回は滞空アニメーションと着地アニメーションを実装します。
youtu.be

・mixamoから着地アニメーションを取得します。

・着地アニメーションを編集して滞空中アニメーションを作成します。
mixamoのアニメーションはReadOnlyになっていて編集できないのでVeryAnimationを使用して編集可能にします。
knb-mayumi.com

・Animatorにアニメーションを設定します。

・下記スクリプトを追加します。

public class PlayerManager : MonoBehaviour //+EP4 playerにアタッチ
{
 private void LateUpdate()
        {
            inputHandler.rollFlag = false;
            inputHandler.sprintFlag = false;
            isSprinting = inputHandler.b_Input;

            //+EP7 滞空時間を変数inAirTimerに代入
            if (isInAir)
            {
                playerLocomotion.inAirTimer = playerLocomotion.inAirTimer + Time.deltaTime;
            }
        }
}
public class PlayerLocomotion : MonoBehaviour //+EP1 playerにアタッチ
{
        //+EP7
        [Header("Ground & Air Detection Stats")]
        [SerializeField]
        float groundDetectionRayStartPoint = 0.5f;
        [SerializeField]
        float minimumDistanceNeededToBeginFall = 1f;
        [SerializeField]
        float groundDirectionRayDistance = 0.2f;
        LayerMask ignoreForGroundCheck;
        public float inAirTimer;

        [Header("Movement Stats")]
        [SerializeField]
        float movementSpeed = 5; //移動スピード
        [SerializeField]
        float sprintSpeed = 7; //+EP5 スプリントスピード
        [SerializeField]
        float rotationSpeed = 10; //回転スピード

        [SerializeField]
        float fallingSpeed = 45; //+EP7

 public void HandleFalling(float delta, Vector3 moveDirection)
        {
            //地面に接地していない
            playerManager.isGrounded = false;
            RaycastHit hit;
            Vector3 origin = myTransform.position;

            //プレイヤーのy座標にgroundDetectionRayStartPoint(0.5f)プラス
            origin.y += groundDetectionRayStartPoint;

            //originからmyTransform.forward方向へRayを生成。Ray表示時間:0,4f
            if (Physics.Raycast(origin, myTransform.forward, out hit, 0.4f))
            {
                //プレイヤー前方にオブジェクトを検知した場合、movedirectionに0ベクトルを代入
                moveDirection = Vector3.zero;
            }

            //プレイヤーが空中時
            if (playerManager.isInAir)
            {
                //プレイヤー下方向に力を加える
                rigidbody.AddForce(-Vector3.up * fallingSpeed);
                rigidbody.AddForce(moveDirection * fallingSpeed / 10f);
                
            }

            Vector3 dir = moveDirection;
            dir.Normalize();
            origin = origin + dir * groundDirectionRayDistance;

            targetPosition = myTransform.position;

            Debug.DrawRay(origin, -Vector3.up * minimumDistanceNeededToBeginFall, Color.red, 0.1f, false);
            //ワールド座標にて start (開始地点)から start + dir (開始地点+方向)までラインを描画します。
            //duration は命令を発行してからラインが描画され、消えるまでの時間(秒単位)です。duration が 0 の場合は 1 フレームのみ表示されます。

            //プレイヤーが地に足がついている状態
            if (Physics.Raycast(origin,-Vector3.up,out hit, minimumDistanceNeededToBeginFall, ignoreForGroundCheck))
            {

                //Rayが衝突した面が向いている方向のベクトルをvector3で出力
                normalVector = hit.normal;

                //レイがコライダー(地面)にヒットした位置 (ワールド空間)。
                Vector3 tp = hit.point;
               // Debug.Log("tp:" + tp);

                playerManager.isGrounded = true;
                targetPosition.y = tp.y;

                //プレイヤーが空中の場合
                if (playerManager.isInAir)
                {
                    //プレイヤーが設定時間より長く空中にいる場合
                    if (inAirTimer > 0.5f)
                    {
                        Debug.Log("You were in the air for" + inAirTimer);

                        //着地アニメーション
                        animatorHandler.PlayTargetAnimation("Land", true);
                        inAirTimer = 0;
                    }
                    // //プレイヤーが設定時間より短く空中にいる場合
                    else
                    {
                        //移動アニメーション
                        animatorHandler.PlayTargetAnimation("Locomotion", false);
                        inAirTimer = 0;
                    }

                    playerManager.isInAir = false;
                }
            }
            //プレイヤーが空中時
            else
            {

                if (playerManager.isGrounded)
                {
                    playerManager.isGrounded = false;
                }

                if (playerManager.isInAir == false)
                {
                    if (playerManager.isInteracting == false)
                    {
                      //  Debug.Log("010");

                        //プレイヤーが落下中のアニメーション
                        animatorHandler.PlayTargetAnimation("Falling", true);
                    }

                    Vector3 vel = rigidbody.velocity;
                    vel.Normalize();
                    rigidbody.velocity = vel * (movementSpeed / 2);
                    playerManager.isInAir = true;
                }
            }

            //プレイヤーが地面に接地している場合
            if (playerManager.isGrounded)
            {
                 //プレイヤーがアニメーション実行しているまたは、移動している場合
                if (playerManager.isInteracting || inputHandler.moveAmount > 0)
                {
                     // myTransform.position = Vector3.Lerp(myTransform.position, targetPosition, Time.deltaTime*2);

                    myTransform.position = targetPosition;
                }
                //プレイヤーが動いていない場合
                else
                {
                                myTransform.position = targetPosition;
                }
            }
        }

今回は以上です。