日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

3Dunity游戏项目实战——飞机大战

發布時間:2023/12/29 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 3Dunity游戏项目实战——飞机大战 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

代碼及游戲資料

一、游戲策劃

1、游戲介紹

??游戲背景是在火星的上空,主角和敵人是不同的太空飛行器,敵人迎面向主角飛來,主角通過射擊消滅敵人來獲得分數。如果主角戰敗,則游戲結束。

2、游戲UI

??屏幕上顯示主角生命值以及得分。如果游戲結束,屏幕上顯示“游戲結束“,同時顯示“再來一次”按鈕。按ESC鍵,游戲會處于暫停狀態,顯示“繼續游戲”,“退出游戲”。

3、主角

??主角有三條性命,被敵人撞擊一次性命直接清零,被敵方子彈命中,性命減一,當性命值為0時,游戲結束。

4、操作

??游戲在pc上進行開發,鍵盤上的上下左右鍵控制角色在相應位置上移動。空格鍵和鼠標左鍵控制發射子彈。

5、敵人

??敵人分為兩類:初級敵人,裝甲較弱,以撞擊主角為主;高級敵人,裝甲較強,可以發射子彈,也可以撞擊主角。

二、代碼分析

1、創建地圖

  • 在Scene中創建一個3D的Plane對象,用星空的圖像作為背景
  • 另外創建一個3D對象,用火星的圖像貼圖
  • 為星空的Plane對象添加動畫效果,使在太空的背景更加逼真。
  • 在地圖的周圍設置空對象,當敵人走出地圖時,要及時銷毀對象,節省內存。

2、創建主角和子彈

  • 創建主角的Object對象,并貼圖
  • 創建子彈的Object對象,并貼圖。這里由于子彈是可重復使用對象,于是將其變為profeb預設對象,只要將Scene中創建好的對象拖進Project相應文件夾中即可。
  • 為場景中的對象添加相關tag,并在對象中指定tag名
  • 為主角添加碰撞容器,并在腳本里實現碰撞效果
  • 為主角添加Audio source容器,這樣才能有聲音,并在腳本中添加開槍聲音以及爆炸特效。
  • 為主角和子彈創建相應腳本,指定腳本中的Transform對象
// Palyer.csusing System.Collections; using System.Collections.Generic; using UnityEngine;[AddComponentMenu("MyGame/Player")] public class Player : MonoBehaviour {public float m_life = 3;//主角共3條命public float m_speed = 3; //控制主角移動速度float m_rocketRate = 0.3f; //控制子彈發射頻率private float m_rocketspeed = 0;public Transform m_rocket; protected Transform m_transform;public AudioClip m_shootClip; //聲音protected AudioSource m_audio; //聲音源public Transform m_explosionFX; //爆炸特效public Transform m_explosionFX2; //爆炸特效// Start is called before the first frame updatevoid Start(){m_transform = this.transform;m_audio = this.GetComponent<AudioSource>();}private void OnTriggerEnter(Collider other){if (other.tag.CompareTo("EnemyRocket") == 0) //碰到敵人的子彈,生命值減一{m_life -= 1;//主角掉血反饋Instantiate(m_explosionFX2, m_transform.position, Quaternion.identity);if (m_life <= 0){//主角死亡爆炸特效Instantiate(m_explosionFX, m_transform.position, Quaternion.identity);Destroy(this.gameObject);}}if (other.tag.CompareTo("Enemy") == 0) //碰到敵人,生命值清零并銷毀{m_life = 0;//主角死亡爆炸特效Instantiate(m_explosionFX, m_transform.position, Quaternion.identity);Destroy(this.gameObject);}}// Update is called once per framevoid Update(){float moveV = 0; //縱向距離float moveH = 0; //橫向距離if (Input.GetKey(KeyCode.DownArrow)){moveV += m_speed * Time.deltaTime;}if (Input.GetKey(KeyCode.UpArrow)){moveV -= m_speed * Time.deltaTime;}if (Input.GetKey(KeyCode.RightArrow)){moveH -= m_speed * Time.deltaTime;}if (Input.GetKey(KeyCode.LeftArrow)){moveH += m_speed * Time.deltaTime;}m_rocketspeed -= Time.deltaTime;if (m_rocketspeed <= 0){m_rocketspeed = m_rocketRate;if (Input.GetKey(KeyCode.Space) || Input.GetMouseButton(0)){Instantiate(m_rocket, new Vector3(m_transform.position.x,m_transform.position.y,m_transform.position.z + 0.5f), m_transform.rotation);m_audio.PlayOneShot(m_shootClip);}//移動}m_transform.Translate(new Vector3(moveH, 0, moveV));} } //Rocket.cs using System.Collections; using System.Collections.Generic; using UnityEngine;[AddComponentMenu("MyGame/Rocket")] public class Rocket : MonoBehaviour {public float m_speed = 10; //設置子彈速度public float m_liveTime = 1; //設置子彈生存時間public float m_power = 1; //設置子彈威力protected Transform m_transform;// Start is called before the first frame updatevoid Start(){m_transform = this.transform;}private void OnTriggerEnter(Collider other){if(other.tag.CompareTo("Enemy") == 0){Destroy(this.gameObject);}}// Update is called once per framevoid Update(){m_liveTime -= Time.deltaTime;if (m_liveTime <= 0)Destroy(this.gameObject);m_transform.Translate(new Vector3(0, 0, -m_speed * Time.deltaTime));} } //Explosion.cs using System.Collections; using System.Collections.Generic; using UnityEngine;[AddComponentMenu("MyGame/Explosion")] public class Explosion : MonoBehaviour {public float m_life = 2;// Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){m_life -= Time.deltaTime;if(m_life <= 0){m_life = 2;Destroy(this.gameObject);}} }

