【问题标题】:How to move camera in x-z axis only RTS touch for mobile?如何仅在 x-z 轴上移动相机 RTS touch for mobile?
【发布时间】:2016-04-04 05:59:14
【问题描述】:

我正在开发基于 RTS 的移动游戏。我想像“部落冲突”一样控制相机,我在 youtube 上找到了 Savalish 的教程和脚本。但那是针对 2D 游戏的。我想要 3D 的结果,所以我修改了它。一切工作正常,除了相机向上移动,即 y 轴。我不想要那个。并且还需要边界来限制相机进一步移动。下面是我使用的代码:

using UnityEngine;
 using System.Collections;



    public class TouchCameraControl : MonoBehaviour 
     {

    public float moveSensitivityX = 1.0f;
         public float moveSensitivityY = 1.0f;
         public bool updateZoomSensitivity = true;
         public float orthoZoomSpeed = 0.05f;
         public float minZoom = 1.0f;
         public float maxZoom = 20.0f;
         public bool invertMoveX = false;
         public bool invertMoveY = false;
         public float mapWidth = 60.0f;
         public float mapHeight = 40.0f;

         public float inertiaDuration = 1.0f;

         private Camera _camera;

         private float minX, maxX, minY, maxY;
         private float horizontalExtent, verticalExtent;

         private float scrollVelocity = 0.0f;
         private float timeTouchPhaseEnded;
         private Vector3 scrollDirection = Vector3.zero;

         void Start () 
         {
             _camera = Camera.main;

             maxZoom = 0.5f * (mapWidth / _camera.aspect);

             if (mapWidth > mapHeight)
                 maxZoom = 0.5f * mapHeight;

             if (_camera.fieldOfView > maxZoom)
                 _camera.fieldOfView = maxZoom;

             CalculateLevelBounds ();
         }

         void Update () 
         {
             if (updateZoomSensitivity)
             {
                 moveSensitivityX = _camera.fieldOfView / 5.0f;
                 moveSensitivityY = _camera.fieldOfView / 5.0f;
             }

             Touch[] touches = Input.touches;

             if (touches.Length < 1)
             {
                 //if the camera is currently scrolling
                 if (scrollVelocity != 0.0f)
                 {
                     //slow down over time
                     float t = (Time.time - timeTouchPhaseEnded) / inertiaDuration;
                     float frameVelocity = Mathf.Lerp (scrollVelocity, 0.0f, t);
                     _camera.transform.position += -(Vector3)scrollDirection.normalized * (frameVelocity * 0.05f) * Time.deltaTime;

                     if (t >= 1.0f)
                         scrollVelocity = 0.0f;
                 }
             }

             if (touches.Length > 0)
             {
                 //Single touch (move)
                 if (touches.Length == 1)
                 {
                     if (touches[0].phase == TouchPhase.Began)
                     {
                         scrollVelocity = 0.0f;
                     }
                     else if (touches[0].phase == TouchPhase.Moved)
                     {
                         Vector3 delta = touches[0].deltaPosition;

                         float positionX = delta.x * moveSensitivityX * Time.deltaTime;
                         positionX = invertMoveX ? positionX : positionX * -1;

                         float positionY = delta.y * moveSensitivityY * Time.deltaTime;
                         positionY = invertMoveY ? positionY : positionY * -1;

                         _camera.transform.position += new Vector3 (positionX, 0, positionY);
                         //_camera.transform.position += transform.TransformDirection((Vector2)((new Vector2 (positionX, positionY-positionX))));
                         scrollDirection = touches[0].deltaPosition.normalized;
                         scrollVelocity = touches[0].deltaPosition.magnitude / touches[0].deltaTime;


                         if (scrollVelocity <= 100)
                             scrollVelocity = 0;
                     }
                     else if (touches[0].phase == TouchPhase.Ended)
                     {
                         timeTouchPhaseEnded = Time.time;
                     }
                 }


                 //Double touch (zoom)
                 if (touches.Length == 2)
                 {
                     Debug.Log ("Double Touch");
                     Vector2 cameraViewsize = new Vector2 (_camera.pixelWidth, _camera.pixelHeight);

                     Touch touchOne = touches[0];
                     Touch touchTwo = touches[1];

                     Vector2 touchOnePrevPos = touchOne.position - touchOne.deltaPosition;
                     Vector2 touchTwoPrevPos = touchTwo.position - touchTwo.deltaPosition;

                     float prevTouchDeltaMag = (touchOnePrevPos - touchTwoPrevPos).magnitude;
                     float touchDeltaMag = (touchOne.position - touchTwo.position).magnitude;

                     float deltaMagDiff = prevTouchDeltaMag - touchDeltaMag;

                     _camera.transform.position += _camera.transform.TransformDirection ((touchOnePrevPos + touchTwoPrevPos - cameraViewsize) * _camera.fieldOfView / cameraViewsize.y);

                     _camera.fieldOfView += deltaMagDiff * orthoZoomSpeed;
                     _camera.fieldOfView = Mathf.Clamp (_camera.fieldOfView, minZoom, maxZoom) - 0.001f;

                     _camera.transform.position -= _camera.transform.TransformDirection ((touchOne.position + touchTwo.position - cameraViewsize) * _camera.fieldOfView / cameraViewsize.y);

                     CalculateLevelBounds ();
                 }
             }
         }

         void CalculateLevelBounds ()
         {
             verticalExtent = _camera.fieldOfView;
             horizontalExtent = _camera.fieldOfView * Screen.width / Screen.height;
             minX = horizontalExtent - mapWidth / 2.0f;
             maxX = mapWidth / 2.0f - horizontalExtent;
             minY = verticalExtent - mapHeight / 2.0f;
             maxY = mapHeight / 2.0f - verticalExtent;
         }

         void LateUpdate ()
         {
             //Vector3 limitedCameraPosition = _camera.transform.position;
             //limitedCameraPosition.x = Mathf.Clamp (limitedCameraPosition.x, minX, maxX);
             //limitedCameraPosition.y = Mathf.Clamp (limitedCameraPosition.y, minY, maxY);
             //_camera.transform.position = limitedCameraPosition;
         }

         void OnDrawGizmos ()
         {
             //Gizmos.DrawWireCube (Vector3.zero, new Vector3 (mapWidth, mapHeight, 0));
         }
     }

请告诉我代码有什么问题。任何帮助将不胜感激。

谢谢。

【问题讨论】:

    标签: ios unity3d camera unity5 perspectivecamera


    【解决方案1】:
    • 将相机设置为 (90,0,0)。

    • 换行

    _camera.transform.position += new Vector3 (positionX, 0, positionY);

    //For perspective Camera
        _camera.transform.position += new Vector3 (positionX+positionY, 0, positionY-positionX);
    
    //For orthographic Camera
    _camera.transform.position += new Vector3 (positionX, 0, positionY);
    

    它现在应该可以工作了。我在一个空项目上进行了测试。

    【讨论】:

      【解决方案2】:

      在 Start() 函数中获取并存储相机的原始 Y 轴值,然后在每次修改相机位置的任何代码之前使用它来修改相机的 y 轴,例如:

      _camera.transform.position=-=+=

      创建变量以存储相机 Y 位置

      float yCamPos;
      

      Start()函数中初始化yCamPos

      yCamPos = _camera.transform.position.y;
      

      覆盖相机 Y 轴

      1. 将_camera.transform.position += new Vector3(positionX, 0, positionY);Update() 函数中更改为

      _camera.transform.position += new Vector3(positionX, yCamPos, positionY);
      

      2.更改_camera.transform.position += _camera.transform.TransformDirection((touchOnePrevPos + touchTwoPrevPos - cameraViewsize) * _camera.fieldOfView / cameraViewsize.y);

      Vector3 tempVector1 = (touchOnePrevPos + touchTwoPrevPos - cameraViewsize) * _camera.fieldOfView / cameraViewsize.y;
      tempVector1.y = yCamPos; //Overwrite the y axis
      _camera.transform.position +=_camera.transform.TransformDirection(tempVector1);
      

      3.更改_camera.transform.position -= _camera.transform.TransformDirection((touchOne.position + touchTwo.position - cameraViewsize) * _camera.fieldOfView / cameraViewsize.y);

      Vector3 tempVector2 = (touchOne.position + touchTwo.position - cameraViewsize) * _camera.fieldOfView / cameraViewsize.y;
      tempVector2.y = yCamPos; //Overwrite the y axis
      _camera.transform.position -= _camera.transform.TransformDirection(tempVector2);
      

      覆盖滚动方向 Y 轴

      1.改变

      _camera.transform.position += -(Vector3)scrollDirection.normalized * (frameVelocity * 0.05f) * Time.deltaTime;
      

      Vector3 sDir1 = (Vector3)scrollDirection.normalized * (frameVelocity * 0.05f) * Time.deltaTime;
      sDir1.y = yCamPos;  //Overwrite the y axis
      _camera.transform.position += -sDir1;
      

      整个代码

      public class TouchCameraControl : MonoBehaviour
      {
      
          public float moveSensitivityX = 1.0f;
          public float moveSensitivityY = 1.0f;
          public bool updateZoomSensitivity = true;
          public float orthoZoomSpeed = 0.05f;
          public float minZoom = 1.0f;
          public float maxZoom = 20.0f;
          public bool invertMoveX = false;
          public bool invertMoveY = false;
          public float mapWidth = 60.0f;
          public float mapHeight = 40.0f;
      
          public float inertiaDuration = 1.0f;
      
          private Camera _camera;
      
          private float minX, maxX, minY, maxY;
          private float horizontalExtent, verticalExtent;
      
          private float scrollVelocity = 0.0f;
          private float timeTouchPhaseEnded;
          private Vector3 scrollDirection = Vector3.zero;
      
          //Get Original Camera Y Position
          float yCamPos = 0f;
      
          void Start()
          {
              _camera = Camera.main;
      
              //Init the yCamPos
              yCamPos = _camera.transform.position.y;
      
      
              maxZoom = 0.5f * (mapWidth / _camera.aspect);
      
              if (mapWidth > mapHeight)
                  maxZoom = 0.5f * mapHeight;
      
              if (_camera.fieldOfView > maxZoom)
                  _camera.fieldOfView = maxZoom;
      
              CalculateLevelBounds();
          }
      
          void Update()
          {
              if (updateZoomSensitivity)
              {
                  moveSensitivityX = _camera.fieldOfView / 5.0f;
                  moveSensitivityY = _camera.fieldOfView / 5.0f;
              }
      
              Touch[] touches = Input.touches;
      
              if (touches.Length < 1)
              {
                  //if the camera is currently scrolling
                  if (scrollVelocity != 0.0f)
                  {
                      //slow down over time
                      float t = (Time.time - timeTouchPhaseEnded) / inertiaDuration;
                      float frameVelocity = Mathf.Lerp(scrollVelocity, 0.0f, t);
      
                      Vector3 sDir1 = (Vector3)scrollDirection.normalized * (frameVelocity * 0.05f) * Time.deltaTime;
                      sDir1.y = yCamPos;  //Overwrite the y axis
                      _camera.transform.position += -sDir1;
      
                      if (t >= 1.0f)
                          scrollVelocity = 0.0f;
                  }
              }
      
              if (touches.Length > 0)
              {
                  //Single touch (move)
                  if (touches.Length == 1)
                  {
                      if (touches[0].phase == TouchPhase.Began)
                      {
                          scrollVelocity = 0.0f;
                      }
                      else if (touches[0].phase == TouchPhase.Moved)
                      {
                          Vector3 delta = touches[0].deltaPosition;
      
                          float positionX = delta.x * moveSensitivityX * Time.deltaTime;
                          positionX = invertMoveX ? positionX : positionX * -1;
      
                          float positionY = delta.y * moveSensitivityY * Time.deltaTime;
                          positionY = invertMoveY ? positionY : positionY * -1;
      
                          //Overwrite the y axis
                          _camera.transform.position += new Vector3(positionX, yCamPos, positionY);
      
      
                          //_camera.transform.position += transform.TransformDirection((Vector2)((new Vector2 (positionX, positionY-positionX))));
                          scrollDirection = touches[0].deltaPosition.normalized;
                          scrollVelocity = touches[0].deltaPosition.magnitude / touches[0].deltaTime;
      
      
                          if (scrollVelocity <= 100)
                              scrollVelocity = 0;
                      }
                      else if (touches[0].phase == TouchPhase.Ended)
                      {
                          timeTouchPhaseEnded = Time.time;
                      }
                  }
      
      
                  //Double touch (zoom)
                  if (touches.Length == 2)
                  {
                      Debug.Log("Double Touch");
                      Vector2 cameraViewsize = new Vector2(_camera.pixelWidth, _camera.pixelHeight);
      
                      Touch touchOne = touches[0];
                      Touch touchTwo = touches[1];
      
                      Vector2 touchOnePrevPos = touchOne.position - touchOne.deltaPosition;
                      Vector2 touchTwoPrevPos = touchTwo.position - touchTwo.deltaPosition;
      
                      float prevTouchDeltaMag = (touchOnePrevPos - touchTwoPrevPos).magnitude;
                      float touchDeltaMag = (touchOne.position - touchTwo.position).magnitude;
      
                      float deltaMagDiff = prevTouchDeltaMag - touchDeltaMag;
      
                      Vector3 tempVector1 = (touchOnePrevPos + touchTwoPrevPos - cameraViewsize) * _camera.fieldOfView / cameraViewsize.y;
                      tempVector1.y = yCamPos; //Overwrite the y axis
                      _camera.transform.position += _camera.transform.TransformDirection(tempVector1);
      
                      _camera.fieldOfView += deltaMagDiff * orthoZoomSpeed;
                      _camera.fieldOfView = Mathf.Clamp(_camera.fieldOfView, minZoom, maxZoom) - 0.001f;
      
                      Vector3 tempVector2 = (touchOne.position + touchTwo.position - cameraViewsize) * _camera.fieldOfView / cameraViewsize.y;
                      tempVector2.y = yCamPos; //Overwrite the y axis
                      _camera.transform.position -= _camera.transform.TransformDirection(tempVector2);
      
                      CalculateLevelBounds();
                  }
              }
          }
      
          void CalculateLevelBounds()
          {
              verticalExtent = _camera.fieldOfView;
              horizontalExtent = _camera.fieldOfView * Screen.width / Screen.height;
              minX = horizontalExtent - mapWidth / 2.0f;
              maxX = mapWidth / 2.0f - horizontalExtent;
              minY = verticalExtent - mapHeight / 2.0f;
              maxY = mapHeight / 2.0f - verticalExtent;
          }
      
          void LateUpdate()
          {
              //Vector3 limitedCameraPosition = _camera.transform.position;
              //limitedCameraPosition.x = Mathf.Clamp (limitedCameraPosition.x, minX, maxX);
              //limitedCameraPosition.y = Mathf.Clamp (limitedCameraPosition.y, minY, maxY);
              //_camera.transform.position = limitedCameraPosition;
          }
      
          void OnDrawGizmos()
          {
              //Gizmos.DrawWireCube (Vector3.zero, new Vector3 (mapWidth, mapHeight, 0));
          }
      }
      

      代码没有经过测试,因为我没有图形文件,但它应该可以工作....

      【讨论】:

      • 非常感谢您的帮助。我理解你解释的逻辑。解释很有帮助。但不知何故它不起作用。当我滚动移动时,Y 轴增加太多。
      猜你喜欢
      • 1970-01-01
      • 2015-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多