Unity編輯器下場景(Scene)相機勻速運動解決方案

 美術在使用Unity編輯地形時,提出了讓場景相機勻速運動的需求,因爲Unity原本的場景相機移動速度不可控,同時在移動過程中會加速。在網上找了很多沒有確切的解決方案,Unity似乎也並沒有提供相關的接口。筆者嘗試了一種利用EditorWindow的Update刷新相機位置的方法,效果還不錯。
 首先創建一個EditorWindow,並在OnGui中提供速度的輸入框。
 如果仍使用Unity原有的相機控制快捷鍵,在持續運動相機一段時間後,Unity自帶的相機速度會加到很大,而Unity自己處理Scene相機頻率比Update快,即使我們在每次Update的時候手動設置了相機位置,仍然會造成相機位置突變,導致圖像晃動。因此筆者採用了一組新的快捷鍵(方向鍵+鼠標右鍵)的組合,既不與現有操作衝突,又可以在移動過程中隨時調整相機角度。
 通過SceneView.onSceneGUIDelegate註冊場景事件,捕捉按鍵變化,並在每個Update中獲取相機角度,計算運動後的位置。
 具體代碼如下:

public class SceneCameraControlWindow : EditorWindow
{
  private string m_speedStr = "1";
  private float m_speed = 1f;
  private bool m_enable = false;
  private Vector3 m_curMove;
  private void OnEnable()
  {
    SceneView.onSceneGUIDelegate += OnSceneFunc;
  }
  private void OnDisable()
  {
    SceneView.onSceneGUIDelegate -= OnSceneFunc;
  }
  private void OnGUI()
  {
    GUILayout.BeginHorizontal();
    GUILayout.Label("速度:");
    string newStr = GUILayout.TextField(m_speedStr);
    GUILayout.EndHorizontal();
    GUILayout.Label("按住鼠標右鍵+方向鍵(↑、↓、←、→)移動相機");
    float newSpeed;
    if(newStr != m_speedStr && float.TryParse(newStr, out newSpeed) && newSpeed >= 0)
    {
      m_speedStr = newStr;
      m_speed = newSpeed;
    }
  }

  private void Update()
  {
    if(m_enable && null != SceneView.lastActiveSceneView)
    {

      SceneView.lastActiveSceneView.pivot += (SceneView.lastActiveSceneView.camera.transform.rotation * m_curMove) * m_speed * Time.deltaTime;
    }
  }

  private void OnSceneFunc(SceneView target)
  {
    if (null == SceneView.lastActiveSceneView || target != SceneView.lastActiveSceneView)
      return;
    switch (Event.current.type)
    {
      case EventType.MouseDown:
        if(Event.current.button == 1)
        {
          m_enable = true;
        }
        break;
      case EventType.MouseUp:
        if (Event.current.button == 1)
        {
          m_enable = false;
        }
        break;
      case EventType.KeyDown:
        switch (Event.current.keyCode)
        {
          case KeyCode.UpArrow:
            m_curMove.z = 1f;
            break;
          case KeyCode.DownArrow:
            m_curMove.z = -1f;
            break;
          case KeyCode.LeftArrow:
            m_curMove.x = -1f;
            break;
          case KeyCode.RightArrow:
            m_curMove.x = 1f;
            break;
        }

        break;
      case EventType.KeyUp:
        switch (Event.current.keyCode)
        {
          case KeyCode.UpArrow:
            m_curMove.z = 0f;
            break;
          case KeyCode.DownArrow:
            m_curMove.z = 0f;
            break;
          case KeyCode.LeftArrow:
            m_curMove.x = 0f;
            break;
          case KeyCode.RightArrow:
            m_curMove.x = 0f;
            break;
        }
        break;
    }
  }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章