很多人都在玩unity3d 太空大战之飞机游戏,但是学习了unity3d之后,就想学着做这个游戏,就在网上找到了比较详细的关于unity3d 太空大战之飞机游戏的解说。下面就来学习。

这个小游戏我分了三个场景,菜单场景,游戏场景,结束场景。由于菜单场景与结束场景都比较简单,所以主要就说说游戏主场景。源码在文章结尾处。

 1.创建游戏场景
由于创建的是2d项目,则将图片拖入Scene中,该图片自动成为一个精灵,所以将图片信息拖入摆放即可。
                                        

下面创建一个GameManager文件,其绑定在摄像机中,主要负责飞机生命,玩家得分,背景播放等的显示功能。而生命,得分的显示需要我们创建GUIText来摆放。

代码如下:
  1. using UnityEngine;
  2. using System.Collections;
  3. public class GameManager : MonoBehaviour {
  4. //显示控件位置
  5. private Transform life;
  6. private Transform score;
  7. //游戏主角对象
  8. private GameObject player;
  9. void Start () {
  10. //得到显示控件位置
  11. life = transform.Find("Life");
  12. score = transform.Find("Score");
  13. //获取主角飞机对象
  14. player = GameObject.FindGameObjectWithTag("Player");
  15. }
  16. void Update () {
  17. if (player != null)
  18. {
  19. life.guiText.text = "生命:" + player.GetComponent<Player>().max_life.ToString();
  20. score.guiText.text = "分数:" + player.GetComponent<Player>().grade.ToString();
  21. }
  22. if (life.guiText.text == "生命:0")
  23. {
  24. //跳转到游戏结束场景
  25. Application.LoadLevel(2);
  26. }
  27. }
  28. }
然后我们来实现背景的滚动。首先创建两个一样的背景图片上下摆放,如下图所示,这里切换到3d模式,更加形象
                           
下面创建用于绑定在背景上的脚本BGControll.cs,代码如下
  1. using UnityEngine;
  2. using System.Collections;
  3. public class BGControll : MonoBehaviour {
  4. //背景滚动速度
  5. public float speed = 1.5f;
  6. void Update () {
  7. transform.Translate(Vector3.down * Time.deltaTime * speed);
  8. if (transform.position.y <= -5.6f)
  9. {
  10. transform.position = new Vector3(0, 5.7f, 0);
  11. }
  12. }
  13. }

  然后将脚本绑定在两张背景图上即可。

 2.创建主角飞机
主角创建与背景创建基本一样,也是可以用一张2d贴图,就不多说了。主角脚本主要处理移动,发射子弹,处理碰撞等,代码如下:
  1. using UnityEngine;
  2. using System.Collections;
  3. public class Player : MonoBehaviour {
  4. //飞机生命值
  5. public int max_life = 5;
  6. //子弹飞行速度
  7. public float m_speed;
  8. //子弹对象
  9. public GameObject bullet;
  10. //子弹发射位置
  11. private Transform bulletLeft;
  12. private Transform bulletRight;
  13. //发射子弹频率
  14. private float bulletRate = 0;
  15. private Transform m_transform;
  16. //声音资源
  17. private AudioSource audio;
  18. [HideInInspector]
  19. //分数
  20. public int grade = 0;
  21. //初始化变量
  22. void Start () {
  23. bulletLeft = this.transform.Find("bulletL");
  24. bulletRight = this.transform.Find("bulletR");
  25. m_transform = this.transform;
  26. audio = GetComponent<AudioSource>();
  27. }
  28. void Update () {
  29. //上方向键
  30. if (Input.GetKey(KeyCode.UpArrow))
  31. {
  32. m_transform.Translate(Vector3.up * Time.deltaTime * m_speed);
  33. }
  34. //左方向键
  35. if (Input.GetKey(KeyCode.LeftArrow))
  36. {
  37. m_transform.Translate(Vector3.left * Time.deltaTime * m_speed);
  38. }
  39. //下方向键
  40. if (Input.GetKey(KeyCode.DownArrow))
  41. {
  42. m_transform.Translate(Vector3.up * Time.deltaTime * (-m_speed));
  43. }
  44. //右方向键
  45. if (Input.GetKey(KeyCode.RightArrow))
  46. {
  47. m_transform.Translate(Vector3.left * Time.deltaTime * (-m_speed));
  48. }
  49. bulletRate -= Time.deltaTime;
  50. if (bulletRate <= 0)
  51. {
  52. bulletRate = 0.1f;
  53. //按下空格键,发射子弹
  54. if (Input.GetKey(KeyCode.Space))
  55. {
  56. Instantiate(bullet, bulletLeft.transform.position, Quaternion.Euler(new Vector3(0, 1, 0)));
  57. Instantiate(bullet, bulletRight.transform.position, Quaternion.identity);
  58. //播放射击声音
  59. audio.Play();
  60. }
  61. }
  62. check();
  63. }
  64. //检测边界,使飞机不飞出摄像机
  65. void check()
  66. {
  67. if (m_transform.position.x <= -1.3f)
  68. {
  69. m_transform.position = new Vector3(-1.3f, m_transform.position.y, 0);
  70. }
  71. if (m_transform.position.x >= 1.3f)
  72. {
  73. m_transform.position = new Vector3(1.3f, m_transform.position.y, 0);
  74. }
  75. if (m_transform.position.y >= 2.5f)
  76. {
  77. m_transform.position = new Vector3(m_transform.position.x, 2.5f, 0);
  78. }
  79. if (m_transform.position.y <= -2.5f)
  80. {
  81. m_transform.position = new Vector3(m_transform.position.x, -2.5f, 0);
  82. }
  83. }
  84. //碰撞时调用该方法,飞机减血
  85. public void Hit(int Value)
  86. {
  87. if (max_life > 0)
  88. {
  89. max_life -= Value;
  90. }
  91. else
  92. {
  93. Destroy(this.gameObject);
  94. //Application.LoadLevel(2);
  95. }
  96. }
  97. //增加分数
  98. public void Add(int score)
  99. {
  100. grade += score;
  101. }
  102. }
