LoginSignup
1
0

More than 1 year has passed since last update.

【Unity】キャラクターをなめらかに方向転換させる

Posted at

はじめに

Unityでキャラクターの方向転換をしたいときに、なめらかに方向転換する方法をまとめました。

Playerを準備する

Hierarchyウィンドウで右クリック→Create Emptyで空のゲームオブジェクトを作成し、名前をPlayerとします。
さらに、Hierarchyウィンドウで右クリック→3D Objectから、CubeとSphereを生成します。
これらをHierarchyウィンドウの中で、Playerにドッグ&ドロップして子要素にします。
最後に、Sphereの位置を少しずらして下画像のようにします。これでPlayerがどちらを向いているか分かるようになりました。
スクリーンショット 2022-07-17 11.12.14.png

Scriptを書く

ProjectウィンドウのAssets内で右クリック→Create→C# Scriptの順に操作します。
生成されたファイル名をPlayerとしておきます。
出来上がったファイルをHierarchyウィンドウのPlayerにAdd Componentします。

それでは中身を書いていきます。Playerファイルをダブルクリックで開きます。
以下のようにコードを記述します。

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

public class Player : MonoBehaviour
{
    private const float RotateSpeed = 720f;

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        Vector3 direction = InputToDirection();
        float magnitude = direction.magnitude;

        if (Mathf.Approximately(magnitude, 0f) == false)
        {
            UpdateRotation(direction);
        }
    }

    private Vector3 InputToDirection() {
        Vector3 direction = new Vector3(0f, 0f, 0f);

        if (Input.GetKey(KeyCode.RightArrow))
        {
            direction.x += 1f;
        }

        if (Input.GetKey(KeyCode.LeftArrow))
        {
            direction.x -= 1f;
        }

        if (Input.GetKey(KeyCode.UpArrow))
        {
            direction.z += 1f;
        }

        if (Input.GetKey(KeyCode.DownArrow))
        {
            direction.z -= 1f;
        }

        return direction.normalized;
    }

    private void UpdateRotation(Vector3 direction)
    {
        Quaternion from = transform.rotation;
        Quaternion to = Quaternion.LookRotation(direction);
        transform.rotation = Quaternion.RotateTowards(from, to, RotateSpeed * Time.deltaTime);
    }
}

Updateメソッドの中身を解説します。
まず、InputToDirection()で入力された方向を取得します。
次に、direction.magnitudeでベクトルの大きさを取得します。
そして、magnitudeと0を比較して、近似していない場合(ベクトルが0でない場合)にUpdateRotationメソッドで向きを変えます。Mathf.Approximatelyは不動小数点の誤差を考慮したfloat型の比較方法です。

    void Update()
    {
        Vector3 direction = InputToDirection();
        float magnitude = direction.magnitude;
        if (Mathf.Approximately(magnitude, 0f) == false)
        {
            UpdateRotation(direction);
        }
    }

InputToDirectionメソッドを定義します。
まず、directionを0ベクトルとして初期化します。
あとは、入力されたキーの方向で条件分岐をしてdirectionのxまたはzを更新するだけです。
returnでは長さ1のベクトルにしてdirectionを返しています。これは斜め方向へ移動する際に長さが1を超えてしまうのでそれを補正するためです。今回は移動は実装しないのであまり関係ありませんが、実装する際はやった方がいいと思います。

    private Vector3 InputToDirection() {
        Vector3 direction = new Vector3(0f, 0f, 0f);

        if (Input.GetKey(KeyCode.RightArrow))
        {
            direction.x += 1f;
        }

        if (Input.GetKey(KeyCode.LeftArrow))
        {
            direction.x -= 1f;
        }

        if (Input.GetKey(KeyCode.UpArrow))
        {
            direction.z += 1f;
        }

        if (Input.GetKey(KeyCode.DownArrow))
        {
            direction.z -= 1f;
        }

        return direction.normalized;
    }

最後にUpdateRotationを解説します。ここが今回のメインです。
まず初めに、キャラクターを回転させる角度をRotateSpeedで設定します。
使い方は後述します。

public class Player : MonoBehaviour
{
    private const float RotateSpeed = 720f;

    // Start is called before the first frame update
    void Start()
    {
        
    }

UpdateRotationの中身を解説します。
directionを引数に取り、その方向へキャラクターを回転させるメソッドです。

まず、Quaternion from = transform.rotation;で回転前のキャラクターの向きを取得します。Quaternionは回転を扱うための型です。

次に、Quaternion to = Quaternion.LookRotation(direction);でキャラクターが回転する方向を取得します。Quaternion.LookRotationは与えられた方向のベクトルを向くQuaternionを返すメソッドです。

最後の、transform.rotation = Quaternion.RotateTowards(from, to, RotateSpeed * Time.deltaTime);でキャラクターを回転させます。
第1引数から第2引数へ、最大でも第3引数の角度分だけ回転させたQuaternionを返します。
これにより、1フレーム内でも最大でもRotateSpeed * Time.deltaTimeしか回転しないため、キャラクターがなめらかに回転します。

    private void UpdateRotation(Vector3 direction)
    {
        Quaternion from = transform.rotation;
        Quaternion to = Quaternion.LookRotation(direction);
        transform.rotation = Quaternion.RotateTowards(from, to, RotateSpeed * Time.deltaTime);
    }

動作確認

gifなので少し分かりづらいかもですが、なめらかに方向転換できています。
RotateSpeedを小さくすればもっとゆっくりと回転するようになります。
2.gif

まとめ

今回はキャラクターをなめらかに回転させる方法についてまとめました。
汎用性がある内容だと思いますのでぜひ試してみてください。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0