UnityRTS实现相机移动缩放功能
所谓RTS就是即时战略游戏(Real-TimeStrategyGame)。
话不多说直接看一下demo:
相机的层级关系(移动的操作是对父物体进行操作,而缩放是对子物体主相机的操作):
以此场景为例,自己设置的一些参数,主要是移动速度,边界、缩放限制等。
代码如下(挂载到相机的父物体上)。有两种鼠标的控制方式,一种是边界检测,一种是鼠标拖动。这个代码是完整版的,也就是键盘也可以控制相机移动缩放的,如果只需要鼠标控制的,请往下看:
usingUnityEngine; ////// ///*Writer:June ///* ///*Data:2021.3.9 ///* ///*Function:RTS模式的相机移动 ///* ///*Remarks: /// /// publicclassCameraMoveControl:MonoBehaviour { #region移动 //////移动速度 /// privatefloatpanSpeed; //////正常速度 /// [SerializeField]privatefloatnormalSpeed; //////按shift加速 /// [SerializeField]privatefloatspeedUp; //////缓冲时间 /// [SerializeField]privatefloatmoveTime; privateVector3newPos; //////边界限制 /// [SerializeField]privatefloatxLimMin,xLimMax; //////这里的Y是指屏幕上下平移的限制 /// [SerializeField]privatefloatyLimMin,yLimMax; //-----------------------------------------------鼠标拖动操作相关字段---------------------------------------------------- privateCameramainCamrea; privateVector3startPoint,currentPoint; #endregion #region缩放 //////主摄像机的位置组件 /// privateTransformmainCamreaTF; //////缩放向量 ///tips:相机的放大缩小改变的是相机自身坐标的yz值 /// [SerializeField]privateVector3zoomV3; /* *需要注意的是缩放限制: *x轴与y轴限制后的缩放比值要一致,不然会出现缩放不平滑的现象 * */ //////缩放最大最小值 /// [SerializeField]privateVector3zoomMin,zoomMax; privateVector3newMainCamreaPos; //////缩放时间 /// [SerializeField]privatefloatzoomTime; #endregion privatevoidStart() { //判断是否有子物体 mainCamreaTF=transform.childCount>0?transform.GetChild(0):null; if(mainCamreaTF)newMainCamreaPos=mainCamreaTF.localPosition; mainCamrea=Camera.main; } privatevoidUpdate() { //按左shift加速 panSpeed=Input.GetKey(KeyCode.LeftShift)?speedUp:normalSpeed; //移动 ControlCamreaMove(); //缩放 ControlCamreaZoom(); } //////控制相机缩放 /// privatevoidControlCamreaZoom() { if(mainCamreaTF) { if(Input.GetKey(KeyCode.R))newMainCamreaPos+=zoomV3*Time.deltaTime;//放大 if(Input.GetKey(KeyCode.F))newMainCamreaPos-=zoomV3*Time.deltaTime;//缩小 newMainCamreaPos+=Input.GetAxis("MouseScrollWheel")*zoomV3; ZoomLimit(refnewMainCamreaPos); //刷新最终位置 mainCamreaTF.localPosition=Vector3.Lerp(mainCamreaTF.localPosition,newMainCamreaPos,zoomTime*Time.deltaTime); } } //////控制相机移动 /// privatevoidControlCamreaMove() { Vector3movePos=transform.position; newPos.Set(Input.GetAxis("Horizontal"),0,Input.GetAxis("Vertical")); #region鼠标操作 #region方式1(鼠标到达边缘,检测后操作相机移动) //Vector2mousePos=Input.mousePosition; //鼠标在四个边缘检测 //if(mousePos.x>Screen.width*0.9f&&mousePos.x0)newPos.x=-1; //if(mousePos.y>Screen.height*0.9f&&mousePos.y 0)newPos.z=-1; movePos+=newPos.normalized*panSpeed*Time.deltaTime; #endregion #region方式2(鼠标右键拖动控制相机移动) //首先判断相机是否为空 if(mainCamrea) { //鼠标右键按下时记录起始位置 if(Input.GetMouseButtonDown(1)) { //新建的世界坐标系下的平面,用于检测射线 Planeplane=newPlane(Vector3.up,Vector3.zero); Rayray=mainCamrea.ScreenPointToRay(Input.mousePosition); floatdistance; if(plane.Raycast(ray,outdistance)) { //获取碰撞位置 startPoint=ray.GetPoint(distance); } } //鼠标右键一直按下时记录当前点位置 if(Input.GetMouseButton(1)) { Planeplane=newPlane(Vector3.up,Vector3.zero); Rayray=mainCamrea.ScreenPointToRay(Input.mousePosition); floatdistance; if(plane.Raycast(ray,outdistance)) { currentPoint=ray.GetPoint(distance); } movePos+=(startPoint-currentPoint); } } #endregion #endregion BoundaryLimit(refmovePos); transform.position=Vector3.Lerp(transform.position,movePos,moveTime); } /// ///边界限制 /// ///要限制的目标向量 privatevoidBoundaryLimit(refVector3_pos) { _pos.x=Mathf.Clamp(_pos.x,xLimMin,xLimMax); _pos.z=Mathf.Clamp(_pos.z,yLimMin,yLimMax); } /// ///缩放限制 /// ///要限制的目标向量 privatevoidZoomLimit(refVector3_v3) { _v3.y=Mathf.Clamp(_v3.y,zoomMin.y,zoomMax.y); _v3.z=Mathf.Clamp(_v3.z,zoomMin.z,zoomMax.z); } }
这个代码是后来我觉得其实没必要用键盘来操控相机,根据我玩过的一些类似游戏,比较多都是鼠标操作的,所以删了键盘操作的部分:
usingUnityEngine; ////// ///*Writer:June ///* ///*Data:2021.3.9 ///* ///*Function:RTS模式的相机移动 ///* ///*Remarks: /// /// publicclassCameraMoveControl:MonoBehaviour { #region移动 //////移动速度 /// privatefloatpanSpeed; //////正常速度 /// [SerializeField]privatefloatnormalSpeed; //////按shift加速 /// [SerializeField]privatefloatspeedUp; //////缓冲时间 /// [SerializeField]privatefloatmoveTime; privateVector3newPos; //////边界限制 /// [SerializeField]privatefloatxLimMin,xLimMax; //////这里的Y是指屏幕上下平移的限制 /// [SerializeField]privatefloatyLimMin,yLimMax; //-----------------------------------------------鼠标拖动操作相关字段---------------------------------------------------- privateCameramainCamrea; privateVector3startPoint,currentPoint; #endregion #region缩放 //////主摄像机的位置组件 /// privateTransformmainCamreaTF; //////缩放向量 ///tips:相机的放大缩小改变的是相机自身坐标的yz值 /// [SerializeField]privateVector3zoomV3; /* *需要注意的是缩放限制: *x轴与y轴限制后的缩放比值要一致,不然会出现缩放不平滑的现象 * */ //////缩放最大最小值 /// [SerializeField]privateVector3zoomMin,zoomMax; privateVector3newMainCamreaPos; //////缩放时间 /// [SerializeField]privatefloatzoomTime; #endregion privatevoidStart() { //判断是否有子物体 mainCamreaTF=transform.childCount>0?transform.GetChild(0):null; if(mainCamreaTF)newMainCamreaPos=mainCamreaTF.localPosition; mainCamrea=Camera.main; } privatevoidUpdate() { //按左shift加速 panSpeed=Input.GetKey(KeyCode.LeftShift)?speedUp:normalSpeed; //移动 ControlCamreaMove(); //缩放 ControlCamreaZoom(); } //////控制相机缩放 /// privatevoidControlCamreaZoom() { if(mainCamreaTF) { newMainCamreaPos+=Input.GetAxis("MouseScrollWheel")*zoomV3; ZoomLimit(refnewMainCamreaPos); //刷新最终位置 mainCamreaTF.localPosition=Vector3.Lerp(mainCamreaTF.localPosition,newMainCamreaPos,zoomTime*Time.deltaTime); } } //////控制相机移动 /// privatevoidControlCamreaMove() { Vector3movePos=transform.position; newPos=Vector3.zero; #region鼠标操作 #region方式1(鼠标到达边缘,检测后操作相机移动) Vector2mousePos=Input.mousePosition; //鼠标在四个边缘检测 if(mousePos.x>Screen.width*0.9f&&mousePos.x0)newPos.x=-1; if(mousePos.y>Screen.height*0.9f&&mousePos.y 0)newPos.z=-1; movePos+=newPos.normalized*panSpeed*Time.deltaTime; #endregion #region方式2(鼠标右键拖动控制相机移动) //首先判断相机是否为空 if(mainCamrea) { //鼠标右键按下时记录起始位置 if(Input.GetMouseButtonDown(1)) { //新建的世界坐标系下的平面,用于检测射线 Planeplane=newPlane(Vector3.up,Vector3.zero); Rayray=mainCamrea.ScreenPointToRay(Input.mousePosition); floatdistance; if(plane.Raycast(ray,outdistance)) { //获取碰撞位置 startPoint=ray.GetPoint(distance); } } //鼠标右键一直按下时记录当前点位置 if(Input.GetMouseButton(1)) { Planeplane=newPlane(Vector3.up,Vector3.zero); Rayray=mainCamrea.ScreenPointToRay(Input.mousePosition); floatdistance; if(plane.Raycast(ray,outdistance)) { currentPoint=ray.GetPoint(distance); } movePos+=(startPoint-currentPoint); } } #endregion #endregion BoundaryLimit(refmovePos); transform.position=Vector3.Lerp(transform.position,movePos,moveTime); } /// ///边界限制 /// ///要限制的目标向量 privatevoidBoundaryLimit(refVector3_pos) { _pos.x=Mathf.Clamp(_pos.x,xLimMin,xLimMax); _pos.z=Mathf.Clamp(_pos.z,yLimMin,yLimMax); } /// ///缩放限制 /// ///要限制的目标向量 privatevoidZoomLimit(refVector3_v3) { _v3.y=Mathf.Clamp(_v3.y,zoomMin.y,zoomMax.y); _v3.z=Mathf.Clamp(_v3.z,zoomMin.z,zoomMax.z); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。