最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

UnityRTS實(shí)現(xiàn)相機(jī)移動(dòng)縮放功能

 更新時(shí)間:2021年03月12日 06:59:32   作者:小小小小羽丶  
這篇文章主要為大家詳細(xì)介紹了UnityRTS實(shí)現(xiàn)相機(jī)的移動(dòng)縮放功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

所謂RTS就是即時(shí)戰(zhàn)略游戲(Real-Time Strategy Game)。

話不多說直接看一下demo:

相機(jī)的層級(jí)關(guān)系(移動(dòng)的操作是對(duì)父物體進(jìn)行操作,而縮放是對(duì)子物體主相機(jī)的操作):

以此場(chǎng)景為例,自己設(shè)置的一些參數(shù),主要是移動(dòng)速度,邊界、縮放限制等。

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

using UnityEngine;
 
/// <summary>
/// 
/// * Writer:June
/// *
/// * Data:2021.3.9
/// *
/// * Function:RTS模式的相機(jī)移動(dòng)
/// *
/// * Remarks:
/// 
/// </summary>
 
public class CameraMoveControl : MonoBehaviour
{
  #region 移動(dòng)
  /// <summary>
  /// 移動(dòng)速度
  /// </summary>
  private float panSpeed;
  /// <summary>
  /// 正常速度
  /// </summary>
  [SerializeField] private float normalSpeed;
  /// <summary>
  /// 按shift加速
  /// </summary>
  [SerializeField] private float speedUp;
  /// <summary>
  /// 緩沖時(shí)間
  /// </summary>
  [SerializeField] private float moveTime;
  private Vector3 newPos;
  /// <summary>
  /// 邊界限制
  /// </summary>
  [SerializeField] private float xLimMin, xLimMax;
  /// <summary>
  /// 這里的Y是指屏幕上下平移的限制
  /// </summary>
  [SerializeField] private float yLimMin, yLimMax;
  //-----------------------------------------------鼠標(biāo)拖動(dòng)操作相關(guān)字段----------------------------------------------------
  private Camera mainCamrea;
  private Vector3 startPoint, currentPoint;
  #endregion
 
  #region 縮放
  /// <summary>
  /// 主攝像機(jī)的位置組件
  /// </summary>
  private Transform mainCamreaTF;
  /// <summary>
  /// 縮放向量
  /// tips:相機(jī)的放大縮小改變的是相機(jī)自身坐標(biāo)的yz值
  /// </summary>
  [SerializeField] private Vector3 zoomV3;
  /*
   * 需要注意的是縮放限制:
   * x軸與y軸限制后的縮放比值要一致,不然會(huì)出現(xiàn)縮放不平滑的現(xiàn)象
   * 
   */
  /// <summary>
  /// 縮放最大最小值
  /// </summary>
  [SerializeField] private Vector3 zoomMin, zoomMax;
  private Vector3 newMainCamreaPos;
  /// <summary>
  /// 縮放時(shí)間
  /// </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;
    //移動(dòng)
    ControlCamreaMove();
    //縮放
    ControlCamreaZoom();
  }
 
  /// <summary>
  /// 控制相機(jī)縮放
  /// </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>
  /// 控制相機(jī)移動(dòng)
  /// </summary>
  private void ControlCamreaMove()
  {
    Vector3 movePos = transform.position;
    newPos.Set(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
 
    #region 鼠標(biāo)操作
    #region 方式1(鼠標(biāo)到達(dá)邊緣,檢測(cè)后操作相機(jī)移動(dòng))
    //Vector2 mousePos = Input.mousePosition;
    //鼠標(biāo)在四個(gè)邊緣檢測(cè)
    //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(鼠標(biāo)右鍵拖動(dòng)控制相機(jī)移動(dòng))
    //首先判斷相機(jī)是否為空
    if (mainCamrea)
    {
      //鼠標(biāo)右鍵按下時(shí)記錄起始位置
      if (Input.GetMouseButtonDown(1))
      {
        //新建的世界坐標(biāo)系下的平面,用于檢測(cè)射線
        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);
        }
      }
      //鼠標(biāo)右鍵一直按下時(shí)記錄當(dāng)前點(diǎn)位置
      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">要限制的目標(biāo)向量</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">要限制的目標(biāo)向量</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);
  }
}

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