3、創建敵人

  • 分別創建普通敵人和高級敵人的object對象,高級敵人可以繼承普通敵人
  • 為敵人添加tag以及以下容器,并設定相應值,高級敵人還要在腳本容器里設置子彈的預設對象。

  • 創鍵敵人腳本
// Enemy.cs using System.Collections; using System.Collections.Generic; using UnityEngine;[AddComponentMenu("MyGame/Enemy")] public class Enemy : MonoBehaviour {public float e_life = 20;//敵人的生命值public float m_speed = 1; //敵人的移動速度public float m_rotSpeed = 30; //旋轉速度protected float m_timer = 1.5f; //變向間隔時間public int m_point = 10; //消滅一個敵人獲得的分數public Transform m_explosionFX; //爆炸特效protected Transform m_transform;// Start is called before the first frame updatevoid Start(){m_transform = this.transform;}// Update is called once per framevoid Update(){ updataMove();}private void OnTriggerEnter(Collider other){if (other.tag.CompareTo("PlayerRocket") == 0) //如果碰到玩家子彈{Rocket rocket = other.GetComponent<Rocket>(); //獲取Rocket 的腳本Componentif (rocket != null){e_life -= rocket.m_power;if (e_life <= 0){//敵人死亡時爆炸特效//Quaternion.identity,該四元數對應于“no rotation”- 對象與世界軸或父軸完全對齊Instantiate(m_explosionFX, m_transform.position, Quaternion.identity); Destroy(this.gameObject);GameManager.instance.AddScore(m_point); //給主角加分}}}if(other.tag.CompareTo("bound") == 0) //敵人飛出屏幕后自動銷毀{e_life = 0;Destroy(this.gameObject);}}virtual protected void updataMove(){m_timer -= Time.deltaTime;if(m_timer <= 0){m_timer = 3; //每間隔3改變一次旋轉的方向m_rotSpeed = -m_rotSpeed;}//Rotate()函數會一直旋轉,參數一表示軸,參數二表示旋轉角度,參數三表示旋轉參考系m_transform.Rotate(Vector3.up, m_rotSpeed * Time.deltaTime, Space.World);//旋轉方向m_transform.Translate(new Vector3(0, 0, -m_speed * Time.deltaTime)); //前進} } //SuperEnemy.cs using System.Collections; using System.Collections.Generic; using UnityEngine;[AddComponentMenu("MyGame/SuperEnemy")] public class SuperEnemy : Enemy {public Transform m_rocket;protected float m_fireTime = 2;protected Transform m_player;void Awake() //在游戲全體實例化時執行一次,并先于stat 方法{GameObject obj = GameObject.FindGameObjectWithTag("player");if (obj != null){m_player = obj.transform;}}// Start is called before the first frame updateprotected override void updataMove(){m_fireTime -= Time.deltaTime;if(m_fireTime <= 0){m_fireTime = 2;if(m_player != null){Vector3 relativePos = m_transform.position - m_player.position;Instantiate(m_rocket, m_transform.position, Quaternion.LookRotation(relativePos));}}//前進m_transform.Translate(new Vector3(0, 0, -m_speed * Time.deltaTime));}private void OnTriggerEnter(Collider other){if (other.tag.CompareTo("PlayerRocket") == 0) //如果碰到玩家子彈{Rocket rocket = other.GetComponent<Rocket>(); //獲取Rocket 的腳本Componentif (rocket != null){e_life -= rocket.m_power;if (e_life <= 0){//敵人死亡時爆炸特效Instantiate(m_explosionFX, m_transform.position, Quaternion.identity);Destroy(this.gameObject);GameManager.instance.AddScore(m_point); //給主角加分}}}if (other.tag.CompareTo("bound") == 0) //敵人飛出屏幕后自動銷毀{e_life = 0;Destroy(this.gameObject);}} }

4、創建敵人生成器

  • 在地圖的上方的指定地點,放置幾個空對象,用于生成敵人
  • 敵人生成器有兩種類型,分別生成不同類型的敵人,需要在腳本容器中指定敵人
  • 為敵人生成器創建腳本
