中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

使用UnityRTS怎么實現一個相機移動縮放功能

發布時間:2021-03-12 17:11:16 來源:億速云 閱讀:488 作者:Leah 欄目:開發技術

本篇文章為大家展示了使用UnityRTS怎么實現一個相機移動縮放功能,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

相機的層級關系(移動的操作是對父物體進行操作,而縮放是對子物體主相機的操作):

使用UnityRTS怎么實現一個相機移動縮放功能

以此場景為例,自己設置的一些參數,主要是移動速度,邊界、縮放限制等。

使用UnityRTS怎么實現一個相機移動縮放功能

代碼如下(掛載到相機的父物體上)。有兩種鼠標的控制方式,一種是邊界檢測,一種是鼠標拖動。這個代碼是完整版的,也就是鍵盤也可以控制相機移動縮放的,如果只需要鼠標控制的,請往下看:

using UnityEngine;
 
/// <summary>
/// 
/// * Writer:June
/// *
/// * Data:2021.3.9
/// *
/// * Function:RTS模式的相機移動
/// *
/// * Remarks:
/// 
/// </summary>
 
public class CameraMoveControl : MonoBehaviour
{
  #region 移動
  /// <summary>
  /// 移動速度
  /// </summary>
  private float panSpeed;
  /// <summary>
  /// 正常速度
  /// </summary>
  [SerializeField] private float normalSpeed;
  /// <summary>
  /// 按shift加速
  /// </summary>
  [SerializeField] private float speedUp;
  /// <summary>
  /// 緩沖時間
  /// </summary>
  [SerializeField] private float moveTime;
  private Vector3 newPos;
  /// <summary>
  /// 邊界限制
  /// </summary>
  [SerializeField] private float xLimMin, xLimMax;
  /// <summary>
  /// 這里的Y是指屏幕上下平移的限制
  /// </summary>
  [SerializeField] private float yLimMin, yLimMax;
  //-----------------------------------------------鼠標拖動操作相關字段----------------------------------------------------
  private Camera mainCamrea;
  private Vector3 startPoint, currentPoint;
  #endregion
 
  #region 縮放
  /// <summary>
  /// 主攝像機的位置組件
  /// </summary>
  private Transform mainCamreaTF;
  /// <summary>
  /// 縮放向量
  /// tips:相機的放大縮小改變的是相機自身坐標的yz值
  /// </summary>
  [SerializeField] private Vector3 zoomV3;
  /*
   * 需要注意的是縮放限制:
   * x軸與y軸限制后的縮放比值要一致,不然會出現縮放不平滑的現象
   * 
   */
  /// <summary>
  /// 縮放最大最小值
  /// </summary>
  [SerializeField] private Vector3 zoomMin, zoomMax;
  private Vector3 newMainCamreaPos;
  /// <summary>
  /// 縮放時間
  /// </summary>
  [SerializeField] private float zoomTime;
  #endregion
 
  private void Start()
  {
    //判斷是否有子物體
    mainCamreaTF = transform.childCount > 0 ? transform.GetChild(0) : null;
    if (mainCamreaTF) newMainCamreaPos = mainCamreaTF.localPosition;
    mainCamrea = Camera.main;
  }
 
 
  private void Update()
  {
    //按左shift加速
    panSpeed = Input.GetKey(KeyCode.LeftShift) ? speedUp : normalSpeed;
    //移動
    ControlCamreaMove();
    //縮放
    ControlCamreaZoom();
  }
 
