【Unity】なめらかに回転させる

投稿者: | 2020-04-21


猿をなめらかに回転させてみました。

前の記事のボールを飛ばすスクリプトに2行追加して、猿にボールをセットします。

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

public class GameScript3 : MonoBehaviour
{

    Vector3 cursorPosition;
    Vector3 cursorPosition3d;
    RaycastHit hit;

    Vector3 cameraPosition;
    Vector3 throwDirection;

    public GameObject ball;
    Rigidbody rb_ball;

    public float thrust = 10f;

    [SerializeField]MonkeyScript sc_monkey;


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

    }

    // Update is called once per frame
    void Update()
    {
        cameraPosition = Camera.main.transform.position; // カメラの位置

        cursorPosition = Input.mousePosition; // 画面上のカーソルの位置
        cursorPosition.z = 10.0f; // z座標に適当な値を入れる
        cursorPosition3d = Camera.main.ScreenToWorldPoint(cursorPosition); // 3Dの座標になおす

        throwDirection = cursorPosition3d - cameraPosition; // 玉を飛ばす方向

        if (Input.GetMouseButtonDown(0)) // マウスの左クリックをしたとき
        {
            rb_ball = Instantiate(ball, cameraPosition, transform.rotation).GetComponent<Rigidbody>(); // 玉を生成
            rb_ball.AddForce(throwDirection * thrust, ForceMode.Impulse); // カーソルの方向に力を一度加える


            sc_monkey.SetTarget(rb_ball.gameObject); // 玉を猿のターゲットにセットする
        }
    }
}

このスクリプトをシーンの空のゲームオブジェクトにつけて、シーンの猿をアタッチします。

また、猿にもスクリプトをつけます。

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

public class MonkeyScript : MonoBehaviour
{
    [SerializeField] GameObject target;
    GameObject cam;

    // Start is called before the first frame update
    void Start()
    {
        cam = Camera.main.gameObject;
        target = cam;

    }

    // Update is called once per frame
    void Update()
    {

        transform.LookAt(Vector3.Lerp(transform.forward + transform.position, target.transform.position, 0.02f), Vector3.up);

        if (target.transform.position.z > 30f)
        {
            target = cam;           
        }
    }

    public void SetTarget(GameObject g)
    {

        target = g;
    }

}

猿は常に、transform.LookAt() に入れる座標の方を向きます。ここにターゲットの位置をそのまま入れると猿は瞬時にその場所へ向きますが、Vector3.Lerpを使って、猿が今見ている場所からターゲットの場所までの中間にある場所を向かせます。

Vector3.Lerp()の第三引数が0だと第1引数の座標、1だと第2引数の座標、中間の値だとその割合だけ第2引数の座標へ近づいた地点の座標が返ります。
この値を小さくして毎フレーム実行すれば、次のフレームでは少しターゲットへ近づいた地点からターゲットまでの間の座標を向き、次はさらにその座標からターゲットまでの間の地点を向き、という風にターゲットの方を向くのに何フレームもかかるので、なめらかに回転します。この値を下げればよりなめらかに、上げればフラットになります。

空のゲームオブジェクトから、ボールを飛ばした時に、SetTargetメソッドを実行してボールをターゲットに設定します。ボールがセットされていないときや、ボールが遠くへ行ったときはメインカメラをターゲットにします。

コメントを残す

メールアドレスが公開されることはありません。