您好,登录后才能下订单哦!
这篇文章主要介绍了怎么用Unity实现掘地求升游戏的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇怎么用Unity实现掘地求升游戏文章都会有所收获,下面我们一起来看看吧。
1.场景搭建
说干就干,我们来实际操作一下。
新建一个场景,用简易的3D物体来组装成猛男和锤子,挂上不同的材质用颜色区分一下。
然后分别挂上Rigibody,因为我们想的是让2D平面运行,因此在Rigibody上分别锁了Z轴的移动和X,Y轴的旋转,顺便把锤子上的重力去掉,因为待会要用代码去控制锤子的位置。
2.控制锤头
新建一个脚本挂载在父节点上,分别获取身体和锤子。
我们想要的效果是锤子能一直跟随鼠标移动且锤头一直指向鼠标,思路是在锤头添加一个空的子节点作为锤头的锚点,然后让整个锤子围绕着这个锚点的Z轴旋转让锤柄指向身体的方向。
public GameObject body;public GameObject hammer;Rigidbody body_rig;Rigidbody hammer_rig;Transform hammer_anchor;void Start(){ body_rig = body.GetComponent<Rigidbody>(); hammer_rig = hammer.GetComponent<Rigidbody>(); hammer_anchor = hammer.transform.GetChild(2);}//物理相关的操作一般最好放在FixedUpdate里进行,与系统的物理计算保持同步 private void FixedUpdate() { HammerControl(); }void HammerControl(){ //获取鼠标在屏幕上的坐标并转换为世界坐标 Vector2 MousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition); //通过修改锤子身上刚体的速度让锤子移动,向量的起点用锤头的坐标 //注意这里要让锤头的锚点与锤子本身的坐标的Z值相等,为了让旋转轴与世界坐标的Z轴平行,同理鼠标坐标的Z值也直接使用锤子的坐标的Z值 hammer_rig.velocity = (new Vector3(MousePosition.x, MousePosition.y, hammer.transform.position.z) - hammer_anchor.position) * 10; //获取身体到鼠标的方向 Vector3 direction = (new Vector3(MousePosition.x, MousePosition.y, hammer_anchor.position.z) - new Vector3(body.transform.position.x, body.transform.position.y, hammer_anchor.position.z)).normalized; //让锤子沿着锤头锚点转向身体的方向 hammer.transform.RotateAround(hammer_anchor.position, Vector3.Cross(hammer_anchor.up, direction), Vector3.Angle(hammer_anchor.up, direction)); }
效果如图:
但是现在问题来了,因为只是简单模拟功能的效果,所以猛男并没有手,但是最终我们是希望锤子活动的范围离猛男有一个最大距离的限制,这样看起来好像是有一只无形的手来操作锤子一样,该如何计算这个范围呢?
由图可见这个问题的思路是,当锤头锚点在最大活动范围里面时是跟着鼠标的坐标走,当处于最大活动范围外的时候是跟着锤头锚点与身体坐标的向量和最大移动范围形成的圆的交点走。这个思路用于代码上就是当鼠标移动到最大距离范围之外时得到当前身体到鼠标位置的方向向量,然后让这个向量的长度等于最大距离的长度。
那么,我们在此基础上修改一下代码。
public float MaxDistance; float RelativeDistance;//单独抽出一个函数获取最大距离以外的转换后的鼠标坐标 Vector2 GetConfinedPosition(Vector2 mouseposition) { Vector2 Confined_MousePosition; //去掉body坐标的Z值,避免计算距离时的影响 Vector2 body_position = new Vector2(body.transform.position.x, body.transform.position.y); //计算当前鼠标位置和身体位置的相对距离 RelativeDistance = Vector2.Distance(mouseposition, body_position); if (RelativeDistance > MaxDistance) { //当相对距离大于自己设置的最大距离时,获取转换以后的目标坐标 //这里的思路需要稍稍转一个弯,一开始是获取的是长度为最大距离,方向为身体到鼠标方向的向量。 //在这个基础上加上身体的当前坐标,其等于是将这个向量的起始点设置为身体的坐标。 //最后向量与坐标点可以直接相互转换,此时转换后的目标坐标就等于这个向量。 Confined_MousePosition = (mouseposition - body_position).normalized * MaxDistance + body_position; } else { //若相对距离小于最大距离那么鼠标当前坐标就是目标坐标 Confined_MousePosition = mouseposition; } return Confined_MousePosition; }
然后把HammerControl()函数内的MousePosition的赋值修改一下:
//获取鼠标在屏幕上的坐标并转换为世界坐标,若相对距离大于最大距离则获得转换后的坐标 Vector2 MousePosition = GetConfinedPosition(Camera.main.ScreenToWorldPoint(Input.mousePosition));
最后调整MaxDistance到一个合适的值,效果如下:
3.控制身体的逆向运动
现在离实现就差最后一步了,前面思考实现方式的时候说过,锤头的移动方向与理论上身体移动的方向刚好是相反的,并且同为以身体重心为原点,锤子的最大移动距离为半径的圆的切线。那么我们顺着这个思路去做。
首先还有一个先决条件,锤子不能凭空受力,必须是杵在地上或者挂在障碍物上才行。
我们先在锤头上加一个碰撞盒子并在锤子上添加一个新建脚本,用几句简单的代码用来检测锤头是否碰撞到东西。
public class CollisionDetection : MonoBehaviour { public bool IsCollision; private void OnCollisionEnter(Collision collision) { IsCollision = true; } private void OnCollisionExit(Collision collision) { IsCollision = false; } }
这里要注意的是锤子是锤头的父物体,所以即便碰撞盒子不在锤子上,作为父物体的锤子依然能检测到子物体上的碰撞信息,反过来由于锤头上并没有刚体组件,所以脚本挂在锤头上是检测不到碰撞信息的。
然后当检测到碰撞时给予身体一个相反的速度值。
void HammerControl() { //在给hammer_rig.velocity赋值后添加下面的代码 if(hammer.GetComponent<CollisionDetection>().IsCollision) { BodyControl(hammer_rig.velocity); } } void BodyControl(Vector3 velociy) { body_rig.velocity = -velociy; }
最后效果如下:
关于“怎么用Unity实现掘地求升游戏”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“怎么用Unity实现掘地求升游戏”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。