  /// <summary>
  /// 控制相機縮放
  /// </summary>
  private void ControlCamreaZoom()
  {
    if (mainCamreaTF)
    {
      if (Input.GetKey(KeyCode.R)) newMainCamreaPos += zoomV3 * Time.deltaTime;//放大
      if (Input.GetKey(KeyCode.F)) newMainCamreaPos -= zoomV3 * Time.deltaTime;//縮小
      newMainCamreaPos += Input.GetAxis("Mouse ScrollWheel") * zoomV3;
      ZoomLimit(ref newMainCamreaPos);
      //刷新最終位置
      mainCamreaTF.localPosition = Vector3.Lerp(mainCamreaTF.localPosition, newMainCamreaPos, zoomTime * Time.deltaTime);
    }
  }
 
 
  /// <summary>
  /// 控制相機移動
  /// </summary>
  private void ControlCamreaMove()
  {
    Vector3 movePos = transform.position;
    newPos.Set(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
 
    #region 鼠標操作
    #region 方式1(鼠標到達邊緣,檢測后操作相機移動)
    //Vector2 mousePos = Input.mousePosition;
    //鼠標在四個邊緣檢測
    //if (mousePos.x > Screen.width * 0.9f && mousePos.x < Screen.width) newPos.x = 1;
    //if (mousePos.x < Screen.width * 0.1f && mousePos.x > 0) newPos.x = -1;
    //if (mousePos.y > Screen.height * 0.9f && mousePos.y < Screen.height) newPos.z = 1;
    //if (mousePos.y < Screen.height * 0.1f && mousePos.y > 0) newPos.z = -1;
 
    movePos += newPos.normalized * panSpeed * Time.deltaTime;
    #endregion
 
    #region 方式2(鼠標右鍵拖動控制相機移動)
    //首先判斷相機是否為空
    if (mainCamrea)
    {
      //鼠標右鍵按下時記錄起始位置
      if (Input.GetMouseButtonDown(1))
      {
        //新建的世界坐標系下的平面,用于檢測射線
        Plane plane = new Plane(Vector3.up, Vector3.zero);
        Ray ray = mainCamrea.ScreenPointToRay(Input.mousePosition);
        float distance;
        if (plane.Raycast(ray, out distance)) 
        {
          //獲取碰撞位置
          startPoint = ray.GetPoint(distance);
        }
      }
      //鼠標右鍵一直按下時記錄當前點位置
      if (Input.GetMouseButton(1))
      {
        Plane plane = new Plane(Vector3.up, Vector3.zero);
        Ray ray = mainCamrea.ScreenPointToRay(Input.mousePosition);
        float distance;
        if (plane.Raycast(ray, out distance))
        {
          currentPoint = ray.GetPoint(distance);
        }
        movePos += (startPoint - currentPoint);
      }
    }
    #endregion
    #endregion
 
    BoundaryLimit(ref movePos);
    transform.position = Vector3.Lerp(transform.position, movePos, moveTime);
  }
 
 
  /// <summary>
  /// 邊界限制
  /// </summary>
  /// <param name="_pos">要限制的目標向量</param>
  private void BoundaryLimit(ref Vector3 _pos)
  {
    _pos.x = Mathf.Clamp(_pos.x, xLimMin, xLimMax);
    _pos.z = Mathf.Clamp(_pos.z, yLimMin, yLimMax);
  }
 
 
  /// <summary>
  /// 縮放限制
  /// </summary>
  /// <param name="_v3">要限制的目標向量</param>
  private void ZoomLimit(ref Vector3 _v3)
  {
    _v3.y = Mathf.Clamp(_v3.y, zoomMin.y, zoomMax.y);
    _v3.z = Mathf.Clamp(_v3.z, zoomMin.z, zoomMax.z);
  }
}

這個代碼是后來我覺得其實沒必要用鍵盤來操控相機,根據我玩過的一些類似游戲,比較多都是鼠標操作的,所以刪了鍵盤操作的部分:

using UnityEngine;
 
/// <summary>
/// 
/// * Writer:June
/// *
/// * Data:2021.3.9
/// *
/// * Function:RTS模式的相機移動
/// *
/// * Remarks:
/// 
/// </summary>
 
public class CameraMoveControl : MonoBehaviour
{
  #region 移動
  /// <summary>
  /// 移動速度
  /// </summary>
  private float panSpeed;
  /// <summary>
  /// 正常速度
  /// </summary>
  [SerializeField] private float normalSpeed;
  /// <summary>
  /// 按shift加速
  /// </summary>
  [SerializeField] private float speedUp;
  /// <summary>
  /// 緩沖時間
  /// </summary>
  [SerializeField] private float moveTime;
  private Vector3 newPos;
  /// <summary>
  /// 邊界限制
  /// </summary>
  [SerializeField] private float xLimMin, xLimMax;
  /// <summary>
  /// 這里的Y是指屏幕上下平移的限制
  /// </summary>
  [SerializeField] private float yLimMin, yLimMax;
  //-----------------------------------------------鼠標拖動操作相關字段----------------------------------------------------
  private Camera mainCamrea;
  private Vector3 startPoint, currentPoint;
  #endregion
 
  #region 縮放
  /// <summary>
  /// 主攝像機的位置組件
  /// </summary>
  private Transform mainCamreaTF;
  /// <summary>
  /// 縮放向量
  /// tips:相機的放大縮小改變的是相機自身坐標的yz值
  /// </summary>
  [SerializeField] private Vector3 zoomV3;
  /*
   * 需要注意的是縮放限制:
   * x軸與y軸限制后的縮放比值要一致,不然會出現縮放不平滑的現象
   * 
   */
  /// <summary>
  /// 縮放最大最小值
  /// </summary>
  [SerializeField] private Vector3 zoomMin, zoomMax;
  private Vector3 newMainCamreaPos;
  /// <summary>
  /// 縮放時間
  /// </summary>
  [SerializeField] private float zoomTime;
  #endregion
 
