zoukankan      html  css  js  c++  java
  • [Unity3D]Unity3D游戏开发之飞机大战项目解说

            大家好,我是秦元培,欢迎大家继续关注我的博客,我的博客地址是blog.csdn.net/qinyuanpei

            首先感谢大家对我博客的关注,今天我想和大家分享的是一个飞机大战的项目。这是一个比較综合的项目,希望对大家学习Unity3D有所帮助,我会在文章最后给出项目代码。

    作为一个游戏而言。游戏策划十分重要,所以在開始今天的文章之前,我们先来了解下这个项目的策划。

    我们的玩家是一个飞机。玩家能够使用A、D、S、W四个键位来控制飞机位置,当按下空格键时,我方飞机能够向敌机发射炮弹。当敌机中弹后将降低生命值。当敌机生命值为0时,敌机将爆炸销毁。在游戏场景中仅仅有一种从屏幕上方不断向下飞行的敌机。当我方飞机与敌机碰撞后,两方都将降低生命值。当我方生命值降低至0时。游戏将结束。好了。了解完游戏规则设定后,我们就能够開始今天的内容了。

           

        一、游戏场景

          游戏场景我们採用2D的界面。如图。我们创建一个蓝天白云的平面场景。该场景垂直于摄像机并採取正交投影方式。假设对在Unity3D中创建2D场景尚存在疑惑的朋友能够參考文章《[Unity3D]Unity3D游戏开发之《经典打砖块》游戏的实现》《Unity3D游戏开发之使用Unity3D开发2D游戏 (一)》两篇文章。


          我们这里在场景中加入GUIText对象来显示玩家得分等基本信息,脚本定义例如以下:

    using UnityEngine;
    using System.Collections;
    
    public class GameManager : MonoBehaviour {
    	
    	//玩家得分
    	private Transform Grade;
    	//玩家生命
    	private Transform HP;
    	//游戏结束
    	private Transform Text;
    	//玩家
    	private GameObject Player;
    	
    	void Start ()
    	{
    	  //初始化界面
    	  Grade=transform.Find("Grade");
    	  HP=transform.Find("HP");
    	  Text=transform.Find("Text");
    	  Text.guiText.enabled=false;
    	  //获取玩家对象
    	  Player=GameObject.Find("Player");
    	}
    	
    	void Update () 
    	{
    	  if(Player!=null)
    	  {
    	    //更新UI
    	    Grade.guiText.text="得分:"+Player.GetComponent<Player>().Grade.ToString();
    	    HP.guiText.text="生命:"+Player.GetComponent<Player>().MaxHP.ToString();
    	  }
    	  if(HP.guiText.text=="生命:0")
    	  {
    		 Text.guiText.enabled=true;
    		 //马上复活
    	     if(Input.GetKey(KeyCode.Y))
    		 {
    			Application.LoadLevel("Main");	
    		 }
    		 //退出
    		 if(Input.GetKey(KeyCode.N))
    		 {
    			Application.Quit();
    		 }
    	  }
    	}
    }
    


          二、玩家飞机

          玩家飞机的创建和背景的创建时相同的,这里我们不再多说。

    玩家飞机须要完毕移动、发射、碰撞的事件处理。为此我们编写以下的脚本:

    using UnityEngine;
    using System.Collections;
    
    public class Player : MonoBehaviour {
    
        //飞机的移动速度
        public float MoveSpeed;
        //飞机的最大生命值
        public int MaxHP=100;
        //定义子弹对象
        public GameObject Bullet;
        //定义子弹发射位置
        private Transform BulletPosL;
        private Transform BulletPosR;
        
    	[HideInInspector]
    	public int Grade=0;
    	
    	void Start () 
    	{
    	  BulletPosL=this.transform.Find("BulletPosL");
    	  BulletPosR=this.transform.Find("BulletPosR");
    	}
    	
    	void Update () 
    	{
    	  if(Input.GetKey(KeyCode.A))
    	  {
    	     transform.Translate(Vector3.left*Time.deltaTime*(-MoveSpeed));
    	  }
    	  if(Input.GetKey(KeyCode.D))
    	  {
    	     transform.Translate(Vector3.left*Time.deltaTime* MoveSpeed );
    	  }
    	  if(Input.GetKey(KeyCode.W))
    	  {
    	     transform.Translate(Vector3.forward*Time.deltaTime*(-MoveSpeed));
    	  }
    	  if(Input.GetKey(KeyCode.S))
    	  {
    	     transform.Translate(Vector3.forward*Time.deltaTime*MoveSpeed);
    	  }
    	  //按下空格键,发射子弹
    	  if(Input.GetKey(KeyCode.Space))
    	  {
    	     Instantiate(Bullet,BulletPosL.transform.position,Quaternion.Euler(new Vector3(0,1,0)));
    	     Instantiate(Bullet,BulletPosR.transform.position,Quaternion.identity);
    	  }
    	}
    	
    	#region 减血
    	public void Hit(int Value)
    	{
    	   if(MaxHP>0)
    	   {
    	     MaxHP-=Value;
    	   }else
    	   {
    		 Destroy(this.gameObject);
    	   }
    	}
    	#endregion
    	
    	#region 添加分数 
    	public void Add(int Value)
    	{
    		Grade+=Value;
    	}
    	#endregion
    
    }
    

           在这段代码中,Bullet是我们的子弹对象,它从飞机的两个子弹发射位置BulletPosL、BulletPosR发射,向屏幕上方依照一定的速度缓缓移动,当子弹与敌人碰撞时,子弹对象将销毁,同一时候敌人生命值降低。

    Bullet对象相应于我们的一个Prefab。BulletPosL、BulletPosR相应于飞机上的两个位置。如图:


          我们的子弹Bullet是一个绑定了脚本的Capsule。

    它的代码定义例如以下:

    using UnityEngine;
    using System.Collections;
    
    public class Bullet : MonoBehaviour {
    	
    	//定义子弹的移动速度
    	public float MoveSpeed=10F;
    	//定义子弹的销毁时间
    	public float DestroyTime=2.0F;
    	//定义子弹对敌人的伤害值
    	public int Damage=2;
    	//玩家飞机
    	private GameObject Player;
    	
    	void Start()
    	{
    		Player=GameObject.Find("Player");
    	}
    	void Update () 
    	{
    	   //移动子弹
    	   transform.Translate(Vector3.up * MoveSpeed * Time.deltaTime);
    	}
    	
    	//碰撞事件捕捉
    	void OnTriggerEnter(Collider mCollider)
    	{
    		if(mCollider.gameObject.tag=="Enemy")
    		{
    			//敌人减血
    			mCollider.gameObject.GetComponent<Enemy>().Hit(Damage);
    			//我方得分
    			Player.GetComponent<Player>().Add(1);
    			//销毁子弹
    			Destroy(this.gameObject);
    		}
    	}
    
         //当离开摄像机范围时触发销毁事件
    	void OnBecameInvisible()
    	{
    	  Destroy(this.gameObject);
    	}
    }
    

       

       三、敌人飞机

       在我们的游戏中共同拥有三种敌机,我们先将它们制作成预设。

    然后通过敌机生成器不断地生成敌机。

    如图:


         和子弹相反,我们希望敌机从屏幕上方以一定速度向下移动,当碰到玩家飞机或者子弹时,将降低生命值。为此,我们这样定义敌机的脚本:

    using UnityEngine;
    using System.Collections;
    
    public class Enemy : MonoBehaviour {
    
    	//移动速度
    	public float MoveSpeed=1.5F;
    	//爆炸
    	public GameObject Explosion;
    	//最大生命值
    	public int MaxHP=100;
    	
    	
    	void Update () 
    	{
    	  //移动飞机
    	  transform.Translate(Vector3.forward*Time.deltaTime*MoveSpeed);
    	}
    	
    	public void Hit(int Value)
    	{ 
    	  //如血量不低于0。则敌人飞机掉血
    	  if(MaxHP>0)
    	  {	
    	     MaxHP-=Value;
    	  }else
    	  {
    		 //产生爆炸效果
             Instantiate(Explosion,transform.position,Quaternion.Euler(new Vector3(90,180,0)));
    		 //销毁敌机
    		 Destroy(this.gameObject);
    	  }
        }
    	
    	void OnTriggerEnter(Collider mCollider)
    	{
    	  //假设与玩家飞机遭遇。则两方减血
    	  if(mCollider.gameObject.tag=="Player")
    	  {
    		 //敌机掉血
    		 this.Hit(2);
    		 //玩家飞机掉血
    		 Transform mPlayer=mCollider.gameObject.transform.Find("Player");
    		 mPlayer.GetComponent<Player>().Hit(2);
    	  }
    	}
    	
    	
    	void OnBecameInvisible()
    	{
    	  Destroy(this.gameObject);
    	}
    }
    
          接下来。我们通过敌机生成器来不断地生成敌机。

    敌人生成器是我们预制在游戏场景中的空游戏体,它位于游戏场景的顶部。

    我们将以下的脚本绑定到游戏生成器 上,使其能够不断地生成敌人:

    using UnityEngine;
    using System.Collections;
    
    public class SpawnEnemy : MonoBehaviour {
    	
    	//定义敌人速度
    	public float SpawnTime=1.0f;
    	//定义敌人对象数组
    	public GameObject[] Enemys;
    	
    	void Start () 
    	{
    	   StartCoroutine("Spawn");
    	}
    	
    	//通过迭代器生成敌人
    	IEnumerator Spawn()
    	{
    	   //等待
    	   yield return new WaitForSeconds(SpawnTime);
    	   //克隆对象
           Instantiate(Enemys[Random.Range(0,3)],new Vector3(transform.position.x * Random.Range(-1F,1F),
    			transform.position.y,-4),Quaternion.Euler(new Vector3(90,180,0)));  
    	   StartCoroutine("Spawn");
    	}
    	
    }
    
          当中Enemys相应到我们的敌人预设,每隔一段时间,我们随机地产生一种敌人,该敌人将从屏幕上方缓缓向下移动。

          

        四、碰撞检測

        在这个游戏中。主要存在子弹与敌机的碰撞、玩家飞机与敌机的碰撞两种形式。

    它们分别被定义在Bullet.cs和Enemy.cs两个类文件里。

    //碰撞事件捕捉
    	void OnTriggerEnter(Collider mCollider)
    	{
    		if(mCollider.gameObject.tag=="Enemy")
    		{
    			//敌人减血
    			mCollider.gameObject.GetComponent<Enemy>().Hit(Damage);
    			//我方得分
    			Player.GetComponent<Player>().Add(1);
    			//销毁子弹
    			Destroy(this.gameObject);
    		}
    	}
    void OnTriggerEnter(Collider mCollider)
    	{
    	  //假设与玩家飞机遭遇。则两方减血
    	  if(mCollider.gameObject.tag=="Player")
    	  {
    		 //敌机掉血
    		 this.Hit(2);
    		 //玩家飞机掉血
    		 Transform mPlayer=mCollider.gameObject.transform.Find("Player");
    		 mPlayer.GetComponent<Player>().Hit(2);
    	  }
    	}
         

         五、爆炸特效

         当敌机被摧毁时,将显示爆炸特效,我们这里採用一组2D贴图来实现爆炸特效,原理是改变贴图的mainTextureScale和mainTextureOffset两个属性值。我们来一起看代码:

    using UnityEngine;
    using System.Collections;
    
    public class Explosion : MonoBehaviour {
    	
    	//动画序列索引
    	private int index=0;
    	//声音
    	private AudioSource mAudio;
    	
    	void Start()
    	{
    	   mAudio=GetComponent<AudioSource>();
    	}
    	
    	void FixedUpdate () 
    	{
    	   if(index<8)
    	   {
    		 this.renderer.sharedMaterial.mainTextureScale=new Vector2(1.0F/8,1);
    		 this.renderer.sharedMaterial.mainTextureOffset=new Vector2(index * 1.0F/8,0);
    		 index+=1;
    	   }else
    		{
    		  mAudio.Play();
    		  Destroy(this.gameObject);
    		}
    	}
    }
    
         当中mAudio相应到一个AudioSource组件,我们在这里指定一个爆炸的音效。相同地,我们将爆炸制作成预设。该预设相应于Enemy.cs中的Explosion。

         好了。到这里今天的 内容就解说完了,我们一起来看看终于的效果吧!


         希望今天的内容大家能够喜欢。

    学了这么长时间的Unity3D。感慨还是挺多的,非常多东西你不努力去做,是永远做不好的,你不给自己压力,你不会知道自己有多优秀。本项目源码能够从这里下载。


         每日箴言: 无论活到什么岁数,总有太多思索、烦恼与迷惘。一个人假设失去这些。安于现状,才是真正意义上的青春的完结。——  渡边淳一




          喜欢我的博客请记住我的名字:秦元培,我的博客地址是blog.csdn.net/qinyuanpei
          转载请注明出处,本文作者:秦元培,本文出处:http://blog.csdn.net/qinyuanpei/article/details/25158323


  • 相关阅读:
    计算机二级Python
    vivado三人表决仿真
    verilog设计加法器
    超前进位加法器
    OO第二单元总结
    OO第一单元总结
    第一次阅读作业
    安卓计算器
    安卓第四周作业
    第十四周作业
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/5064789.html
Copyright © 2011-2022 走看看