塔防游戏 Day2

1. 创建炮塔选择的 UI

  使用 UI -> Toggle 。注意指定同一 group。

 

2. 创建炮台的数据类

 1 [System.Serializable]                       // 序列化
 2 public class TurretData{
 3     public GameObject turretPrefab;         // 炮塔模型
 4     public int cost;                        // 建造炮塔花费
 5     public GameObject turretUpgradedPrefab; // 升级炮塔模型
 6     public int costUpgraded;                // 升级花费
 7     public TurretType type;                 // 炮台类型
 8 }
 9 
10 public enum TurretType                      // 炮塔类型
11 {
12     LaserTurret,
13     MissileTurret,
14     StandardTurret
15 }

 

 

3. 监听炮塔选择的事件

  在 Inspector 中指定 On Value Changed 触发函数。

  

 1 public void onLaserSelected(bool isOn)              // 当监听变量发生变化时触发
 2     {
 3         if (isOn)
 4         {
 5             selectedTurretData = laserTurretData;
 6         }
 7     }
 8 
 9     public void onMissileSelected(bool isOn)
10     {
11         if (isOn)
12         {
13             selectedTurretData = missileTurretData;
14         }
15     }
16 
17     public void onStandardSelected(bool isOn)
18     {
19         if (isOn)
20         {
21             selectedTurretData = standardTurretData;
22         }
23     }

 

 

4. 鼠标点击创建炮塔

 1 void Update()
 2     {
 3         if (Input.GetMouseButtonDown(0))                            // 监测鼠标左键点击 
 4         {
 5             if (!EventSystem.current.IsPointerOverGameObject())     // 鼠标没有点击 UI 图标
 6             {
 7                 // 有鼠标所在位置发射射线
 8                 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
 9                 RaycastHit hit;                                     // 存储射线碰撞物
10                 bool isCollider = Physics.Raycast(ray, out hit, 1000, LayerMask.GetMask("MapCube"));
11                 if (isCollider)
12                 {
13                     MapCube mapCube = hit.collider.GetComponent<MapCube>();     // 获取点击方块
14                     // 当前已选择炮台且方块上没有放置炮台
15                     if (selectedTurretData != null &&  mapCube.turretGo == null)
16                     {
17                         if (money > selectedTurretData.cost)                    // 钱够用
18                         {
19                             ChangeMoney(-selectedTurretData.cost);
20                             mapCube.BuildTurret(selectedTurretData.turretPrefab);
21                         }
22                         else 
23                         {
24                             // 钱不够,则触发动画
25                             moneyAnimator.SetTrigger("Flicker");
26                         }
27                     }
28                     else if (mapCube.turretGo != null)
29                     {
30                         // TODO 升级处理
31                     }
32                 }
33             }
34         }
35     }

 

1 // 建造炮塔
2     public void BuildTurret(GameObject turretPrefab)
3     {
4         // 实例化炮塔模型
5         turretGo = GameObject.Instantiate(turretPrefab, transform.position, Quaternion.identity);
6         // 产生建造特效
7         GameObject effect = GameObject.Instantiate(buildEffect, transform.position, Quaternion.identity);
8         Destroy(effect, 1);                     // 一秒后销毁特效
9     }

 

 

5. 检测炮塔附近的敌人

 1 public class Turret : MonoBehaviour {
 2     // 存储炮塔攻击范围内的敌人
 3     public List<GameObject> enemys = new List<GameObject>();
 4 
 5     void OnTriggerEnter(Collider col)
 6     {
 7         if (col.tag == "Enemy")             // 敌人进入
 8         {
 9             enemys.Add(col.gameObject);
10         }
11     }
12 
13     void OnTriggerExit(Collider col)
14     {   
15         if (col.tag == "Enemy")             // 敌人离开
16         {
17             enemys.Remove(col.gameObject);
18         }
19     }
20 
21     public float attackRateTime = 1;        // 攻击频率      
22     private float timer = 0;                // 记录时间
23 
24     public GameObject bulletPrefab;         // 子弹模型
25     public Transform firePosition;          // 子弹生成位置
26     public Transform head;                  // 炮塔头部位置
27 
28     void Start()
29     {
30         timer = attackRateTime;             // 有敌人立刻攻击
31     }
32 
33     void Update()
34     {
35         if (enemys.Count > 0)
36         {
37             if (enemys[0] != null)
38             {
39                 // 炮塔头部转向敌人位置
40                 Vector3 targetPosition = enemys[0].transform.position;
41                 targetPosition.y = head.position.y;         // 要注意高度相同
42                 head.LookAt(targetPosition);
43             }
44             timer += Time.deltaTime;
45             if (timer >= attackRateTime)                    // 攻击
46             {
47                 timer -= attackRateTime;
48                 Attack();
49             }
50         }
51     }
52 
53     void Attack()
54     {
55         if (enemys[0] == null)             // 若第一个敌人为空
56         {
57             updateEnemys();                 // 更新攻击范围内敌人
58         }
59         if (enemys.Count > 0)
60         {
61             // 实例化子弹
62             GameObject bullet = GameObject.Instantiate(bulletPrefab, firePosition.position, firePosition.rotation);
63             bullet.GetComponent<Bullet>().setTarget(enemys[0].transform);
64         }
65         else
66         {
67             timer = attackRateTime;
68         }
69     }
70 
71     // 去除已经死亡的敌人
72     void updateEnemys()
73     {
74         List<int> emptyIndex = new List<int>();
75         for (int i = 0; i < enemys.Count; ++i)
76         {
77             if (enemys[i] == null)
78             {
79                 emptyIndex.Add(i);
80             }
81         }
82         for (int i = 0; i < emptyIndex.Count; ++i)
83         {
84             enemys.RemoveAt(emptyIndex[i] - i);
85         }
86     }
87 }

 

6. 敌人添加血条设计

  使用 UI -> Slider 

hpSlider.value = (float)hp / totalHp;           // 更新血条

 

7. 

 

posted @ 2018-03-15 20:14  Just_for_Myself  阅读(446)  评论(0编辑  收藏  举报