上面代码中我用了bulletLeft,bulletRight,这是我为主机添加的两个子对象,主要是用于发射子弹,相当于炮筒吧,而bullet则是定义的预设,其中绑定的脚本后面会说明。

下面是Bullet子弹预设绑定的脚本代码,子弹主要功能为与敌人发生碰撞,主角得分,敌人减血。
  1. using UnityEngine;
  2. using System.Collections;
  3. public class Bullet : MonoBehaviour {
  4. //子弹的速度
  5. public float m_speed = 2f;
  6. //子弹存在时间
  7. public float lifeTime = 20f;
  8. //子弹碰撞到敌人伤害
  9. public int power = 2;
  10. //玩家飞机
  11. private GameObject player;
  12. void Start () {
  13. //根据Tag找到玩家飞机对象
  14. player = GameObject.FindGameObjectWithTag("Player");
  15. }
  16. void Update () {
  17. //移动子弹
  18. transform.Translate(Vector3.up * Time.deltaTime * m_speed);
  19. }
  20. void OnTriggerEnter2D(Collider2D mCollider)
  21. {
  22. //如果碰撞的是敌人
  23. if (mCollider.gameObject.tag == "Enemy")
  24. {
  25. //敌人减血
  26. mCollider.gameObject.GetComponent<Enemy>().Hit(power);
  27. //得分
  28. player.GetComponent<Player>().Add(100);
  29. //销毁子弹
  30. Destroy(this.gameObject);
  31. }
  32. }
  33. //当离开摄像机范围时触发销毁事件
  34. void OnBecameInvisible()
  35. {
  36. Destroy(this.gameObject);
  37. }
  38. }
期间犯了个非常2的错误就是将OnTriggerEnter2D写成了OnTriggerEnter导致一直没有碰撞,我竟然忘记我建的是2d项目了,函数名改了也不知道,查了些资料终于解决了,不仔细啊。

好了,通过以上的代码我们就可以按键盘的方向键移动飞机,按空格键发射子弹了,我已经等不及要打敌人了。

 3.创建敌机
敌机也是先拖入敌机图片,然后绑定脚本,添加组件,然后保存为预设,我们以后还有个敌机生产器要生产敌机呢。
我创建了三种敌机预设

