わかゲームスタジオ

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

Unity マウスでカメラを制御してみる

前回までカメラの操作を実装してきたので、今回はそれをよくあるマウス制御にも対応していきたいと思います。
先に前回までの記事をご覧ください。
wakagamestudio.hatenablog.jp
wakagamestudio.hatenablog.jp

UnityVar.2019.3.4f1

①変数を追加

    [Header("マウス感度")]
    [SerializeField]
    private Vector2 mouseSpeed;
  • マウス感度(マウス操作によるカメラの移動速度を設定します)

②入力値を設定

        //キーボードかコントローラか判断
        float rx = 0;
        float ry = 0;
        if (Input.GetJoystickNames().Length != 0 && Input.GetJoystickNames()[Input.GetJoystickNames().Length - 1] != "")
        {
            rx = Input.GetAxis("HorizontalR");
            ry = Input.GetAxis("VerticalR");
        }
        else
        {
            rx = Input.GetAxis("Mouse X") * mouseSpeed.x;
            ry = Input.GetAxis("Mouse Y") * mouseSpeed.y;
        }
  • 入力値変数を使いまわすため、現在ゲームパッドが接続されているか判定します。

③前々回記述部分を編集

    Input.GetAxis("HorizontalR") ->rx
    Input.GetAxis("VerticalR") -> ry
  • ジョイスティック入力の取得部分をすべて②で作成した変数におきかえます。

これで動くようになるはずです。
①で作成した変数に値を入れるのを忘れないでくださいね。

これまでの全コード

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

public class CameraAction : MonoBehaviour
{
    [Header("カメラが向くターゲット")]
    [SerializeField]
    private GameObject target; //ターゲット

    [Header("マウス感度")]
    [SerializeField]
    private Vector2 mouseSpeed;
    [Header("回転するスピード")]
    [SerializeField]
    private Vector2 rotateSpeed;
    [Header("回転できる上限")]
    [SerializeField]
    private float rotateCeiling;//回転できる上限
    [Header("回転できる下限")]
    [SerializeField]
    private float rotateLower;  //回転できる下限
    [Header("スティックの入力制限")]
    [SerializeField]
    private float inputLimit;   //スティックの入力制限

    [Header("左右反転")]
    public bool LROpposite; //trueで反転
    [Header("上下反転")]
    public bool UDOpposite; //trueで反転

    [Header("カメラ位置リセットする遷移時間")]
    [SerializeField]
    private float camReset;     //カメラ位置リセットする遷移時間

    private bool reset;     //カメラリセット
    private float resetTime;
    private float resetAngle;
    private float nowTime;
    private float[] camnum;
    private float[] before;
    private Vector2 initRotate; //初期角度X

    private Vector3 beforePos;  //ターゲットの前位置

    private void Start()
    {
        //beforePosを初期化
        beforePos = target.transform.position;

        initRotate.x = transform.localEulerAngles.x;
        initRotate.y = transform.localEulerAngles.y;
        reset = false;
        resetTime = camReset;
        resetAngle = initRotate.x;
        camnum = new float[2];
        before = new float[2];
    }

    private void Update()
    {
        //ターゲットが動いた分移動
        transform.position += target.transform.position - beforePos;

        //入力値を判定
        //キーボードかコントローラか判断
        float rx = 0;
        float ry = 0;
        if (Input.GetJoystickNames().Length != 0 && Input.GetJoystickNames()[Input.GetJoystickNames().Length - 1] != "")
        {
            rx = Input.GetAxis("HorizontalR");
            ry = Input.GetAxis("VerticalR");
        }
        else
        {
            rx = Input.GetAxis("Mouse X") * mouseSpeed.x;
            ry = Input.GetAxis("Mouse Y") * mouseSpeed.y;
        }
        Vector3 angle = new Vector3(rx * rotateSpeed.x, ry * rotateSpeed.y, 0) * Time.deltaTime;

        //カメラを回転させる
        //横回転
        if (LROpposite)
        {
            transform.RotateAround(target.transform.position, Vector3.down, angle.x);
        }
        else
        {
            transform.RotateAround(target.transform.position, Vector3.up, angle.x);
        }

        //縦回転
        if (UDOpposite)
        {
            if ((transform.localEulerAngles.x <= rotateCeiling || transform.localEulerAngles.x >= 360 + rotateLower)
                || (ry >= inputLimit && transform.localEulerAngles.x < 360 + rotateLower && 180 <= transform.localEulerAngles.x)
                || (ry <= -inputLimit && transform.localEulerAngles.x < 180 && rotateCeiling < transform.localEulerAngles.x))
            {
                transform.RotateAround(target.transform.position, transform.right, angle.y);
            }
        }
        else
        {
            if ((transform.localEulerAngles.x <= rotateCeiling || transform.localEulerAngles.x >= 360 + rotateLower)
                || (ry <= -inputLimit && transform.localEulerAngles.x < 360 + rotateLower && 180 <= transform.localEulerAngles.x)
                || (ry >= inputLimit && transform.localEulerAngles.x < 180 && rotateCeiling < transform.localEulerAngles.x))
            {
                transform.RotateAround(target.transform.position, -transform.right, angle.y);
            }
        }

        //beforePosを更新
        beforePos = target.transform.position;

        //カメラ位置リセット中
        if (reset && nowTime <= resetTime)
        {
            nowTime += Time.deltaTime;
            transform.RotateAround(target.transform.position, Vector3.down, ResetCalc(0));
            transform.RotateAround(target.transform.position, transform.right, ResetCalc(1));
        }
        else
        {
            reset = false;
        }

        //カメラ位置リセット開始
        if (Input.GetButtonDown("JoyR") && !reset)
        {
            resetTime = camReset;
            resetAngle = initRotate.x;
            ResetStart();
        }
    }

    private void ResetStart()
    {
        camnum[0] = transform.localEulerAngles.y;
        if (camnum[0] >= 180)
        {
            camnum[0] -= 360;
        }
        float pnum = target.transform.localEulerAngles.y;
        if (pnum >= 180)
        {
            pnum -= 360;
        }
        camnum[0] -= pnum;
        if (camnum[0] >= 180)
        {
            camnum[0] -= 360;
        }
        else if (camnum[0] < -180)
        {
            camnum[0] += 360;
        }
        camnum[1] = -transform.localEulerAngles.x + resetAngle;
        if (camnum[1] < 0)
        {
            camnum[1] += 360;
        }
        if (camnum[1] >= 180)
        {
            camnum[1] -= 360;
        }
        nowTime = 0;
        before[0] = 0;
        before[1] = 0;
        reset = true;
    }

    private float ResetCalc(int sel)
    {
        float Percentage = nowTime / resetTime;
        float[] num = new float[2];
        float[] pos = new float[2];

        num[sel] = camnum[sel] * Percentage;
        pos[sel] = num[sel] - before[sel];
        before[sel] = num[sel];
        return pos[sel];
    }
}

以上です。
次回はプレイヤー自体の回転について書こうと思います。