キャラクターの向きを基準に移動する
<動作概要>
キーボードの入力 (↑↓→←) によって、キャラクターの移動を制御するスクリプト。
その際キャラクターの向いている方向を基準とする。
例えば↑を押したとき、ワールド座標の↑方向(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メソッドで滑らかに回転するようにしている。