使用UnityRTS怎么实现一个相机移动缩放功能

本篇文章为大家展示了使用UnityRTS怎么实现一个相机移动缩放功能,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

相机的层级关系(移动的操作是对父物体进行操作,而缩放是对子物体主相机的操作):

使用UnityRTS怎么实现一个相机移动缩放功能

以此场景为例,自己设置的一些参数,主要是移动速度,边界、缩放限制等。

使用UnityRTS怎么实现一个相机移动缩放功能

代码如下(挂载到相机的父物体上)。有两种鼠标的控制方式,一种是边界检测,一种是鼠标拖动。这个代码是完整版的,也就是键盘也可以控制相机移动缩放的,如果只需要鼠标控制的,请往下看:

usingUnityEngine;

///<summary>
///
///*Writer:June
///*
///*Data:2021.3.9
///*
///*Function:RTS模式的相机移动
///*
///*Remarks:
///
///</summary>

publicclassCameraMoveControl:MonoBehaviour
{
#region移动
///<summary>
///移动速度
///</summary>
privatefloatpanSpeed;
///<summary>
///正常速度
///</summary>
[SerializeField]privatefloatnormalSpeed;
///<summary>
///按shift加速
///</summary>
[SerializeField]privatefloatspeedUp;
///<summary>
///缓冲时间
///</summary>
[SerializeField]privatefloatmoveTime;
privateVector3newPos;
///<summary>
///边界限制
///</summary>
[SerializeField]privatefloatxLimMin,xLimMax;
///<summary>
///这里的Y是指屏幕上下平移的限制
///</summary>
[SerializeField]privatefloatyLimMin,yLimMax;
//-----------------------------------------------鼠标拖动操作相关字段----------------------------------------------------
privateCameramainCamrea;
privateVector3startPoint,currentPoint;
#endregion

#region缩放
///<summary>
///主摄像机的位置组件
///</summary>
privateTransformmainCamreaTF;
///<summary>
///缩放向量
///tips:相机的放大缩小改变的是相机自身坐标的yz值
///</summary>
[SerializeField]privateVector3zoomV3;
/*
*需要注意的是缩放限制:
*x轴与y轴限制后的缩放比值要一致,不然会出现缩放不平滑的现象
*
*/
///<summary>
///缩放最大最小值
///</summary>
[SerializeField]privateVector3zoomMin,zoomMax;
privateVector3newMainCamreaPos;
///<summary>
///缩放时间
///</summary>
[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();
}

///<summary>
///控制相机缩放
///</summary>
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);
}
}


///<summary>
///控制相机移动
///</summary>
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.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))
{
//新建的世界坐标系下的平面,用于检测射线
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);
}


///<summary>
///边界限制
///</summary>
///<paramname="_pos">要限制的目标向量</param>
privatevoidBoundaryLimit(refVector3_pos)
{
_pos.x=Mathf.Clamp(_pos.x,xLimMin,xLimMax);
_pos.z=Mathf.Clamp(_pos.z,yLimMin,yLimMax);
}


///<summary>
///缩放限制
///</summary>
///<paramname="_v3">要限制的目标向量</param>
privatevoidZoomLimit(refVector3_v3)
{
_v3.y=Mathf.Clamp(_v3.y,zoomMin.y,zoomMax.y);
_v3.z=Mathf.Clamp(_v3.z,zoomMin.z,zoomMax.z);
}
}

这个代码是后来我觉得其实没必要用键盘来操控相机,根据我玩过的一些类似游戏,比较多都是鼠标操作的,所以删了键盘操作的部分:

usingUnityEngine;

///<summary>
///
///*Writer:June
///*
///*Data:2021.3.9
///*
///*Function:RTS模式的相机移动
///*
///*Remarks:
///
///</summary>

publicclassCameraMoveControl:MonoBehaviour
{
#region移动
///<summary>
///移动速度
///</summary>
privatefloatpanSpeed;
///<summary>
///正常速度
///</summary>
[SerializeField]privatefloatnormalSpeed;
///<summary>
///按shift加速
///</summary>
[SerializeField]privatefloatspeedUp;
///<summary>
///缓冲时间
///</summary>
[SerializeField]privatefloatmoveTime;
privateVector3newPos;
///<summary>
///边界限制
///</summary>
[SerializeField]privatefloatxLimMin,xLimMax;
///<summary>
///这里的Y是指屏幕上下平移的限制
///</summary>
[SerializeField]privatefloatyLimMin,yLimMax;
//-----------------------------------------------鼠标拖动操作相关字段----------------------------------------------------
privateCameramainCamrea;
privateVector3startPoint,currentPoint;
#endregion

#region缩放
///<summary>
///主摄像机的位置组件
///</summary>
privateTransformmainCamreaTF;
///<summary>
///缩放向量
///tips:相机的放大缩小改变的是相机自身坐标的yz值
///</summary>
[SerializeField]privateVector3zoomV3;
/*
*需要注意的是缩放限制:
*x轴与y轴限制后的缩放比值要一致,不然会出现缩放不平滑的现象
*
*/
///<summary>
///缩放最大最小值
///</summary>
[SerializeField]privateVector3zoomMin,zoomMax;
privateVector3newMainCamreaPos;
///<summary>
///缩放时间
///</summary>
[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();
}

///<summary>
///控制相机缩放
///</summary>
privatevoidControlCamreaZoom()
{
if(mainCamreaTF)
{
newMainCamreaPos+=Input.GetAxis("MouseScrollWheel")*zoomV3;
ZoomLimit(refnewMainCamreaPos);
//刷新最终位置
mainCamreaTF.localPosition=Vector3.Lerp(mainCamreaTF.localPosition,newMainCamreaPos,zoomTime*Time.deltaTime);
}
}


///<summary>
///控制相机移动
///</summary>
privatevoidControlCamreaMove()
{
Vector3movePos=transform.position;
newPos=Vector3.zero;
#region鼠标操作
#region方式1(鼠标到达边缘,检测后操作相机移动)
Vector2mousePos=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))
{
//新建的世界坐标系下的平面,用于检测射线
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);
}


///<summary>
///边界限制
///</summary>
///<paramname="_pos">要限制的目标向量</param>
privatevoidBoundaryLimit(refVector3_pos)
{
_pos.x=Mathf.Clamp(_pos.x,xLimMin,xLimMax);
_pos.z=Mathf.Clamp(_pos.z,yLimMin,yLimMax);
}


///<summary>
///缩放限制
///</summary>
///<paramname="_v3">要限制的目标向量</param>
privatevoidZoomLimit(refVector3_v3)
{
_v3.y=Mathf.Clamp(_v3.y,zoomMin.y,zoomMax.y);
_v3.z=Mathf.Clamp(_v3.z,zoomMin.z,zoomMax.z);
}
}

上述内容就是使用UnityRTS怎么实现一个相机移动缩放功能,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注恰卡编程网行业资讯频道。

发布于 2021-03-13 15:41:28
收藏
分享
海报
0 条评论
163
上一篇:如何搭建MyBatis-Plus框架并进行数据库增删改查功能 下一篇:ASP.NET Core扩展库的功能是什么
目录

    推荐阅读

    0 条评论

    本站已关闭游客评论,请登录或者注册后再评论吧~

    忘记密码?

    图形验证码