Unity3D之飛機游戲追蹤導彈制作


最近開發完成一款打飛機的游戲,記錄一下制作追蹤導彈的方法,最開始在網上找到的資料制作出來的追蹤導彈都不夠真實,主要的問題是沒有對導彈進行一個閥值處理,導彈每幀都始終會面向目標,而不是按照一定的角度進行旋轉,導致無法躲避跟蹤導彈,下面我來說一下更加真實的跟蹤導彈的制作方法。

拖拽

首先,我的Demo里有兩個小飛機,一個是主角,一個是敵機,有一個需求就是這兩個飛機可以通過鼠標進行拖拽,所以先給出拖拽的腳本,直接綁定即可,當然記得給GameObject添加一個BoxCollder。

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

導彈被我制作為了一個預制件。

導彈邏輯

最重要的就是閥值了,我規定了每幀允許旋轉的一個最大值,保證模擬出現實世界的效果,導彈要轉彎肯定是畫出一個弧線而不是馬上掉頭的。

 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 /// <summary>
 5 /// 跟蹤導彈腳本.
 6 /// </summary>
 7 public class BulletScript : MonoBehaviour
 8 {
 9     /// <summary>
10     /// 每秒最大可旋轉的角度.
11     /// </summary>
12     private const float MAX_ROTATION = 90;
13     
14     /// <summary>
15     /// 每幀最大可旋轉的角度.
16     /// </summary>
17     private static float MAX_ROTATION_FRAME = MAX_ROTATION / ((float) (Application.targetFrameRate == -1 ? 60 : Application.targetFrameRate));
18 
19     /// <summary>
20     /// 攻擊目標.
21     /// </summary>
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     /// <summary>
54     /// 確保角度在 [0, 360) 這個區間內.
55     /// </summary>
56     /// <param name="rotation">任意數值的角度.</param>
57     /// <returns>對應的在 [0, 360) 這個區間內的角度.</returns>
58     private float MakeSureRightRotation(float rotation)
59     {
60         rotation += 360;
61         rotation %= 360;
62         return rotation;
63     }
64 }

運行即可查看效果。

源碼下載

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM