Unity カメラの位置リセットを追加する
前回スティックでカメラを動かしたので、今回はカメラの位置リセットを設定しようと思います。
↓前回↓
wakagamestudio.hatenablog.jp
↓今回できること↓
カメラの向きリセットしてみた pic.twitter.com/8svgZpUtex
— わかです (@wakaGameStudio) 2020年9月4日
Unity var2019.3.4f1
①InputManagerを編集する
- カメラ向きリセット用のインプットを設定しておきます。
②変数を宣言する
[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
- 向きリセットに使う変数たちです。
③Startで初期化する
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];
- Startで初期化しておきます。
④Updateに処理を追加する
//カメラ位置リセット中 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(); }
- Updateでリセット回転中の動きを書きます。
⑤関数を追加する
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]; }
- リセット開始時に初期化する関数と、向きを360°に変換する用の計算関数です。
前回分も含む全コード
using System.Collections; using System.Collections.Generic; using UnityEngine; public class CameraAction : MonoBehaviour { [Header("カメラが向くターゲット")] [SerializeField] private GameObject target; //ターゲット [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; //入力値を判定 Vector3 angle = new Vector3(Input.GetAxis("HorizontalR") * rotateSpeed.x, Input.GetAxis("VerticalR") * 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) || (Input.GetAxis("VerticalR") >= inputLimit && transform.localEulerAngles.x < 360 + rotateLower && 180 <= transform.localEulerAngles.x) || (Input.GetAxis("VerticalR") <= -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) || (Input.GetAxis("VerticalR") <= -inputLimit && transform.localEulerAngles.x < 360 + rotateLower && 180 <= transform.localEulerAngles.x) || (Input.GetAxis("VerticalR") >= 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]; } }
以上です。
リセット中にもカメラを動かせるようになっているので、ゲームに合わせて制限する等してみてください。
次回はマウスでも動かせるようにしようと思います。