【ダークソウル風ゲームを作りたい(Unity)。その9】
今回は攻撃アクションを実装します。
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); } }