using UnityEngine;
 
/// <summary>
/// 
/// * Writer:June
/// *
/// * Data:2021.3.9
/// *
/// * Function:RTS模式的相機(jī)移動(dòng)
/// *
/// * Remarks:
/// 
/// </summary>
 
public class CameraMoveControl : MonoBehaviour
{
  #region 移動(dòng)
  /// <summary>
  /// 移動(dòng)速度
  /// </summary>
  private float panSpeed;
  /// <summary>
  /// 正常速度
  /// </summary>
  [SerializeField] private float normalSpeed;
  /// <summary>
  /// 按shift加速
  /// </summary>
  [SerializeField] private float speedUp;
  /// <summary>
  /// 緩沖時(shí)間
  /// </summary>
  [SerializeField] private float moveTime;
  private Vector3 newPos;
  /// <summary>
  /// 邊界限制
  /// </summary>
  [SerializeField] private float xLimMin, xLimMax;
  /// <summary>
  /// 這里的Y是指屏幕上下平移的限制
  /// </summary>
  [SerializeField] private float yLimMin, yLimMax;
  //-----------------------------------------------鼠標(biāo)拖動(dòng)操作相關(guān)字段----------------------------------------------------
  private Camera mainCamrea;
  private Vector3 startPoint, currentPoint;
  #endregion
 
