#android #unity3d #camera #clamp
#Android #unity3d #камера #зажим
Вопрос:
Мой код не работает, я пытаюсь зажать камеру, но она не работает. Он мгновенно переключается на 45. Как я могу зажать камеру?
Вот мой код.
using UnityEngine;
using System.Collections;
public class MoveCamera : MonoBehaviour
{
public float sensitivity = 4.0f;
private Vector3 mouseOrigin;
private bool isRotating;
private float minX = -45.0f;
private float maxX = 45.0f;
private float minY = -10.0f;
private float maxY = 10.0f;
float rotationY = 0.0f;
float rotationX = 0.0f;
void Start()
{
}
void Update ()
{
if (Input.GetMouseButtonDown (0)) {
mouseOrigin = Input.mousePosition;
isRotating = true;
}
if (!Input.GetMouseButton (0))
isRotating = false;
if (isRotating) {
Vector3 pos = Camera.main.ScreenToViewportPoint (Input.mousePosition - mouseOrigin);
transform.RotateAround (transform.position, transform.right, -pos.y * sensitivity);
transform.RotateAround (transform.position, Vector3.up, pos.x * sensitivity);
rotationY = Mathf.Clamp (transform.localEulerAngles.y, minY, maxY);
rotationX = Mathf.Clamp (transform.localEulerAngles.x, minX, maxX);
transform.localEulerAngles = new Vector3 (-rotationY, rotationX, 0);
}
}
}
Комментарии:
1. transform.RotateAround фактически поворачивает преобразование, поэтому при каждом обновлении вы поворачиваете, а затем снова поворачиваете с помощью transform.localEulerAngles. Что вы хотите, чтобы камера делала?
2. я хочу, чтобы камера фиксировала ось Y на 10 и -10, а ось X — на 45 и -45
3. если я удалю последние 3 строки, они будут вращаться так, как я хотел. но я хочу зажать, поэтому я добавил последние 3 строки, но они не зажимаются.
4. Хорошо, поэтому вместо того, чтобы использовать transform.RotateAround, сначала рассчитайте свои углы, закрепите их, а затем используйте transform.rotation = что угодно. Существуют различные методы, которые вы можете использовать в классах Quaternion и Vector3, чтобы помочь вам с углами
5. На самом деле, я новичок в этом, можете ли вы исправить код и опубликовать в качестве ответа? Я приму ответ. Кстати, спасибо за быстрый ответ 🙂 @Absinthe
Ответ №1:
Вот пример ограничения поворота оси Y, вы можете адаптировать его и для X. Вы не указали, на чем должен основываться лимит, поэтому здесь он основан на вращении другого объекта (общедоступной цели преобразования), это может быть ваш плеер или что-то еще.
public float sensitivity = 16.0f;
public Transform target;
void Update()
{
if (Input.GetMouseButton(0))
{
//Debug.Log(Quaternion.Angle(transform.rotation, target.rotation));
float angle = Quaternion.Angle(transform.rotation, target.rotation);
if(angle < 45 || angle > 315)
{
Vector3 pos = Camera.main.ScreenToViewportPoint(Input.mousePosition);
transform.RotateAround(pos, Vector3.up, Time.deltaTime * sensitivity);
}
}
}
Если вместо этого вы хотите ограничить на основе мирового пространства, просто проверьте вращение камеры:
public float sensitivity = 16.0f;
//public Transform target;
void Update()
{
if (Input.GetMouseButton(0))
{
float angle = transform.eulerAngles.y;
Debug.Log(angle);
if (angle < 45 || angle > 315)
{
Vector3 pos = Camera.main.ScreenToViewportPoint(Input.mousePosition);
transform.RotateAround(pos, Vector3.up, Time.deltaTime * sensitivity);
}
}
}
Обратите внимание, что в обоих случаях используется Time.deltaTime, чтобы гарантировать, что вращение происходит с одинаковой скоростью, независимо от частоты кадров игроков.
Если вы хотите изменить вращение, инвертируйте аргумент оси RotateAround:
transform.RotateAround(pos, -Vector3.up, Time.deltaTime * sensitivity);
Ответ №2:
Я это исправил. Вот полный код.
using UnityEngine;
using System.Collections;
public class MoveCamera : MonoBehaviour
{
public float sensitivity = 4.0f;
private Vector3 mouseOrigin;
private bool isRotating;
public GameObject cam;
void Start()
{
}
protected float ClampAngle(float angle, float min, float max) {
angle = NormalizeAngle(angle);
if (angle > 180) {
angle -= 360;
} else if (angle < -180) {
angle = 360;
}
min = NormalizeAngle(min);
if (min > 180) {
min -= 360;
} else if (min < -180) {
min = 360;
}
max = NormalizeAngle(max);
if (max > 180) {
max -= 360;
} else if (max < -180) {
max = 360;
}
return Mathf.Clamp(angle, min, max);
}
protected float NormalizeAngle(float angle) {
while (angle > 360)
angle -= 360;
while (angle < 0)
angle = 360;
return angle;
}
void Update ()
{
if (Input.GetMouseButtonDown (0)) {
mouseOrigin = Input.mousePosition;
isRotating = true;
}
if (!Input.GetMouseButton (0))
isRotating = false;
if (isRotating) {
cam.transform.localEulerAngles = new Vector3(0, ClampAngle(cam.transform.localEulerAngles.y, -45, 45), 0);
Vector3 pos = Camera.main.ScreenToViewportPoint (Input.mousePosition - mouseOrigin);
transform.RotateAround (transform.position, transform.right, -pos.y * sensitivity);
transform.RotateAround (transform.position, Vector3.up, pos.x * sensitivity);
}
}
}