  private void Start()
  {
    //判斷是否有子物體
    mainCamreaTF = transform.childCount > 0 ? transform.GetChild(0) : null;
    if (mainCamreaTF) newMainCamreaPos = mainCamreaTF.localPosition;
    mainCamrea = Camera.main;
  }
 
 
  private void Update()
  {
    //按左shift加速
    panSpeed = Input.GetKey(KeyCode.LeftShift) ? speedUp : normalSpeed;
    //移動
    ControlCamreaMove();
    //縮放
    ControlCamreaZoom();
  }
 
  /// <summary>
  /// 控制相機縮放
  /// </summary>
  private void ControlCamreaZoom()
  {
    if (mainCamreaTF)
    {
      newMainCamreaPos += Input.GetAxis("Mouse ScrollWheel") * zoomV3;
      ZoomLimit(ref newMainCamreaPos);
      //刷新最終位置
      mainCamreaTF.localPosition = Vector3.Lerp(mainCamreaTF.localPosition, newMainCamreaPos, zoomTime * Time.deltaTime);
    }
  }
 
 
  /// <summary>
  /// 控制相機移動
  /// </summary>
  private void ControlCamreaMove()
  {
    Vector3 movePos = transform.position;
    newPos = Vector3.zero;
    #region 鼠標操作
    #region 方式1(鼠標到達邊緣,檢測后操作相機移動)
    Vector2 mousePos = Input.mousePosition;
    //鼠標在四個邊緣檢測
    if (mousePos.x > Screen.width * 0.9f && mousePos.x < Screen.width) newPos.x = 1;
    if (mousePos.x < Screen.width * 0.1f && mousePos.x > 0) newPos.x = -1;
    if (mousePos.y > Screen.height * 0.9f && mousePos.y < Screen.height) newPos.z = 1;
    if (mousePos.y < Screen.height * 0.1f && mousePos.y > 0) newPos.z = -1;
    movePos += newPos.normalized * panSpeed * Time.deltaTime;
    #endregion
 
    #region 方式2(鼠標右鍵拖動控制相機移動)
    //首先判斷相機是否為空
    if (mainCamrea)
    {
      //鼠標右鍵按下時記錄起始位置
      if (Input.GetMouseButtonDown(1))
      {
        //新建的世界坐標系下的平面,用于檢測射線
        Plane plane = new Plane(Vector3.up, Vector3.zero);
        Ray ray = mainCamrea.ScreenPointToRay(Input.mousePosition);
        float distance;
        if (plane.Raycast(ray, out distance))
        {
          //獲取碰撞位置
          startPoint = ray.GetPoint(distance);
        }
      }
      //鼠標右鍵一直按下時記錄當前點位置
      if (Input.GetMouseButton(1))
      {
        Plane plane = new Plane(Vector3.up, Vector3.zero);
        Ray ray = mainCamrea.ScreenPointToRay(Input.mousePosition);
        float distance;
        if (plane.Raycast(ray, out distance))
        {
          currentPoint = ray.GetPoint(distance);
        }
        movePos += (startPoint - currentPoint);
      }
    }
    #endregion
    #endregion
 
    BoundaryLimit(ref movePos);
    transform.position = Vector3.Lerp(transform.position, movePos, moveTime);
  }
 
 
  /// <summary>
  /// 邊界限制
  /// </summary>
  /// <param name="_pos">要限制的目標向量</param>
  private void BoundaryLimit(ref Vector3 _pos)
  {
    _pos.x = Mathf.Clamp(_pos.x, xLimMin, xLimMax);
    _pos.z = Mathf.Clamp(_pos.z, yLimMin, yLimMax);
  }
 
 
  /// <summary>
  /// 縮放限制
  /// </summary>
  /// <param name="_v3">要限制的目標向量</param>
  private void ZoomLimit(ref Vector3 _v3)
  {
    _v3.y = Mathf.Clamp(_v3.y, zoomMin.y, zoomMax.y);
    _v3.z = Mathf.Clamp(_v3.z, zoomMin.z, zoomMax.z);
  }
}

上述內容就是使用UnityRTS怎么實現一個相機移動縮放功能,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

藁城市| 图们市| 修水县| 望谟县| 革吉县| 上杭县| 普洱| 永春县| 金华市| 苏尼特左旗| 渭南市| 南靖县| 泸西县| 巴楚县| 普兰店市| 高邑县| 象山县| 寻乌县| 新宁县| 麻江县| 马龙县| 电白县| 大邑县| 定结县| 邛崃市| 桑植县| 莆田市| 甘南县| 体育| 海南省| 大埔县| 望奎县| 宿松县| 阿拉善右旗| 盐山县| 泸定县| 获嘉县| 广西| 莲花县| 昭苏县| 阿尔山市|