Я разрабатываю игру, в первую очередь ориентированную на просмотр с камер видеонаблюдения. Камеры должны автоматически вращаться. Код работает безупречно до момента, когда камере нужно изменить направление вращения. Камера начинает быстро переключаться между движением по часовой стрелке и против часовой стрелки, в результате чего камера покачивается, а не вращается. Код:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class cam : MonoBehaviour
{
public float moveMin;
public float moveMax;
public float turnSpeed;
public bool turnDir;
private Transform self;
public Vector3 eulerTurn;
// Start is called before the first frame update
void Start()
{
self = this.gameObject.transform;
}
// Update is called once per frame
void Update()
{
eulerTurn = self.localRotation.eulerAngles;
if (eulerTurn.y <= moveMin) { turnDir = false; }
if (eulerTurn.y >= moveMax) { turnDir = true; }
switch (turnDir) {
case false:
self.localRotation = Quaternion.Euler(eulerTurn.x, eulerTurn.y + (turnSpeed * Time.deltaTime), eulerTurn.z);
break;
case true:
self.localRotation = Quaternion.Euler(eulerTurn.x, eulerTurn.y + (-turnSpeed * Time.deltaTime), eulerTurn.z);
break;
}
}
}
Я пробовал играть с <=
, >=
и другими значениями, но камера всегда зависает в точке, где ей нужно повернуться. Есть идеи?
P.S. moveMin
установлен на 300 (-60), а moveMax
установлен на 0.
Обновлено: Код, который я опубликовал, имеет другую проблему, потому что я возился с ним. Этот код вообще не меняет направление, но я понимаю почему. Скоро выложу обновленную версию кода.
В каждом кадре вы добавляете (turnSpeed * Time.deltaTime) к текущему углу. В вероятном случае, когда он пройдет 300 или 0 (например, 298.5f + 2.5f пройдет 300), камера начнет поворачиваться по часовой стрелке и против часовой стрелки каждый кадр. (298.5f, 301.0f, 298.5f, 301.0f и так далее). Вы должны использовать математические функции, которые, как мы уверены, не превысят некоторых значений. Функция Sin() является хорошим примером, поскольку мы знаем, что она всегда будет находиться в диапазоне от -1 до 1. Что-то вроде этого должно натолкнуть вас на мысль:
void Update()
{
transform.rotation = Quaternion.Euler(maxRotation * Mathf.Sin(Time.time * turnSpeed), 0f, 0f);
}
Кроме того, в вашем коде есть еще одна вещь, которая работает нормально, но странно:
if (eulerTurn.y <= moveMin) { turnDir = false; }
if (eulerTurn.y >= moveMax) { turnDir = true; }
switch (turnDir) {
case false:
self.localRotation = Quaternion.Euler(eulerTurn.x, eulerTurn.y + (turnSpeed * Time.deltaTime), eulerTurn.z);
break;
case true:
self.localRotation = Quaternion.Euler(eulerTurn.x, eulerTurn.y + (-turnSpeed * Time.deltaTime), eulerTurn.z);
break;
}
Почему вы делаете дополнительные вычисления, чтобы понять, является ли логическое значение ложным или истинным? Сначала вы оцениваете что-то, чтобы увидеть, истинно это или ложно, затем присваиваете соответствующее значение в блоке if, которое вы только что оценили в условии if, а затем снова оцениваете в третий раз в операторе switch-case. Кроме того, вы используете оператор switch-case очень странным образом: case false или case true? Если есть 2 случая, достаточно одного оператора if.
Код, который вы написали, можно упростить следующим образом:
if (eulerTurn.y <= moveMin) {
self.localRotation = Quaternion.Euler(eulerTurn.x, eulerTurn.y + (turnSpeed * Time.deltaTime), eulerTurn.z);
}else if (eulerTurn.y >= moveMax){
self.localRotation = Quaternion.Euler(eulerTurn.x, eulerTurn.y + (-turnSpeed * Time.deltaTime), eulerTurn.z);
}