キャラクターの向きを基準に移動する

<動作概要>

キーボードの入力 (↑↓→←) によって、キャラクターの移動を制御するスクリプト。
その際キャラクターの向いている方向を基準とする。
例えば↑を押したとき、ワールド座標の↑方向(Z軸)ではなく、キャラクターの向いている方向に移動する。

カメラはUnityちゃんの子オブジェクトにしているので、常に背後からのアングルになる。

<動作環境>

Unity 2019.3.9f1

<ソースコード>

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


public class CharacterManager : MonoBehaviour
{

    //------------------------------public変数の宣言---------------------------------------

    //歩行速度
    public float walkSpeed;
    //走行速度
    public float runSpeed;
    //キャラクターの回転速度
    public float rotationalSpeed;

    //------------------------------private変数の宣言--------------------------------------

    AnimatorEventGenerator animatorEventGenerator;
    CharacterController controller;

    //移動方向
    Vector3 moveDirection;
    
    float direction_h;
    float direction_v;
    float moveSpeed;

    void Start()
    {
        //private変数の初期化
        animatorEventGenerator = GetComponent<AnimatorEventGenerator>();
        controller = GetComponent<CharacterController>();
        moveDirection = transform.forward.normalized;
    }

    {
        //ジャンプ
        if (Input.GetButtonDown("Jump"))
        {
            animatorEventGenerator.startJumpEvent();
        }

        //上下左右移動

        direction_h = Input.GetAxis("Horizontal");
        direction_v = Input.GetAxis("Vertical");

        if (direction_h == 0 && direction_v == 0) {
            animatorEventGenerator.endWalkEvent();
            animatorEventGenerator.endRunEvent();
        } else {
  
            //移動方向の単位ベクトルの取得
            if (Vector3.Dot(moveDirection.normalized, transform.forward.normalized) > 0.99f) {
                moveDirection = transform.forward.normalized * direction_v + transform.right.normalized * direction_h;
            }
                
            //移動処理
            if(Input.GetButton("Run")){
                animatorEventGenerator.startRunEvent();
                moveSpeed = runSpeed;
            } else {
                animatorEventGenerator.startWalkEvent();
                moveSpeed = walkSpeed;
            }
            
            controller.Move(moveDirection * moveSpeed * Time.deltaTime);

        }

        //回転処理。移動方向へ回転。Quaternion.RotateTowards関数によって滑らかに回転を行う。
        transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.LookRotation(moveDirection), rotationalSpeed * Time.deltaTime);
    }
}

<ソースコード解説>

①Input.GetAxisでキーボードの入力を取得する

入力値は「Edit」→「Project Settings」→ 「 InputManager 」で細かく設定可能。↑を押している間は変数direction_vに1.0(↓の時は-1.0)、→を押している間は変数direction_hに1.0(←の時は-1.0)が代入される

②キャラの移動方向(ベクトル)を計算する

ソースコード内の以下の箇所で移動方向を計算している。
“moveDirection = transform.forward.normalized * direction_v + transform.right.normalized * direction_h;”

transform.forwardはキャラクターの正面方向に伸びるベクトル。これをnormalizedメソッドで単位ベクトルにして、キーボードの↑↓の入力値direction_vを掛ける。
同様にtransform.rightとdirection_hを掛ける。
最終的に2つのベクトルを足し合わせることで、キャラクターの向きを基準とした 移動方向(ベクトル)が決定する。

移動方向を計算する前に、1フレーム前の移動方向とキャラクターの内積を計算する。 後述の④でキャラクター回転しきる前に 移動方向が更新されるのを防ぐ。内積が1のときは両ベクトルが同じ方向を向いている。
“if (Vector3.Dot(moveDirection.normalized,transform.forward.normalized) > 0.99f)”

③キャラクターを移動させる

移動にはCharacterControllerクラスのmoveメソッドを使用する。
CharacterController クラスはInspectorタブの「Add Componet」→「Physics」→「 CharacterController 」でオブジェクト(Unityちゃん)にアタッチできる。

④キャラクターの向きを移動方向に回転させる。

Quaternion.LookRotationメソッドを使って、移動方向にキャラクターを回転させる。その際Quaternion.RotateTowardsメソッドで滑らかに回転するようにしている。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です