1 using UnityEngine;
2 using System.Collections;
3
4 [AddComponentMenu("Game/AutoDestroy")]
5 public class AutoDestroy : MonoBehaviour {
6
7 public float m_timer = 1.0f;
8
9 void Start () {
10
11 Destroy(this.gameObject, m_timer);
12 }
13 }
AutoDestroy
1 using UnityEngine;
2 using System.Collections;
3
4
5 [AddComponentMenu("Game/Enemy")]
6 public class Enemy : MonoBehaviour {
7
8 // Transform组件
9 Transform m_transform;
10 //CharacterController m_ch;
11
12 // 动画组件
13 Animator m_ani;
14
15 // 寻路组件
16 NavMeshAgent m_agent;
17
18 // 主角
19 Player m_player;
20
21 // 角色移动速度
22 float m_movSpeed = 2.5f;
23
24 // 角色旋转速度
25 float m_rotSpeed = 5.0f;
26
27 // 计时器
28 float m_timer=2;
29
30 // 生命值
31 int m_life = 15;
32
33 // 成生点
34 protected EnemySpawn m_spawn;
35
36 // Use this for initialization
37 void Start () {
38
39 m_transform = this.transform;
40 // 获取动画组件
41 m_ani = this.GetComponent<Animator>();
42
43 // 获得主角
44 m_player = GameObject.FindGameObjectWithTag("Player").GetComponent<Player>();
45 m_agent = GetComponent<NavMeshAgent>();
46 m_agent.speed = m_movSpeed;
47 // 设置寻路目标
48 m_agent.SetDestination(m_player.m_transform.position);
49
50 }
51
52 // 初始化
53 public void Init(EnemySpawn spawn)
54 {
55 m_spawn = spawn;
56
57 m_spawn.m_enemyCount++;
58 }
59
60
61 // Update is called once per frame
62 void Update () {
63
64 // 如果主角生命为0,什么也不做
65 if (m_player.m_life <= 0)
66 return;
67
68 // 获取当前动画状态
69 AnimatorStateInfo stateInfo = m_ani.GetCurrentAnimatorStateInfo(0);
70
71 // 如果处于待机状态
72 if (stateInfo.nameHash == Animator.StringToHash("Base Layer.idle") && !m_ani.IsInTransition(0))
73 {
74 m_ani.SetBool("idle", false);
75
76 // 待机一定时间
77 m_timer -= Time.deltaTime;
78 if (m_timer > 0)
79 return;
80
81 // 如果距离主角小于1.5米,进入攻击动画状态
82 if (Vector3.Distance(m_transform.position, m_player. m_transform.position) < 1.5f)
83 {
84 m_ani.SetBool("attack", true);
85 }
86 else
87 {
88 // 重置定时器
89 m_timer=1;
90
91 // 设置寻路目标点
92 m_agent.SetDestination(m_player. m_transform.position);
93
94 // 进入跑步动画状态
95 m_ani.SetBool("run", true);
96 }
97 }
98
99 // 如果处于跑步状态
100 if (stateInfo.nameHash == Animator.StringToHash("Base Layer.run") && !m_ani.IsInTransition(0))
101 {
102
103 m_ani.SetBool("run", false);
104
105 // 每隔1秒重新定位主角的位置
106 m_timer -= Time.deltaTime;
107 if (m_timer < 0)
108 {
109 m_agent.SetDestination(m_player. m_transform.position);
110
111 m_timer = 1;
112 }
113
114 // 追向主角
115 // MoveTo();
116
117 // 如果距离主角小于1.5米,向主角攻击
118 if (Vector3.Distance(m_transform.position, m_player. m_transform.position) <= 1.5f)
119 {
120 //停止寻路
121 //m_agent.ResetPath();
122 m_agent.Stop();
123 // 进入攻击状态
124 m_ani.SetBool("attack", true);
125 }
126 }
127
128 // 如果处于攻击状态
129 if (stateInfo.nameHash == Animator.StringToHash("Base Layer.attack") && !m_ani.IsInTransition(0))
130 {
131
132 // 始终面向主角
133 RotateTo();
134
135 m_ani.SetBool("attack", false);
136
137 // 如果攻击动画播完,重新进入待机状态
138 if (stateInfo.normalizedTime >= 1.0f)
139 {
140 m_ani.SetBool("idle", true);
141
142 // 重置计时器
143 m_timer = 2;
144
145 m_player.OnDamage(1);
146 }
147 }
148
149 // 死亡
150 if (stateInfo.nameHash == Animator.StringToHash("Base Layer.death") && !m_ani.IsInTransition(0))
151 {
152 if (stateInfo.normalizedTime >= 1.0f)
153 {
154 //更新敌人数量
155 m_spawn.m_enemyCount--;
156
157 // 加100分
158 GameManager.Instance.SetScore(100);
159
160 // 销毁
161 Destroy(this.gameObject);
162
163 }
164 }
165
166
167 }
168
169 // 转向目标点
170 void RotateTo()
171 {
172 // 获取目标方向
173 Vector3 targetdir = m_player.m_transform.position - m_transform.position;
174 // 计算出新方向
175 Vector3 newDir = Vector3.RotateTowards(transform.forward, targetdir, m_rotSpeed * Time.deltaTime, 0.0f);
176 // 旋转至新方向
177 m_transform.rotation = Quaternion.LookRotation(newDir);
178 }
179
180 // 寻路移动
181 void MoveTo()
182 {
183 float speed = m_movSpeed * Time.deltaTime;
184 m_agent.Move(m_transform.TransformDirection((new Vector3(0, 0, speed))));
185
186 }
187
188 // 伤害
189 public void OnDamage(int damage)
190 {
191 m_life -= damage;
192
193 // 如果生命为0,销毁自身
194 if (m_life <= 0)
195 {
196 m_ani.SetBool("death", true);
197 }
198 }
199 }
Enemy
1 using UnityEngine;
2 using System.Collections;
3
4 /// <summary>
5 /// 敌人孵化器
6 /// </summary>
7 [AddComponentMenu("Game/EnemySpawn")]
8 public class EnemySpawn : MonoBehaviour
9 {
10 /// <summary>
11 /// 敌人预设
12 /// </summary>
13 public Transform m_enemy;
14
15 /// <summary>
16 /// 生成的敌人数量
17 /// </summary>
18 public int m_enemyCount = 0;
19
20 /// <summary>
21 /// 敌人的最大生成数量
22 /// </summary>
23 public int m_maxEnemy = 3;
24
25 /// <summary>
26 /// 生成敌人的时间间隔
27 /// </summary>
28 public float m_timer = 0;
29
30 protected Transform m_transform;
31
32 void Start () {
33
34 m_transform = this.transform;
35
36 }
37
38 void Update () {
39
40 if(m_enemyCount >= m_maxEnemy)
41 return;
42
43 m_timer -= Time.deltaTime;
44 if (m_timer <= 0)
45 {
46 m_timer = Random.value * 15.0f;
47 if (m_timer < 5)
48 m_timer = 5;
49
50 Transform obj=(Transform)Instantiate(m_enemy, m_transform.position, Quaternion.identity);
51 Enemy enemy = obj.GetComponent<Enemy>();
52 enemy.Init(this);
53 }
54 }
55
56 void OnDrawGizmos ()
57 {
58 Gizmos.DrawIcon (transform.position, "item.png", true);
59 }
60
61 }
EnemySpawn
1 using UnityEngine;
2 using System.Collections;
3
4 [AddComponentMenu("Game/GameManager")]
5 public class GameManager : MonoBehaviour {
6
7 public static GameManager Instance = null;
8
9 // 游戏得分
10 public int m_score = 0;
11
12 // 游戏最高得分
13 public static int m_hiscore = 0;
14
15 // 弹药数量
16 public int m_ammo = 100;
17
18 // 游戏主角
19 Player m_player;
20
21 // UI文字
22 GUIText txt_ammo;
23 GUIText txt_hiscore;
24 GUIText txt_life;
25 GUIText txt_score;
26
27 // Use this for initialization
28 void Start () {
29
30 Instance = this;
31
32 // 获得主角
33 m_player = GameObject.FindGameObjectWithTag("Player").GetComponent<Player>();
34
35 // 获得设置的UI文字
36 foreach (Transform t in this.transform.GetComponentsInChildren<Transform>())
37 {
38
39 if (t.name.CompareTo("txt_ammo") == 0)
40 {
41 txt_ammo = t.GetComponent<GUIText>();
42 }
43 else if (t.name.CompareTo("txt_hiscore") == 0)
44 {
45 txt_hiscore = t.GetComponent<GUIText>();
46 txt_hiscore.text = "High Score " + m_hiscore;
47 }
48 else if (t.name.CompareTo("txt_life") == 0)
49 {
50 txt_life = t.GetComponent<GUIText>();
51 }
52 else if (t.name.CompareTo("txt_score") == 0)
53 {
54 txt_score = t.GetComponent<GUIText>();
55 }
56 }
57
58
59 }
60
61 void Update()
62 {
63 if (Input.GetKeyDown(KeyCode.Escape))
64 Application.Quit();
65 }
66
67 void OnGUI()
68 {
69 if (m_player.m_life <= 0)
70 {
71 // 居中显示文字
72 GUI.skin.label.alignment = TextAnchor.MiddleCenter;
73
74 // 改变文字大小
75 GUI.skin.label.fontSize = 40;
76
77 // 显示Game Over
78 GUI.Label(new Rect(0, 0, Screen.width, Screen.height), "Game Over");
79
80 // 显示重新游戏按钮
81 GUI.skin.label.fontSize = 30;
82 if ( GUI.Button( new Rect( Screen.width*0.5f-150,Screen.height*0.75f,300,40),"Try again"))
83 {
84 Application.LoadLevel(Application.loadedLevelName);
85 }
86 }
87 }
88
89 // 更新分数
90 public void SetScore(int score)
91 {
92 m_score+= score;
93
94 if (m_score > m_hiscore)
95 m_hiscore = m_score;
96
97 txt_score.text = "Score <color=yellow>" + m_score + "</color>";;
98 txt_hiscore.text = "High Score " + m_hiscore;
99
100 }
101
102 // 更新弹药
103 public void SetAmmo(int ammo)
104 {
105 m_ammo -= ammo;
106
107 // 如果弹药为负数,重新填弹
108 if (m_ammo <= 0)
109 m_ammo = 100 - m_ammo;
110
111 txt_ammo.text = m_ammo.ToString()+"/100";
112 }
113
114 // 更新生命
115 public void SetLife(int life)
116 {
117 txt_life.text = life.ToString();
118 }
119
120
121
122 }
GameManager
1 using UnityEngine;
2 using System.Collections;
3
4 [AddComponentMenu("Game/MiniCamera")]
5 public class MiniCamera : MonoBehaviour {
6
7 void Start () {
8 // 获得屏幕分辨率比例
9 float ratio = (float)Screen.width / (float)Screen.height;
10 // 使摄像机视图永远是一个正方向, rect的前两个参数表示XY位置,后两个参数是XY大小
11 this.GetComponent<Camera>().rect = new Rect((1 - 0.2f), (1 - 0.2f * ratio), 0.2f, 0.2f * ratio);
12 }
13 }
MiniCamera
1 using UnityEngine;
2 using System.Collections;
3
4 [AddComponentMenu("Game/Player")]
5 public class Player : MonoBehaviour {
6
7 public Transform m_transform;
8
9 // 角色控制器组件
10 CharacterController m_ch;
11
12 // 角色移动速度
13 float m_movSpeed = 3.0f;
14
15 // 重力
16 float m_gravity = 2.0f;
17
18
19 // 摄像机
20 Transform m_camTransform;
21
22 // 摄像机旋转角度
23 Vector3 m_camRot;
24
25 // 摄像机高度
26 float m_camHeight = 1.4f;
27
28 // 生命值
29 public int m_life = 5;
30
31 //枪口transform
32 Transform m_muzzlepoint;
33
34 // 射击时,射线能射到的碰撞层
35 public LayerMask m_layer;
36
37 // 射中目标后的粒子效果
38 public Transform m_fx;
39
40 // 射击音效
41 public AudioClip m_audio;
42
43 // 射击间隔时间计时器
44 float m_shootTimer = 0;
45
46 // Use this for initialization
47 void Start () {
48
49 m_transform = this.transform;
50 // 获取角色控制器组件
51 m_ch = this.GetComponent<CharacterController>();
52
53 // 获取摄像机
54 m_camTransform = Camera.main.transform;
55
56 // 设置摄像机初始位置
57 Vector3 pos = m_transform.position;
58 pos.y += m_camHeight;
59 m_camTransform.position = pos;
60
61 // 设置摄像机的旋转方向与主角一致
62 m_camTransform.rotation = m_transform.rotation;
63 m_camRot = m_camTransform.eulerAngles;
64
65 Screen.lockCursor = true;
66
67 // 查找muzzlepoint
68 m_muzzlepoint = m_camTransform.FindChild("M16/weapon/muzzlepoint").transform;
69
70 }
71
72 // Update is called once per frame
73 void Update () {
74
75 // 如果生命为0,什么也不做
76 if (m_life <= 0)
77 return;
78
79 Control();
80 }
81
82 void Control()
83 {
84
85 //获取鼠标移动距离
86 float rh = Input.GetAxis("Mouse X");
87 float rv = Input.GetAxis("Mouse Y");
88
89 // 旋转摄像机
90 m_camRot.x -= rv;
91 m_camRot.y += rh;
92 m_camTransform.eulerAngles = m_camRot;
93
94 // 使主角的面向方向与摄像机一致
95 Vector3 camrot = m_camTransform.eulerAngles;
96 camrot.x = 0; camrot.z = 0;
97 m_transform.eulerAngles = camrot;
98
99 // 定义3个值控制移动
100 float xm = 0, ym = 0, zm = 0;
101
102 // 重力运动
103 ym -= m_gravity*Time.deltaTime;
104
105 // 上下左右运动
106 if (Input.GetKey(KeyCode.W)){
107 zm += m_movSpeed * Time.deltaTime;
108 }
109 else if (Input.GetKey(KeyCode.S)){
110 zm -= m_movSpeed * Time.deltaTime;
111 }
112
113 if (Input.GetKey(KeyCode.A)){
114 xm -= m_movSpeed * Time.deltaTime;
115 }
116 else if (Input.GetKey(KeyCode.D)){
117 xm += m_movSpeed * Time.deltaTime;
118 }
119
120 // 更新射击间隔时间
121 m_shootTimer -= Time.deltaTime;
122
123 // 鼠标左键射击
124 if (Input.GetMouseButton(0) && m_shootTimer<=0)
125 {
126 m_shootTimer = 0.1f;
127
128 this.GetComponent<AudioSource>().PlayOneShot(m_audio);
129
130 // 减少弹药,更新弹药UI
131 GameManager.Instance.SetAmmo(1);
132
133 // RaycastHit用来保存射线的探测结果
134 RaycastHit info;
135
136 // 从muzzlepoint的位置,向摄像机面向的正方向射出一根射线
137 // 射线只能与m_layer所指定的层碰撞
138 bool hit = Physics.Raycast(m_muzzlepoint.position, m_camTransform.TransformDirection(Vector3.forward), out info, 100, m_layer);
139 if (hit)
140 {
141 // 如果射中了tag为enemy的游戏体
142 if (info.transform.tag.CompareTo("enemy") == 0)
143 {
144 Enemy enemy = info.transform.GetComponent<Enemy>();
145
146 // 敌人减少生命
147 enemy.OnDamage(1);
148 }
149
150 // 在射中的地方释放一个粒子效果
151 Instantiate(m_fx, info.point, info.transform.rotation);
152 }
153 }
154
155
156 // 使用角色控制器提供的Move函数进行移动 它会自动检测碰撞
157 m_ch.Move( m_transform.TransformDirection(new Vector3(xm, ym, zm)) );
158
159 // 使摄像机的位置与主角一致
160 Vector3 pos = m_transform.position;
161 pos.y += m_camHeight;
162 m_camTransform.position = pos;
163
164 }
165
166 void OnDrawGizmos()
167 {
168 Gizmos.DrawIcon(this.transform.position, "Spawn.tif");
169 }
170
171 // 伤害
172 public void OnDamage(int damage)
173 {
174 m_life -= damage;
175
176 // 更新UI
177 GameManager.Instance.SetLife(m_life);
178
179 // 如果生命为0,解锁鼠标显示
180 if (m_life <= 0)
181 Screen.lockCursor = false;
182 }
183
184
185 }
Player
1 using UnityEngine;
2 using System.Collections;
3
4 [AddComponentMenu("Game/Spawn")]
5 public class Spawn : MonoBehaviour
6 {
7
8 public Transform m_transform;
9
10 public Transform m_enemy;
11
12 void Awake()
13 {
14 m_transform = this.transform;
15 }
16
17
18
19 // 图标显示
20 void OnDrawGizmos()
21 {
22 Gizmos.DrawIcon(transform.position, "Node.tif");
23 }
24
25
26 }
Spawn
1 using UnityEngine;
2 using System.Collections;
3
4 public class Cannon : MonoBehaviour {
5
6 // 射击计时器
7 float m_shootTimer = 0;
8
9 void Update () {
10
11 m_shootTimer -= Time.deltaTime;
12 UpdateInput();
13 }
14
15 void UpdateInput()
16 {
17 // 获得鼠标位置
18 Vector3 ms = Input.mousePosition;
19 ms = Camera.main.ScreenToWorldPoint(ms);
20
21 // 大炮的位置
22 Vector3 mypos = this.transform.position;
23
24 // 按鼠标左键开火
25 if (Input.GetMouseButton(0))
26 {
27 // 计算鼠标位置与大炮位置之间的角度
28 Vector2 targetDir = ms - mypos;
29 float angle = Vector2.Angle(targetDir, Vector3.up);
30 if (ms.x > mypos.x)
31 angle = -angle;
32 this.transform.eulerAngles = new Vector3(0, 0, angle);
33
34
35 if (m_shootTimer <= 0)
36 {
37 m_shootTimer = 0.1f;
38
39 // 开火,创建子弹实例
40 Fire.Create(this.transform.TransformPoint(0, 1, 0), new Vector3(0, 0, angle));
41 }
42 }
43 }
44 }
Cannon
1 using UnityEngine;
2 using System.Collections;
3
4 public class Fire : MonoBehaviour {
5
6 // 移动速度
7 float m_moveSpeed = 10.0f;
8
9 // 创建子弹
10 public static Fire Create( Vector3 pos, Vector3 angle )
11 {
12 // 读取子弹Sprite prefab
13 GameObject prefab = Resources.Load<GameObject>("fire");
14 // 创建子弹Sprite实例
15 GameObject fireSprite = (GameObject)Instantiate(prefab, pos, Quaternion.Euler(angle));
16 Fire f = fireSprite.AddComponent<Fire>();
17 Destroy(fireSprite, 2.0f);
18 return f;
19 }
20
21 // Update is called once per frame
22 void Update () {
23 // 更新位置
24 this.transform.Translate(new Vector3(0, m_moveSpeed * Time.deltaTime, 0));
25
26 }
27
28 void OnTriggerEnter2D(Collider2D other)
29 {
30 Fish f =other.GetComponent<Fish>();
31 if (f == null)
32 return;
33 else
34 f.SetDamage(1);
35 Destroy(this.gameObject);
36 }
37 }
Fire
1 using UnityEngine;
2 using System.Collections;
3
4 public class Fish : MonoBehaviour {
5
6 /// <summary>
7 /// 移动速度
8 /// </summary>
9 protected float m_moveSpeed = 2.0f;
10 // 生命值
11 protected int m_life = 10;
12
13 public enum Target
14 {
15 Left=0,
16 Right=1
17 }
18 /// <summary>
19 /// 移动目标(方向)
20 /// </summary>
21 public Target m_target = Target.Right;
22 /// <summary>
23 /// 目标位置
24 /// </summary>
25 public Vector3 m_targetPosition;
26
27 public delegate void VoidDelegate( Fish fish );
28 public VoidDelegate OnDeath;
29
30 /// <summary>
31 /// 创建一个Fish实例
32 /// </summary>
33 public static Fish Create(GameObject prefab, Target target, Vector3 pos )
34 {
35 GameObject go = (GameObject)Instantiate(prefab, pos, Quaternion.identity);
36 Fish fish = go.AddComponent<Fish>();
37 fish.Init(target);
38
39 return fish;
40 }
41
42 void Init(Target target)
43 {
44 m_target = target;
45 }
46
47 public void SetDamage( int damage )
48 {
49 m_life -= damage;
50 if (m_life <= 0)
51 {
52
53 GameObject prefab = Resources.Load<GameObject>("explosion");
54 GameObject explosion = (GameObject)Instantiate(prefab, this.transform.position, this.transform.rotation);
55 Destroy(explosion, 1.0f);
56
57 OnDeath(this);
58 Destroy(this.gameObject);
59 }
60 }
61
62 // Use this for initialization
63 void Start () {
64
65 SetTarget();
66 }
67
68 // Update is called once per frame
69 void Update () {
70
71 UpdatePosition();
72 }
73
74 void UpdatePosition()
75 {
76 Vector3 pos = Vector3.MoveTowards(this.transform.position, m_targetPosition, m_moveSpeed*Time.deltaTime);
77 if (Vector3.Distance(pos, m_targetPosition) < 0.1f)
78 {
79 m_target = m_target==Target.Left ? Target.Right : Target.Left;
80 SetTarget();
81 }
82 this.transform.position = pos;
83 }
84
85 void SetTarget()
86 {
87 // 随机值
88 float rand = Random.value;
89
90 // 设置Sprite翻转方向
91 Vector3 scale = this.transform.localScale;
92 scale.x = Mathf.Abs(scale.x) * (m_target == Target.Right ?1 : -1);
93 this.transform.localScale = scale;
94
95 float cameraz = Camera.main.transform.position.z;
96 // 设置目标位置
97 m_targetPosition = Camera.main.ViewportToWorldPoint(new Vector3((int)m_target, 1 * rand, -cameraz));
98 }
99 }
Fish
1 using UnityEngine;
2 using System.Collections;
3
4 public class FishSpawn : MonoBehaviour {
5
6 /// <summary>
7 /// 生成计时器
8 /// </summary>
9 public float timer = 0;
10
11 /// <summary>
12 /// 最大生成数量
13 /// </summary>
14 public int max_fish = 30;
15 /// <summary>
16 /// 当前鱼的数量
17 /// </summary>
18 public int fish_count = 0;
19
20 // Use this for initialization
21 void Start () {
22
23 }
24
25 // Update is called once per frame
26 void Update () {
27
28 timer -= Time.deltaTime;
29 if (timer <= 0)
30 {
31 // 重新计时
32 timer = 2.0f;
33
34 // 如果鱼的数量达到最大数量则返回
35 if (fish_count >= max_fish)
36 return;
37
38 // 随机1、2、3产生不同的鱼
39 int index = 1 + (int)(Random.value * 3.0f);
40 if (index > 3)
41 index = 3;
42 // 更新鱼的数量
43 fish_count++;
44 // 读取鱼的prefab
45 GameObject fishprefab = (GameObject)Resources.Load("fish " + index);
46
47 float cameraz = Camera.main.transform.position.z;
48 // 鱼的初始随机位置
49 Vector3 randpos = new Vector3(Random.value, Random.value, -cameraz);
50 randpos = Camera.main.ViewportToWorldPoint(randpos);
51
52 // 鱼的随机初始方向
53 Fish.Target target = Random.value > 0.5f ? Fish.Target.Right : Fish.Target.Left;
54 Fish f = Fish.Create(fishprefab, target, randpos);
55
56 // 注册鱼的死亡消息
57 f.OnDeath+=OnDeath;
58
59 }
60
61 }
62
63 void OnDeath( Fish fish )
64 {
65 // 更新鱼的数量
66 fish_count--;
67 }
68
69 }
FishSpawn