剣で戦闘を行う(練習)

合戦における部隊運用を作っていく前に、一対一での戦闘できるようにします。
今回は刀vs刀を作ることにします。

プレイヤー

今回もユニティちゃんを使います。
[Transform]以外のコンポーネントを外し、[CharacterController]をつけます。

基本操作

そしてプレイヤーキャラクターに基本的な操作をするためのスクリプトを[Player.cs]に作ります。

[Player.cs]

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour {

    private CharacterController controller;
    private Animator animator;

    // キャラクターの速度
    private Vector3 velocity;
    private float speed = 10f;

    void Start() {
        controller = GetComponent<CharacterController>();
        animator = GetComponent <Animator> ();

    }

    void Update() {
        if(controller.isGrounded) {
            velocity = Vector3.zero;
	    // 横方向のキーの押し具合をx軸に入れる
	    velocity.x = Input.GetAxis("Horizontal") * speed;
	    // y軸は高さなので0に設定(キー操作で重力を無視して動く事はないから)
	    velocity.y = 0;
	    // 手前と奥方向に移動するキーの押し具合をz軸に入れる
	    velocity.z = Input.GetAxis("Vertical") * speed;

	}
	velocity.y += Physics.gravity.y * Time.deltaTime; // 重力値を計算
	controller.Move(velocity * Time.deltaTime);
    }

}

抜刀

次に、刀を鞘から抜けるようにします。
作戦としては、納刀状態の刀をユニティちゃんの腰[J_L_SusoSide_01]の子オブジェクトにし、抜刀状態の刀をユニティちゃんの右手[Character1_RightHand]の子オブジェクトにしておきます。
そして、納刀時には抜刀状態の刀を非表示に、抜刀時には納刀状態の刀を非表示にするというものです。

というわけで、とりあえず納刀状態と抜刀状態の刀を両方ユニティちゃんに付けます。この時、それぞれの刀はローカル座標にしておきます。
f:id:tatsuyann:20190501183137p:plain
f:id:tatsuyann:20190501183459p:plainf:id:tatsuyann:20190501183511p:plain

次に抜刀のアニメーションを作ります。[katana]アニメーターに写真のようにステートを作成します。
f:id:tatsuyann:20190501174106p:plain

そして[combat.cs]を作りましょう。

[combat.cs]

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerCombat : MonoBehaviour {
    private Animator animator;

    public GameObject sheathedSword;
    public GameObject drawnSword;

    void Start() {
        animator = GetComponent <Animator> ();
    }

    void Update() {
        if(Input.GetButtonDown("Draw")) {
            animator.SetBool("is_draw", true);
            sheathedSword.SetActive(false);
            drawnSword.SetActive(true);
        }
    }
}

これで抜刀できるようになりました!
f:id:tatsuyann:20190501211550p:plain
本当は抜刀アニメーションが始まってから抜き身の刀をアクティブ化するまでちょっと遅らせたいところですが、まあここでは良しとしましょう。

移動のアニメーション

次は走るアニメーションを付けます。
これは、納刀時のアイドルと抜刀時のアイドル両方からアクセスできるようにします。
f:id:tatsuyann:20190501214136p:plain


ステートマシンにする

キャラクターの制御をステートマシンで行います。
まず[CombatStates.cs]にステートを定義します。

[CombatStates.cs]

public enum CombatStates {
  //平常時
  IDLE,
  MOVE,
  // 戦闘時
  BATTOU,
  KAMAE,
  FMOVE,
  LOCKON,
  ATTACK,
  DEFENSE,
  DAMAGE,
  NOUTO
}

そしてこれを[PlayerCombat.cs]で利用します。

[PlayerCombat.cs]

private CombatStates state = CombatStates.IDLE;

void Update() {
    // ステートのチェック
    if (state == CombatStates.IDLE) {
        Idle();
    } else if (state == CombatStates.MOVE) {
        Move();
    } else if (state == CombatStates.BATTOU) {
        Battou();
    } else if (state == CombatStates.KAMAE) {
        Kamae();
    } else if (state == CombatStates.FMOVE) {
        FMove();
    } else if (state == CombatStates.LOCKON) {
        LockOn();
    } else if (state == CombatStates.ATTACK) {
        Attack();
    } else if (state == CombatStates.DEFENSE) {
        Defense();
    } else if (state == CombatStates.DAMAGE) {
        Damage();
    } else if (state == CombatStates.NOUTO) {
        Nouto();
    }

    // 入力の処理
    // 抜刀
    if(Input.GetButtonDown("Draw")) {
      state = SetState(CombatStates.BATTOU);
    }
    // 攻撃
    if(Input.GetButtonDown("Attack")) {
      state = SetState(CombatStates.ATTACK);
    }
}

// ステートの更新
public CombatStates SetState(CombatStates newState) {
    state = newState;
    return state;
}

// 抜刀時の処理
public void Battou() {
    animator.SetBool("is_draw", true);
}
void BattouStart() {
    sheathedSword.SetActive(false);
    drawnSword.SetActive(true);
}
void BattouEnd() {
    SetState(CombatStates.KAMAE);
}