2016-10-04 7 views
3

У меня возникла проблема в моей сцене. Что я делаю, есть две панели, на одной панели есть одна кнопка, которая выполняет OnClick() прослушиватель с именем метода RotateCamera().Камера не плавно интерполирует свое вращение

Image 1

Кроме того, в иерархии есть MainMenugameobject, который крепится с помощью одного сценария. Когда я играю сцену и нажимаю на кнопку panel one, чем MainCamera, поверните на 90 градусов в направлении второй панели. Скрипт отлично работает, но я хочу плавно поворачивать камеру на эту панель, когда я нажимаю на эту кнопку - прямо сейчас она вращается мгновенно. Я не знаю, что я делаю неправильно в этом скрипте.

public class CameraSmooth : MonoBehaviour { 

    private bool check = false; 
    private Transform from; 
    private Transform to; 

    void Start(){ 
     from = Camera.main.transform; 
    } 

    void Update(){ 
     if (to != null) { 
      Camera.main.transform.rotation = Quaternion.Slerp (from.rotation, to.rotation, 3 * Time.deltaTime); 
     } 
    } 

    public void RotateCamera(){ 
     if (!check) { 
      Camera.main.transform.Rotate (0,90f,0f); 
      to = Camera.main.transform; 
      check = true; 
     } 
     else if (check) { 
      Camera.main.transform.rotation = Quaternion.identity; 
      to = Camera.main.transform; 
      check = false; 
     } 
    } 
} 
+0

Проблема в том, что ваша камера сразу вращается? Потому что похоже, что именно это делает ваш код. – Serlite

+0

@Serlite да, это немедленно вращается! – hamel123

ответ

3

Основная проблема здесь состоит в том, что вы звоните Camera.main.transform.Rotate() в RotateCamera(). Это приводит к немедленному применению вращения к камере, что приводит к мгновенному вращению, которое вы видите.

Еще одно небольшое заблуждение - поскольку Transform является ссылочным типом, from и to всегда на самом деле указывают на тот же экземпляр (Transform камеры)! Наконец, значение 3 * Time.deltaTime всегда будет составлять среднее значение около 3/60 и, вероятно, никогда не окажется близко к 1, что необходимо для завершения интерполяции. Таким образом, следующая строка:

Camera.main.transform.rotation = Quaternion.Slerp (from.rotation, to.rotation, 3 * Time.deltaTime); 

не сможет ничего сделать, даже если первая проблема адресована.

Ситуация требует иного решения, на мой взгляд:

  1. Сохранение целевых ротацию в Quaternion переменных, а не устанавливать их непосредственно на Transform и отслеживании начального вращения камеры

  2. Поддержание таймера, который отслеживает ход вращения (или вы можете отказаться от Slerp() и просто применить инкрементное вращение напрямую, это также действительный подход)

Вот мой Рекомендованное обновление кода:

public class CameraSmooth : MonoBehaviour { 

    private bool check = false; 
    private float rotationProgress = 1; 
    private Quaternion initial; 
    private Quaternion from; 
    private Quaternion to; 

    void Start(){ 
     // Cache the starting rotation, so we can calculate rotations relative to it 
     initial = Camera.main.transform.rotation; 
    } 

    void Update(){ 
     if (rotationProgress < 1) { 
      rotationProgress += 3 * Time.deltaTime; 
      Camera.main.transform.rotation = Quaternion.Slerp (from, to, rotationProgress); 
     } 
    } 

    public void RotateCamera(){ 
     from = Camera.main.transform.rotation; 
     rotationProgress = 0; 

     if (!check) { 
      to = initial * Quaternion.Euler(0,90f,0f); 
      check = true; 
     } 
     else if (check) { 
      to = initial; 
      check = false; 
     } 
    } 
} 

(. Не проверял этот код, поэтому, пожалуйста, дайте мне знать, если есть какие-либо вопросы) Надеюсь, что это помогает! Дайте знать, если у вас появятся вопросы!