【ダークソウル風ゲームを作りたい(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; } } }
今回は以上です。