  #region 縮放
  /// <summary>
  /// 主攝像機(jī)的位置組件
  /// </summary>
  private Transform mainCamreaTF;
  /// <summary>
  /// 縮放向量
  /// tips:相機(jī)的放大縮小改變的是相機(jī)自身坐標(biāo)的yz值
  /// </summary>
  [SerializeField] private Vector3 zoomV3;
  /*
   * 需要注意的是縮放限制:
   * x軸與y軸限制后的縮放比值要一致,不然會(huì)出現(xiàn)縮放不平滑的現(xiàn)象
   * 
   */
  /// <summary>
  /// 縮放最大最小值
  /// </summary>
  [SerializeField] private Vector3 zoomMin, zoomMax;
  private Vector3 newMainCamreaPos;
  /// <summary>
  /// 縮放時(shí)間
  /// </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;
    //移動(dòng)
    ControlCamreaMove();
    //縮放
    ControlCamreaZoom();
  }
 
  /// <summary>
  /// 控制相機(jī)縮放
  /// </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>
  /// 控制相機(jī)移動(dòng)
  /// </summary>
  private void ControlCamreaMove()
  {
    Vector3 movePos = transform.position;
    newPos = Vector3.zero;
    #region 鼠標(biāo)操作
    #region 方式1(鼠標(biāo)到達(dá)邊緣,檢測(cè)后操作相機(jī)移動(dòng))
    Vector2 mousePos = Input.mousePosition;
    //鼠標(biāo)在四個(gè)邊緣檢測(cè)
    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(鼠標(biāo)右鍵拖動(dòng)控制相機(jī)移動(dòng))
    //首先判斷相機(jī)是否為空
    if (mainCamrea)
    {
      //鼠標(biāo)右鍵按下時(shí)記錄起始位置
      if (Input.GetMouseButtonDown(1))
      {
        //新建的世界坐標(biāo)系下的平面,用于檢測(cè)射線
        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);
        }
      }
      //鼠標(biāo)右鍵一直按下時(shí)記錄當(dāng)前點(diǎn)位置
      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">要限制的目標(biāo)向量</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">要限制的目標(biāo)向量</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);
  }
}

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 探討:關(guān)閉瀏覽器后,php腳本會(huì)不會(huì)繼續(xù)運(yùn)行

    探討:關(guān)閉瀏覽器后,php腳本會(huì)不會(huì)繼續(xù)運(yùn)行

    本篇文章是對(duì)關(guān)閉瀏覽器后,php腳本會(huì)不會(huì)繼續(xù)運(yùn)行進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • C#列表框、復(fù)選列表框、組合框的用法實(shí)例

    C#列表框、復(fù)選列表框、組合框的用法實(shí)例

    這篇文章主要介紹了C#列表框、復(fù)選列表框、組合框的用法,實(shí)例分析了在一個(gè)簡單存儲(chǔ)項(xiàng)目中列表框、復(fù)選列表框、組合框的使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-01-01
  • 分享WCF聊天程序--WCFChat實(shí)現(xiàn)代碼

    分享WCF聊天程序--WCFChat實(shí)現(xiàn)代碼

    無意中在一個(gè)國外的站點(diǎn)下到了一個(gè)利用WCF實(shí)現(xiàn)聊天的程序,作者是:Nikola Paljetak。研究了一下,自己做了測(cè)試和部分修改,感覺還不錯(cuò),分享給大家
    2015-11-11
  • C#中分部方法和分部類分析

    C#中分部方法和分部類分析

    這篇文章主要介紹了C#中分部方法和分部類基本用法,并且較為詳細(xì)的分析了分部方法和分部類使用時(shí)的注意事項(xiàng),需要的朋友可以參考下
    2014-11-11
  • C#統(tǒng)計(jì)C、C++及C#程序代碼行數(shù)的方法

    C#統(tǒng)計(jì)C、C++及C#程序代碼行數(shù)的方法

    這篇文章主要介紹了C#統(tǒng)計(jì)C、C++及C#程序代碼行數(shù)的方法,較為詳細(xì)的分析了C#統(tǒng)計(jì)文本文件的原理與相關(guān)實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-08-08
  • C#實(shí)現(xiàn)手機(jī)拍照并且保存水印照片

    C#實(shí)現(xiàn)手機(jī)拍照并且保存水印照片

    這篇文章主要介紹了C#實(shí)現(xiàn)手機(jī)拍照并且保存水印照片的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-11-11
  • c#日志記錄幫助類分享

    c#日志記錄幫助類分享

    這篇文章主要介紹了c#日志記錄幫助類,可以設(shè)置記錄的日志類型,需要的朋友可以參考下
    2014-03-03
  • c#二維碼生成的代碼分享

    c#二維碼生成的代碼分享

    c#生成二維碼實(shí)現(xiàn)示例代碼分享,生成方法是調(diào)用外網(wǎng)API,為了不直接調(diào)用別人的接口,創(chuàng)建一個(gè)QrImg.aspx用于顯示二維碼,傳參數(shù)即可
    2013-12-12
  • 使用C#編寫一個(gè)Web服務(wù)器

    使用C#編寫一個(gè)Web服務(wù)器

    在.NET世界中,C#是一種功能強(qiáng)大的編程語言,常被用于構(gòu)建各種類型的應(yīng)用程序,本文主要為大家介紹了如何使用C#編寫一個(gè)簡單的Web服務(wù)器,需要的可以參考下
    2024-03-03
  • C#使用AutoMapper進(jìn)行對(duì)象映射的示例代碼

    C#使用AutoMapper進(jìn)行對(duì)象映射的示例代碼

    AutoMapper 是一個(gè)對(duì)象到對(duì)象映射的庫,可以簡化 DTO (Data Transfer Objects) 和實(shí)體類之間的轉(zhuǎn)換,在大型應(yīng)用程序中,通常需要將業(yè)務(wù)實(shí)體映射到視圖模型或 DTO 中,本文將詳細(xì)介紹如何在 C# 項(xiàng)目中使用 AutoMapper,包括安裝、配置、以及示例代碼
    2024-08-08

最新評(píng)論

鹤山市| 郑州市| 德惠市| 清水河县| 治县。| 宁明县| 梁山县| 松阳县| 津市市| 民丰县| 原阳县| 原阳县| 富蕴县| 都江堰市| 阜康市| 古田县| 苗栗县| 广宁县| 长春市| 黎川县| 清镇市| 杭锦旗| 兖州市| 罗甸县| 越西县| 门源| 永清县| 陵川县| 涿鹿县| 西吉县| 南宫市| 会理县| 临潭县| 陇南市| 都匀市| 泸溪县| 南木林县| 山丹县| 巴南区| 顺昌县| 台北县|