// EnemySpawn.cs using System.Collections; using System.Collections.Generic; using UnityEngine;[AddComponentMenu("MyGame/EnemySpawn")] public class EnemySpawn : MonoBehaviour {public Transform m_enemy; //敵人的prefabpublic float m_timer = 5; //生成敵人的間隔時間protected Transform m_transform;// Start is called before the first frame updatevoid Start(){m_transform = this.transform;}// Update is called once per framevoid Update(){m_timer -= Time.deltaTime;if (m_timer <= 0){m_timer = 5 + Random.value * 15.0f; //產生5 - 15之間的隨機數// Quaternion.identity就是指Quaternion(0,0,0,0)Instantiate(m_enemy, m_transform.position, Quaternion.identity);}}//用一幅圖填充空對象,在控制臺方便知道生成器的位置,游戲中看不到void OnDrawGizmos(){Gizmos.DrawIcon(transform.position, "item.png", true);} }

5、創建游戲管理器

游戲管理器是一個空對象,有且只能有一個,用于控制游戲界面,以及控制游戲開始和退出。

  • 創建一個空對象,命名為GameManager,為其添加腳本
  • 為其添加Audio Source容器,并在腳本容器中指定背景音樂文件
// GameManager.csusing System.Collections; using System.Collections.Generic; using UnityEngine;[AddComponentMenu("MyGame/GameManager")] public class GameManager : MonoBehaviour {public static GameManager instance;public float m_score = 0;public static int m_hiscore = 0;public AudioClip m_musicClip; //指定音樂片段protected Player m_player;protected AudioSource m_audio;private void Awake(){instance = this;}// Start is called before the first frame updatevoid Start(){m_audio = this.GetComponent<AudioSource>();//獲取主角GameObject obj = GameObject.FindGameObjectWithTag("player");if(obj != null){m_player = obj.GetComponent<Player>();}}// Update is called once per framevoid Update(){//循環播放背景音樂if (!m_audio.isPlaying){m_audio.clip = m_musicClip;m_audio.Play();}//暫停游戲if(Time.timeScale > 0 && Input.GetKeyDown(KeyCode.Escape)){Time.timeScale = 0;}}[System.Obsolete]private void OnGUI(){//暫停游戲if(Time.timeScale == 0){//繼續游戲按鈕if(GUI.Button(new Rect(Screen.width * 0.5f -50,Screen.height * 0.4f, 100, 30), "繼續游戲")){Time.timeScale = 1;}//退出游戲按鈕if (GUI.Button(new Rect(Screen.width * 0.5f - 50, Screen.height * 0.6f, 100, 30), "退出游戲")){Application.Quit(); //只有當工程打包編譯后的程序使用Application.Quit()才奏效}}int life = 0;if(m_player != null){life = (int)m_player.m_life; //獲取主角的生命值}else //主角被銷毀,即游戲失敗{//放大字體GUI.skin.label.fontSize = 50;//顯示游戲失敗GUI.skin.label.alignment = TextAnchor.LowerCenter;GUI.Label(new Rect(0, Screen.height * 0.2f, Screen.width, 60), "游戲失敗");GUI.skin.label.fontSize = 20;//顯示再來一次按鈕if(GUI.Button(new Rect(Screen.width * 0.5f - 50, Screen.height * 0.5f, 100, 30), "再來一次")){//讀取當前關卡Application.LoadLevel(Application.loadedLevelName);}}GUI.skin.label.fontSize = 15;//顯示主角生命GUI.Label(new Rect(5, 5, 100, 30), "裝甲:" + life);//顯示最高分GUI.skin.label.alignment = TextAnchor.LowerCenter;GUI.Label(new Rect(0, 5, Screen.width, 30), "最高分:" + m_hiscore);//顯示當前得分GUI.Label(new Rect(0, 25, Screen.width, 30), "得分:" + m_score);}public void AddScore(int point){m_score += point;// 更高分記錄if(m_hiscore < m_score){m_hiscore = (int)m_score;}} }

6、創建游戲開始標題

這里游戲基本已經完成,現在需要創建一個開始的標題Scene,然后點擊“開始游戲”跳轉到當前的level1。

  • 創建一個新的Scene,保存為start
  • 在這個start中創建一個攝像機和一個UI->RowImage對象,用圖片填充,布置好游戲一開始的畫面
  • 為攝像機添加一個腳本文件
//TitleSceen.csusing System.Collections; using System.Collections.Generic; using UnityEngine;[AddComponentMenu("MyGame/TitleScreen")] public class TitleSceen : MonoBehaviour {// Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){}[System.Obsolete]private void OnGUI(){GUI.skin.label.fontSize = 48;GUI.skin.label.alignment = TextAnchor.LowerCenter; //UI中心對齊GUI.Label(new Rect(0, 30, Screen.width, 100), "太空大戰");//開始游戲按鈕if (GUI.Button(new Rect(Screen.width * 0.5f - 100, Screen.height * 0.7f, 200, 30), "開始游戲")){Application.LoadLevel("level1");}} }

三、游戲編譯發布

設置游戲圖標,以及相應的一些參數。不懂就用默認。

編譯時必須把兩個Scene全勾上,并調整順序。

代碼及游戲資料

總結

以上是生活随笔為你收集整理的3Dunity游戏项目实战——飞机大战的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。