敌机主要是移动,碰撞。下面来看看敌机脚本:

  1. using UnityEngine;
  2. using System.Collections;
  3. public class Enemy : MonoBehaviour {
  4. //敌机移动速度
  5. public float m_speed = 3;
  6. //生命值
  7. public int max_life = 5;
  8. //得到爆炸动画
  9. private Animator animator;
  10. //爆炸声音
  11. private AudioSource audio;
  12. void Start () {
  13. animator = GetComponent<Animator>();
  14. audio = GetComponent<AudioSource>();
  15. }
  16. void Update () {
  17. transform.Translate(Vector3.down * Time.deltaTime * m_speed);
  18. }
  19. void OnTriggerEnter2D(Collider2D mCollider)
  20. {
  21. //敌机与主机碰撞双方掉血
  22. if (mCollider.gameObject.tag == "Player")
  23. {
  24. //敌机掉血
  25. this.Hit(1);
  26. //主机掉血
  27. mCollider.gameObject.GetComponent<Player>().Hit(1);
  28. }
  29. }
  30. //减血
  31. public void Hit(int value)
  32. {
  33. //如果生命值大于0
  34. if (max_life > 0)
  35. {
  36. //生命值降低
  37. max_life -= value;
  38. }
  39. //如果等于0,则播放动画
  40. else
  41. {
  42. audio.Play();
  43. animator.SetBool("isLive", false);
  44. AnimatorStateInfo animatorState = animator.GetCurrentAnimatorStateInfo(0);
  45. //销毁敌机
  46. if (animatorState.IsName("Base Layer.explosion"))
  47. {
  48. Destroy(this.gameObject);
  49. }
  50. }
  51. }
  52. //离开摄像机视野时销毁对象
  53. void OnBecameInvisible()
  54. {
  55. Destroy(this.gameObject);
  56. }
  57. }
上面使用到了一个动画,就是敌机爆炸时的动画。那么如何创建动画呢?首先资源中可以拖动一组连续的爆炸图片到场景中,系统会自动提醒创建动画,命名为explosion即可。然后Project视图中就出现了一个animation和一个animator。在菜单栏找到Windows -> Animation和 Winodws -> Animator可以打开如下窗口。


具体的动画编辑可以看看雨松MOMO的关于动画的文章.
下面是敌机生产器,在主界面的左右两边的顶部分别放上两个空物体用来创建敌机。敌机创建时间为1~3秒不等,然后绑定创建脚本即可。

  1. using UnityEngine;
  2. using System.Collections;
  3. public class SpawnEnemy : MonoBehaviour {
  4. //生成敌人速度
  5. public float spawnTime = 1.0f;
  6. //敌人对象数组
  7. public GameObject[] enemys;
  8. void Start () {
  9. StartCoroutine("spawn");
  10. }
  11. void Update()
  12. {
  13. //生成敌人速度在1~3秒之间变化
  14. spawnTime = Random.Range(1.0f, 3.0f);
  15. }
  16. IEnumerator spawn()
  17. {
  18. //等待
  19. yield return new WaitForSeconds(spawnTime);
  20. //克隆对象
  21. Instantiate(enemys[Random.Range(0, 3)], new Vector3(transform.position.x * Random.Range(-1.2f, 1.2f), transform.position.y, 0), Quaternion.Euler(0, 0, 0));
  22. StartCoroutine("spawn");
  23. }
  24. }

  4.关于碰撞检测

 子弹:
  1. void OnTriggerEnter2D(Collider2D mCollider)
  2. {
  3. //如果碰撞的是敌人
  4. if (mCollider.gameObject.tag == "Enemy")
  5. {
  6. //敌人减血
  7. mCollider.gameObject.GetComponent<Enemy>().Hit(power);
  8. //得分
  9. player.GetComponent<Player>().Add(100);
  10. //销毁子弹
  11. Destroy(this.gameObject);
  12. }
  13. }
 敌机:

  1. void OnTriggerEnter2D(Collider2D mCollider)
  2. {
  3. //敌机与主机碰撞双方掉血
  4. if (mCollider.gameObject.tag == "Player")
  5. {
  6. //敌机掉血
  7. this.Hit(1);
  8. //主机掉血
  9. mCollider.gameObject.GetComponent<Player>().Hit(1);
  10. }
  11. }
碰撞检测需要添加2d刚体组件和2d碰撞器组件,在Physics 2D中,不要选错了。关于碰撞检测的比较可以看看我的这篇文章【Unity3D游戏开发】—— 碰撞检测。
最后就运行一下感受一下打飞机的快感吧(遮面)

基本上这个一个小游戏也就完成了,关于其他的一些功能可以随便加嘛,多几个关卡就多创建几个场景,还能加上BOSS战什么的。