您好,登錄后才能下訂單哦!
本篇文章為大家展示了使用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怎么實現一個相機移動縮放功能,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。