わかゲームスタジオ

ゲーム制作初心者専門学生の備忘録

Unity プレイヤーの回転をなめらかにしたい

瞬時に入力方向を向いても良いのですが、なめらかに向いても良いと思うのです。
というわけで今回はなめらかな振り返りを実装しようと思います。

↓今回できること↓

前回までの記事を先に読んでください。
wakagamestudio.hatenablog.jp


Unity ver.2019.3.4f1

①変数を追加

    [Header("回転速度")]
    [SerializeField]
    private float rotateSpeed;
  • 回転速度を決める変数です。

②前回書いた分を削除

    //===向き切り替え===//
    if (inputVector != Vector2.zero)
    {
        // キャラクターの向きを進行方向に
        transform.rotation = Quaternion.LookRotation(moveVector);
    }
  • 回転部分を書き換えます。

③削除部分にコードを追加

    Vector3 dirMoveVector = (moveVector + transform.position) - gameObject.transform.position;
    Vector3 cross = Vector3.Cross(transform.forward, moveVector);
    if (hori != 0 || ver != 0)
    {
        if (cross.y <= 0)
        {
            transform.rotation = Quaternion.Euler(0, transform.eulerAngles.y - rotateSpeed, 0);
        }
        else
        {
            transform.rotation = Quaternion.Euler(0, transform.eulerAngles.y + rotateSpeed, 0);
        }
    }
  • 向いている方向と向きたい方向で外積を取ります。

すると、


以上です。
操作性が極端に悪くならない限りはこれのほうが滑らかでよいかもしれませんね。

これまでの全コード

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

public class PlayerMovement : MonoBehaviour
{
    [Header("リジッドボディ")]
    [SerializeField]
    private Rigidbody rigidbody;

    [Header("移動速度")]
    [SerializeField]
    private float speed = 15;

    [Header("入力制限")]
    [SerializeField]
    [Range(0, 1)]
    private float inputLimit = 0.1f;

    [Header("回転速度")]
    [SerializeField]
    private float rotateSpeed;

    //入力値代入用
    private Vector2 inputVector;
    //移動方向決定
    private Vector3 moveVector;

    void Update()
    {
        //入力値を代入
        float hori = Input.GetAxis("Horizontal") >= -inputLimit && Input.GetAxis("Horizontal") <= inputLimit ? 0 : Input.GetAxis("Horizontal");
        float ver = Input.GetAxis("Vertical") >= -inputLimit && Input.GetAxis("Vertical") <= inputLimit ? 0 : Input.GetAxis("Vertical");
        inputVector = new Vector2( hori, ver);

        //カメラの向きから移動方向を決定
        moveVector = (Vector3.Scale(Camera.main.transform.forward, new Vector3(1, 0, 1)).normalized * inputVector.y + Camera.main.transform.right * inputVector.x) * speed;

        Vector3 dirMoveVector = (moveVector + transform.position) - gameObject.transform.position;
        Vector3 cross = Vector3.Cross(transform.forward, moveVector);
        if (hori != 0 || ver != 0)
        {
            if (cross.y <= 0)
            {
                transform.rotation = Quaternion.Euler(0, transform.eulerAngles.y - rotateSpeed, 0);
            }
            else
            {
                transform.rotation = Quaternion.Euler(0, transform.eulerAngles.y + rotateSpeed, 0);
            }
        }
    }

    private void FixedUpdate()
    {
        //移動方向に重力分を足す
        rigidbody.velocity = moveVector + new Vector3(0, rigidbody.velocity.y, 0);
    }
}