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

今回は攻撃アクションを実装します。

youtu.be

 public class PlayerLocomotion : MonoBehaviour //+EP1 playerにアタッチ
    {
  public void HandleMovement(float delta)
        {
            //+EP5 ローリング中の場合、以降なにもしない
            if (inputHandler.rollFlag)
                return;

            //+EP7 アニメーション実行中、以降なにもしない
            if (playerManager.isInteracting)
                return;

            moveDirection = cameraObject.forward * inputHandler.vertical;
            //cameraObject.forward:world spaceに対するプレイヤーの前方位置(0.0, 0.0, -1.0)
            //inputHandler.vertical:キーボードW(+1) or S(-1)
            //moveDirection:キーボードW(0.0, 0.0, -1.0) or S(0.0, 0.0, 1.0)

            moveDirection += cameraObject.right * inputHandler.horizontal;
            //cameraObject.right:world spaceに対するプレイヤーの右位置(-1.0, 0.0, 0.0)
            //inputHandler.horizontal:キーボードA(-1) or D(+1)
            //cameraObject.right * inputHandler.horizontal:キーボードA(1.0, 0.0, 0.0) or D(-1.0, 0.0, 0.0)
            // moveDirection:キーボードW,A押下の場合(1.0, 0.0, -1.0) 

            //正規化:ベクトルの向きは変えずに大きさを1にする
            moveDirection.Normalize();

            moveDirection.y = 0; //+EP2

            float speed = movementSpeed;

            //+EP5 スプリントフラグがONになった場合の設定

            // if (inputHandler.sprintFlag)
            if (inputHandler.sprintFlag && inputHandler.moveAmount>0.5)
            {
                speed = sprintSpeed;
                playerManager.isSprinting = true;
                moveDirection *= speed;
            }
            else
            {
                moveDirection *= speed;
                playerManager.isSprinting = false; //+EP9
            }

            //ProjectOnPlane:斜面に沿ったベクトルを計算
            Vector3 projectedVelocity = Vector3.ProjectOnPlane(moveDirection, normalVector);

            //velocityによりプレイヤー移動
            rigidbody.velocity = projectedVelocity;

            //animatorの変数Verticalと変数Horizontalの値を設定
            animatorHandler.UpdateAnimatorValues(inputHandler.moveAmount, 0,playerManager.isSprinting);

            if (animatorHandler.canRotate)
            {
                HandleRotaion(delta);
            }
        }
    }
||

>|cs|
 public class InputHandler : MonoBehaviour //+EP1 playerにアタッチ
    {
        public float horizontal;
        public float vertical;
        public float moveAmount;
        public float mouseX;
        public float mouseY;

        public bool b_Input; //+EP4
        public bool rb_Input;// +EP9
        public bool rt_Input; //+EP9

        public bool rollFlag; //+EP4
        public float rollInputTimer; //+EP5 ローリングボタンを押下している時間を格納
        public bool sprintFlag; //+EP5 スプリントフラグがOnの場合、true

        PlayerControls inputActions;
        PlayerAttacker playerAttacker; //+EP9
        PlayerInventory playerInventory; //+EP9

        Vector2 movementInput;
        Vector2 cameraInput;

        //+EP9
        private void Awake()
        {
            playerAttacker = GetComponent<PlayerAttacker>();
            playerInventory = GetComponent<PlayerInventory>();
        }

        public void OnEnable() //OnEnableはオブジェクトが有効になったときに呼び出されます.
        {
            if (inputActions == null)
            {
                inputActions = new PlayerControls();
                //アクション実行中(performed)に、+=でデリゲート登録されたメソッドが実行される。
                inputActions.PlayerMovement.Movement.performed += inputActions => movementInput = inputActions.ReadValue<Vector2>();
                inputActions.PlayerMovement.Camera.performed += i => cameraInput = i.ReadValue<Vector2>();
            }
            //インプットアクションの有効化
            inputActions.Enable();
        }

        private void OnDisable()
        {
            //インプットアクションの無効化
            inputActions.Disable();
        }

        public void TickInput(float delta)
        {
            MoveInput(delta);
            HandleRollInput(delta); //+EP4
            AttackInput(delta); //+EP9
        }

        //キーボードやマウスの入力値を取得
        public void MoveInput(float delta)
        {
            //Actions:Movementのx方向入力値(キーボードA(-1) or D(+1))を変数horizontalに代入
            horizontal = movementInput.x;
            //Actions:Movementのy方向入力値(キーボードW(+1) or S(-1))を変数Verticalに代入
            vertical = movementInput.y;
           //Clamp値(0~1)を変数moveAmountに代入。WASDの押下により1が代入される。
            moveAmount = Mathf.Clamp01(Mathf.Abs(horizontal) + Mathf.Abs(vertical));

            //Actions:Cameraの入力値(マウスの場合、前フレーム位置からの差分)を変数mouseに代入
            //mouseXはx方向値(画面横方向のデルタ値)を代入。-1~1
            //mouseYはy方向値(画面縦方向のデルタ値)を代入。-1~1
            mouseX = cameraInput.x;
            mouseY = cameraInput.y;
        }

        //+EP4 ローリングをONした場合の設定
        private void HandleRollInput(float delta)
        {
            //ローリングボタン押下でb_input=true
            b_Input = inputActions.PlayerActions.Roll.phase == UnityEngine.InputSystem.InputActionPhase.Started;

            //ローリングボタンを押下中
            if (b_Input)
            {
                //+EP5
                rollInputTimer += delta;
                sprintFlag = true;
            }
            else //+EP5
            {
                //ローリングボタンを下記条件でON/OFFした場合、ローリングを行う
                if(rollInputTimer>0 && rollInputTimer < 0.5f)
                {
                    sprintFlag = false;
                    rollFlag = true;
                }

                rollInputTimer = 0;
            }

        }

        //+EP9
        private void AttackInput(float delta)
        {
            //InputActionのRB,RT押下をr*_inputに設定
            inputActions.PlayerActions.RB.performed += i => rb_Input = true;
            inputActions.PlayerActions.RT.performed += i => rt_Input = true;

            if (rb_Input)
            {
                playerAttacker.HandleLightAttack(playerInventory.rightWeapon);
            }

            if (rt_Input)
            {
                playerAttacker.HandleHeavyAttack(playerInventory.rightWeapon);
            }
        }
    }
public class ResetAnimatorBool : StateMachineBehaviour //+EP9 Animator Override Emptyにアタッチ
{
    public string targetBool;
    public bool status;

    public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        animator.SetBool(targetBool, status);
    }
}
[CreateAssetMenu(menuName="Items/Weapom Item")]
    public class WeaponItem : Item //+EP8
    {
        public GameObject modelPrefab;
        public bool isUnarmed;

        //+EP9
        [Header("On Handed Attack Animations")]
        public string OH_Light_Attack_1;
        public string OH_Heavy_Attack_1;
    }
 public class PlayerAttacker : MonoBehaviour //+EP9 プレイヤーにアタッチ
    {
        AnimatorHandler animatorHandler;

        private void Awake()
        {
            animatorHandler = GetComponentInChildren<AnimatorHandler>();
        }

        //ライトアタックアニメーションを実装
        public void HandleLightAttack(WeaponItem weapon)
        {
            animatorHandler.PlayTargetAnimation(weapon.OH_Light_Attack_1, true);
        }

        //ヘビーアタックアニメーションを実装
        public void HandleHeavyAttack(WeaponItem weapon)
        {
            animatorHandler.PlayTargetAnimation(weapon.OH_Heavy_Attack_1, true);
        }
    }