Unity3D之飞机游戏追踪导弹制作

您所在的位置:网站首页 unity3d发射炮弹 Unity3D之飞机游戏追踪导弹制作

Unity3D之飞机游戏追踪导弹制作

2023-03-30 13:41| 来源: 网络整理| 查看: 265

最近开发完成一款打飞机的游戏,记录一下制作追踪导弹的方法,最开始在网上找到的资料制作出来的追踪导弹都不够真实,主要的问题是没有对导弹进行一个阀值处理,导弹每帧都始终会面向目标,而不是按照一定的角度进行旋转,导致无法躲避跟踪导弹,下面我来说一下更加真实的跟踪导弹的制作方法。

拖拽

首先,我的Demo里有两个小飞机,一个是主角,一个是敌机,有一个需求就是这两个飞机可以通过鼠标进行拖拽,所以先给出拖拽的脚本,直接绑定即可,当然记得给GameObject添加一个BoxCollder。

1 using UnityEngine; 2 using System.Collections; 3 4 /// 5 /// 拖拽脚本. 6 /// 7 public class DragAndDrop : MonoBehaviour 8 { 9 bool isCatched = false; 10 11 void Update() 12 { 13 if(Input.GetMouseButtonDown(0)) 14 { 15 //根据鼠标位置创建一条垂直于屏幕的射线 16 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); 17 //保存射线信息的结构体 18 RaycastHit hit; 19 //对射线进行碰撞, 如果存在碰撞 20 if(Physics.Raycast(ray, out hit)) 21 { 22 //碰撞到当前对象时 23 if(hit.collider.gameObject == this.gameObject) 24 { 25 //标记为抓取状态 26 isCatched = true; 27 } 28 } 29 } 30 31 if(Input.GetMouseButtonUp(0)) 32 { 33 //取消抓取状态 34 isCatched = false; 35 } 36 37 if(isCatched) 38 { 39 //获取鼠标点在场景中的位置 40 Vector3 pos = Camera.main.ScreenToWorldPoint(Input.mousePosition); 41 pos.z = 0; 42 //设置位置 43 this.transform.position = pos; 44 } 45 } 46 } 管理类

我使用UGUI添加了一个发射导弹的按钮,需要一个管理类来管理这部分的逻辑:

1 using UnityEngine; 2 using System.Collections; 3 4 /// 5 /// 控制脚本. 6 /// 7 public class TrackDemoScript : MonoBehaviour 8 { 9 public GameObject player; 10 11 public GameObject enemy; 12 13 /// 14 /// 开火. 15 /// 16 public void Fire() 17 { 18 GameObject go = Resources.Load("Prefab/Bullet"); 19 GameObject bullet = Instantiate(go, player.transform.position, Quaternion.identity) as GameObject; 20 bullet.GetComponent().target = enemy; 21 } 22 }

导弹被我制作为了一个预制件。

导弹逻辑

最重要的就是阀值了,我规定了每帧允许旋转的一个最大值,保证模拟出现实世界的效果,导弹要转弯肯定是画出一个弧线而不是马上掉头的。

1 using UnityEngine; 2 using System.Collections; 3 4 /// 5 /// 跟踪导弹脚本. 6 /// 7 public class BulletScript : MonoBehaviour 8 { 9 /// 10 /// 每秒最大可旋转的角度. 11 /// 12 private const float MAX_ROTATION = 90; 13 14 /// 15 /// 每帧最大可旋转的角度. 16 /// 17 private static float MAX_ROTATION_FRAME = MAX_ROTATION / ((float) (Application.targetFrameRate == -1 ? 60 : Application.targetFrameRate)); 18 19 /// 20 /// 攻击目标. 21 /// 22 public GameObject target; 23 24 void Start() 25 { 26 } 27 28 void Update() 29 { 30 //转向目标 31 float dx = target.transform.position.x - this.transform.position.x; 32 float dy = target.transform.position.y - this.transform.position.y; 33 float rotationZ = Mathf.Atan2(dy, dx) * 180 / Mathf.PI; 34 //得到最终的角度并且确保在 [0, 360) 这个区间内 35 rotationZ -= 90; 36 rotationZ = MakeSureRightRotation(rotationZ); 37 //获取增加的角度 38 float originRotationZ = MakeSureRightRotation(this.transform.eulerAngles.z); 39 float addRotationZ = rotationZ - originRotationZ; 40 //超过 180 度需要修改为负方向的角度 41 if(addRotationZ > 180) 42 { 43 addRotationZ -= 360; 44 } 45 //不超过每帧最大可旋转的阀值 46 addRotationZ = Mathf.Max(-MAX_ROTATION_FRAME, Mathf.Min(MAX_ROTATION_FRAME, addRotationZ)); 47 //应用旋转 48 this.transform.eulerAngles = new Vector3(0, 0, this.transform.eulerAngles.z + addRotationZ); 49 //移动 50 this.transform.Translate(new Vector3(0, 2.0f * Time.deltaTime, 0)); 51 } 52 53 /// 54 /// 确保角度在 [0, 360) 这个区间内. 55 /// 56 /// 任意数值的角度. 57 /// 对应的在 [0, 360) 这个区间内的角度. 58 private float MakeSureRightRotation(float rotation) 59 { 60 rotation += 360; 61 rotation %= 360; 62 return rotation; 63 } 64 }

运行即可查看效果。

源码下载

http://pan.baidu.com/s/1qWBsvSg



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3