关于Unity的入门游戏飞机大战的开发(上)
每個組件都是一個類的實例,要獲得某個組件,要先創建一個同類型的組件類實例,然后把實例傳引用過去,就可以對想要的組件實例進行操作。
做游戲一般創建一個邏輯節點,里面只管邏輯,再創建一個動畫節點,里面有好多動畫節點。一般我們把邏輯節點作為動畫節點的父節點。
?
?
開發步驟:
1: 搭建unity項目工程;
2: 資源整理好;
3: 配置好我們的canvas;
4: 做一個開始界面;
5: 做一個總的游戲的控制腳本game_scene;
6: 點擊開始按鈕,讓這個開始界面消失;
7: 讓這個飛行射擊類游戲背景滾動起來;
8: 創建一個飛機,能讓它被自由的移動和拖動;
9: 創建一個子彈,能夠在物理引擎的控制下發射出去;
10: 產生一個預制體,讓這個飛機不斷的射擊;
11: 修改開始,讓玩家獲得開始消息;
?
?
步驟一和步驟二>>>>>>搭建unity項目工程>>>>>>資源整理好
1.創建一個2D的Unity項目
2.創建好scenes,resources,scripts文件夾
3.在resources文件夾下再創建一個tex文件夾
4.把要用到的圖片資源放進tex文件夾中
5.保存場景到scenes文件夾
?
?
步驟三>>>>>>配置好我們的canvas
1.創建一個Canvas節點
2.把Canvas節點的Canvas組件中的Render Mode設置為Screen Space-Camera,并把Main Camera節點拖進Render Camera屬性
3.把Canvas節點的Canvas Scaler組件的UI Scale Mode設置為Scale With Screen Size,并把Refernces Resultion設置為和Game視圖分辨率一樣的640X960
4.創建兩個空節點game_root和menu_root作為Canvas節點的子節點,game_root是用來放游戲的節點,menu_root是用來放菜單的節點。由于還沒有講場景跳轉,所以這里需要這兩個節點。
?
?
步驟四>>>>>>做一個開始界面
1.給menu_root創建一個叫menu_bg的Image子節點,把背景拖進去,set native size。
2.給menu_root創建一個叫start_button的button子節點,,把按鈕貼紙拖進去,set native size,把它自帶的Text子節點刪除。
?
?
步驟五>>>>>>做一個總的游戲的控制腳本game_scene
1.創建一個叫game_scene的腳本掛載在Canvas下面作為游戲總控制的腳本。
?
?
步驟六>>>>>>點擊開始按鈕,讓這個開始界面消失
1.打開game_scene腳本,編寫一個游戲開始函數,on_game_start_click(){}
using UnityEngine; using System.Collections;public class game_scene : MonoBehaviour {//設置一個開始游戲的標志bool is_started = false;// Use this for initializationvoid Start () {}//刪除菜單節點函數 private void delete_menu() {MonoBehaviour.Destroy(GameObject.Find("Canvas/menu_root"));}//游戲開始按鈕點擊,菜單按鈕點擊后的響應函數,記得要設置為public權限才能關聯按鈕public void on_game_start_click() {//防止重復點擊 if (this.is_started) {return;}this.is_started = true;//執行一個定時器(自帶的),讓刪除節點的函數過一會再執行,過渡效果this.Invoke("delete_menu", 0.2f); }// Update is called once per framevoid Update () {} }
2.寫好按鈕事件函數后,可以直接在Inspector視圖里面關聯相應的按鈕,就是在按鈕的屬性視圖的最下面。
?
?
步驟七>>>>>>讓這個飛行射擊類游戲背景滾動起來
1.先把menu_root節點隱藏起來,像ps里面的把眼睛關掉
2. 給game_root創建一個叫sky的Raw Image子節點(有UVRect屬性,只有它才能動態修改紋理坐標),,用來做游戲地圖滾動背景。再把sky的貼圖屬性改成Texture(只有這種模式才能repeat紋理),我這個版本沒有Texture屬性,只有一個Default屬性,兩者效果一樣的。再把Wrap Mode改成repeat,最后Apply。
3.把背景地圖拖進sky節點的貼圖屬性,set native size。設置大小(512X1024)和縮放比例(X:1.25 Y:1.25),只要覆蓋Canvas節點就行,沒必要太大,影響性能。
4.創建一個叫sky的腳本掛載在sky下面,用來實現地圖滾動效果。
5.打開sky腳本,主要是拿到Raw Image組件,并且拿到UVRect屬性,進行動態修改地圖紋理坐標移動,又因為Repeat的特效,會讓地圖一直重復。
using UnityEngine; using System.Collections; using UnityEngine.UI;public class sky : MonoBehaviour {//背景圖片移動的速度設置public float speed = 0.1f;//創建一個RawImage用來操作組件實例private RawImage img;// Use this for initializationvoid Start () {this.img = this.GetComponent<RawImage>();}// Update is called once per framevoid Update () {float sy = this.speed * Time.deltaTime;Rect uvrect = this.img.uvRect;//不是傳引用uvrect.y += sy;this.img.uvRect = uvrect;} }?
?
步驟八>>>>>>創建一個飛機,能讓它被自由的移動和拖動
1.給game_root創建一個叫plane的空子節點,在plane節點下面創建一個叫anim的Image類型的動畫子節點。
2.把飛機貼圖拖進anim節點,set native size,節點大小設置大一點,讓飛機大一點。
3.創建一個叫plane的腳本掛載在plane節點下面,用來實現飛機被鼠標自由的移動和拖動的效果。
4..打開plane腳本,先實現飛機被鼠標自由的移動和拖動;的效果
using UnityEngine; using System.Collections;public class plane : MonoBehaviour {//飛機隨著鼠標運動需要定義飛機坐標和鼠標坐標Vector3 start_plane_pos; // 按鈕按下的時候飛機的起始坐標Vector3 start_mouse_pos; // 鼠標的起始坐標;// Use this for initializationvoid Start () {}//這里有一個問題就是鼠標不按在飛機上,飛機也會跟著移動,這是還沒有處理碰撞的原因,后面會改//屏幕坐標轉世界坐標我的理解是把攝像機拍的二維平面坐標,也就是我們鼠標點擊的那個坐標,轉化為三維世界的坐標,三維世界的坐標才能做一些動作。// 響應我們的鼠標事件,GetMouseButton(0)// Update is called once per framevoid Update () {if (Input.GetMouseButtonDown(0)) { // 鼠標按下的情況// 世界坐標來記錄// 記錄一下當前鼠標的位置,獲得鼠標的初始點擊位置this.start_mouse_pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);// 記錄一下當前我們飛機的位置,獲得飛機的初始位置this.start_plane_pos = this.transform.position;}else if (Input.GetMouseButton(0)) { // 鼠標在滑動的情況Vector3 w_pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);Vector3 offset = w_pos - this.start_mouse_pos;//獲得偏移量this.transform.position = this.start_plane_pos + offset;//設置飛機偏移后的位置 }} }5.修改
上次說過,這里有一個問題就是鼠標不按在飛機上,也可以移動飛機,這是因為沒有在鼠標控制飛機前判斷鼠標是否點在飛機上,所以這里的代碼修改如下
打開plane腳本
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI;public class plane : MonoBehaviour {//飛機隨著鼠標運動需要定義飛機坐標和鼠標坐標 Vector3 start_plane_pos;Vector3 start_mouse_pos;//-----修改-----private bool is_touch = false;//是否點到飛機// Use this for initializationvoid Start () {}// Update is called once per framevoid Update () {//鼠標按下的情況if(Input.GetMouseButtonDown(0)){//-----修改-----this.is_touch = false;//每次鼠標點下去,不管有沒有點到飛機,初始化為沒點到Ray myRay = Camera.main.ScreenPointToRay(Input.mousePosition);//從攝像機發出一條射線RaycastHit2D hit = Physics2D.Raycast(new Vector2(myRay.origin.x, myRay.origin.y), Vector2.zero);//射線從鼠標點擊屏幕的那個點出發,射到以當前點擊位置為原點的坐標系中的垂直于(0,0)的位置,//如果從3D的視角看就是攝像機的射線垂直射到Canvas上if (hit.collider)//如果碰到有Collider2D組件的物體,就做一些事情 {if (hit.transform.gameObject.name == "plane")//如果碰到的是飛機 {//Debug.Log(hit.transform.name);//打印出碰撞到的節點的名字this.is_touch = true;//點到飛機 }} if (is_touch)//如果點到飛機 {//獲得鼠標的初始點擊位置this.start_mouse_pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);//獲得飛機的初始位置this.start_plane_pos = this.transform.position;}}//鼠標滑動的情況else if (Input.GetMouseButton(0) && this.is_touch){Vector3 w_pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);//獲得偏移量Vector3 offset = w_pos - this.start_mouse_pos;//設置飛機偏移后的位置this.transform.position = this.start_plane_pos + offset;}} }?
?
步驟九>>>>>>創建一個子彈,能夠在物理引擎的控制下發射出去
1.給game_root創建一個叫bullet_root的空子節點,在bullet_root節點下面創建一個叫plane_bullet的Image類型的子節點,Hierarchy視圖中把bullet_root節點移動到plane節點的上面,這樣子彈不會跑到飛機上面去。
2.把plane_bullet節點的大小設置為width:10,height:14,顏色為紅色。
3.準備要給子彈添加剛體組件和碰撞形狀組件,所以要先進行物理引擎設置edit --> ProjectSetting -->Physices 2D;設置重力為0
4.給子彈添加Rigidbody 2D剛體組件,打鉤Freeze Rotation,不然子彈在碰撞過程中旋轉。又因為子彈的碰撞是連續的(比較特殊),所以Collision Detection設置為Continuous
5.給子彈添加碰撞形狀檢測器組件,設置碰撞檢測器的大小,再在物理引擎設置器中設置碰撞檢測器的邊界框的顏色,再打鉤always show coll總是顯示邊界框。
6.創建一個叫plane_bullet的腳本掛載在plane_bullet節點下面,用來實現子彈飛行和飛出半個屏幕后消失的效果。
using UnityEngine; using System.Collections;public class plane_bullet : MonoBehaviour {//設置子彈的速度public float speed = 8; // 子彈的飛行速度//什么時候刪除我們的子彈,因為設計分辨率是640X960,但是如果改變了分辨率,//就不會還是半個屏幕的時候子彈消失,所以要轉換設計分辨率的屏幕的高成具體的分辨率高,//有一個scale比例,轉換完再乘0.5f就可以取一半屏幕高private float dead_line_y;
Rigidbody2D body;// Use this for initializationvoid Start () {this.body = this.GetComponent<Rigidbody2D>();Vector2 v = new Vector2(0, this.speed);//剛體的運動會帶動與它相連接的整個節點的運動this.body.velocity = v;float scale = 640.0f / (float)Screen.width;this.dead_line_y = Screen.height * scale * 0.5f;//Debug.Log("this.dead_line_y: " + this.dead_line_y); }// Update is called once per framevoid Update () {// 找準已給時機來刪除我們的子彈;這里原點是屏幕中心,所以只要超過一半屏幕的高度就刪除子彈。if (this.transform.localPosition.y >= this.dead_line_y) {MonoBehaviour.Destroy(this.gameObject);}} }
?
?
步驟十>>>>>>產生一個預制體,讓這個飛機不斷的射擊
1.為了飛機不斷地射擊,不斷地產生子彈,需要把子彈變成預制體,就是把剛才設計的子彈變成一個模板,后面可以不斷地用這個模板生成子彈。
2.在Resources文件夾下面創建一個prefabs文件夾,里面存放子彈預制體,也就是直接把plane_bullet節點拖動到prefabs文件夾下面,原節點名字變藍。
3.打開飛機節點下的plane腳本,里面添加讓飛機不斷通過子彈預制體產生子彈的實現代碼
要添加三個public的Inspector視圖屬性,一個放預制體,一個放目標父節點,也就是生成的一大堆子彈等下放在哪里,一個是子彈發射的頻率,這里分別拖進plane_bullet和bullet_root和自定義頻率數值。
4.打開plane腳本
using UnityEngine; using System.Collections;public class plane : MonoBehaviour {//飛機隨著鼠標運動需要定義飛機坐標和鼠標坐標Vector3 start_plane_pos; // 按鈕按下的時候飛機的開始的坐標Vector3 start_mouse_pos; // 鼠標開始的坐標;//子彈預制體public GameObject bullet_prefab;//預制體子彈節點public Transform bullet_root;//預制體子彈節點的父節點public float shoot_rate = 0.2f; // 子彈發射的頻率;我感覺是一個時間間隔,設定的子彈發射時間間隔private float shoot_time = 0.0f; // 距離上一次發射過去的時間private bool is_shooting = false;//是否處于發射子彈的狀態//-----優化-----private bool is_touch = false;//是否點到飛機// Use this for initializationvoid Start(){}void shoot_bullet(){//使用預制體生成一顆子彈GameObject bullet = GameObject.Instantiate(this.bullet_prefab);// 注意這個參數要使用false,和Canvas的實現機制有關,false意思是不用世界坐標bullet.transform.SetParent(this.bullet_root, false);//使用localPosition是因為子彈和plane都有相同的父節點,兩者之間是相對坐標 Vector3 offset = new Vector3(0, 64, 0);//之所以用localPosition是因為子彈和飛機都是同一個父節點的子節點bullet.transform.localPosition = this.transform.localPosition + offset;}// 響應我們的鼠標事件,GetMouseButton(0)void Update(){//鼠標按下的情況if (Input.GetMouseButtonDown(0)){//-----修改-----this.is_touch = false;//每次鼠標點下去,不管有沒有點到飛機,初始化為沒點到Ray myRay = Camera.main.ScreenPointToRay(Input.mousePosition);//從攝像機發出一條射線RaycastHit2D hit = Physics2D.Raycast(new Vector2(myRay.origin.x, myRay.origin.y), Vector2.zero);//射線從鼠標點擊屏幕的那個點出發,射到以當前點擊位置為原點的坐標系中的垂直于(0,0)的位置,//如果從3D的視角看就是攝像機的射線垂直射到Canvas上if (hit.collider)//如果碰到有Collider2D組件的物體,就做一些事情 {if (hit.transform.gameObject.name == "plane")//如果碰到的是飛機 {//Debug.Log(hit.transform.name);//打印出碰撞到的節點的名字this.is_touch = true;//點到飛機 }}if (is_touch)//如果點到飛機 {//獲得鼠標的初始點擊位置this.start_mouse_pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);//獲得飛機的初始位置this.start_plane_pos = this.transform.position;}}//鼠標滑動的情況else if (Input.GetMouseButton(0) && this.is_touch){Vector3 w_pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);//獲得偏移量Vector3 offset = w_pos - this.start_mouse_pos;//設置飛機偏移后的位置this.transform.position = this.start_plane_pos + offset;}// 子彈發射邏輯控制,update里面嵌套自定義的update,自定義刷新函數this.shoot_update(Time.deltaTime);}void shoot_update(float dt){if (!this.is_shooting){return;}this.shoot_time += dt;if (this.shoot_time < this.shoot_rate){return;}this.shoot_time = 0;this.shoot_bullet();} }5.然后可以把愿來Hierarchy視圖里面藍色名字的子彈節點plane_bullet刪除
?
?
步驟十一>>>>>>修改開始,讓玩家獲得開始消息
1.給總的游戲控制腳本game_scene添加游戲開始的代碼,就是點擊按鈕后觸發游戲開始,飛機開始發射子彈。
2.打開game_scene腳本
using UnityEngine; using System.Collections;public class game_scene : MonoBehaviour {//設置一個開始游戲的標志bool is_started = false; //定義plane腳本,為了等一下執行里面的start_game方法,這個方法可以讓子彈開始發射private plane player_ctrl;// Use this for initializationvoid Start () {//獲得plane腳本this.player_ctrl = this.transform.Find("game_root/plane").GetComponent<plane>();}//執行plane腳本里面的start_game函數開始發射子彈private void game_realy_started() {this.player_ctrl.start_game();//開始發射子彈 }//刪除菜單節點函數private void delete_menu() {MonoBehaviour.Destroy(GameObject.Find("Canvas/menu_root"));}//菜單按鈕點擊后的響應函數,記得要設置為public權限才能關聯按鈕public void on_game_start_click() {if (this.is_started) { // 防止重復點擊return;}this.is_started = true;//執行一個定時器(自帶的),讓刪除節點的函數過一會再執行,場景過渡效果this.Invoke("delete_menu", 0.2f);this.Invoke("game_realy_started", 1.0f);}// Update is called once per framevoid Update () {} }3.打開plane腳本,里面添加游戲開始的觸發函數
using UnityEngine; using System.Collections;public class plane : MonoBehaviour {//飛機隨著鼠標運動需要定義飛機坐標和鼠標坐標Vector3 start_plane_pos; // 按鈕按下的時候飛機的開始的坐標Vector3 start_mouse_pos; // 鼠標開始的坐標;//子彈預制體public GameObject bullet_prefab;//預制體子彈節點public Transform bullet_root;//預制體子彈節點的父節點public float shoot_rate = 0.2f; // 子彈發射的頻率;我感覺是一個時間間隔,設定的子彈發射時間間隔private float shoot_time = 0.0f; // 距離上一次發射過去的時間private bool is_shooting = false;//是否處于發射子彈的狀態//-----優化-----private bool is_touch = false;//是否點到飛機// Use this for initializationvoid Start(){}public void start_game(){this.is_shooting = true;}void shoot_bullet(){//使用預制體生成一顆子彈GameObject bullet = GameObject.Instantiate(this.bullet_prefab);// 注意這個參數要使用falsebullet.transform.SetParent(this.bullet_root, false);//使用localPosition是因為子彈和plane都有相同的父節點,兩者之間是相對坐標Vector3 offset = new Vector3(0, 64, 0);bullet.transform.localPosition = this.transform.localPosition + offset;}// 響應我們的鼠標事件,GetMouseButton(0)void Update(){//鼠標按下的情況if (Input.GetMouseButtonDown(0)){//-----修改-----this.is_touch = false;//每次鼠標點下去,不管有沒有點到飛機,初始化為沒點到Ray myRay = Camera.main.ScreenPointToRay(Input.mousePosition);//從攝像機發出一條射線RaycastHit2D hit = Physics2D.Raycast(new Vector2(myRay.origin.x, myRay.origin.y), Vector2.zero);//射線從鼠標點擊屏幕的那個點出發,射到以當前點擊位置為原點的坐標系中的垂直于(0,0)的位置,//如果從3D的視角看就是攝像機的射線垂直射到Canvas上if (hit.collider)//如果碰到有Collider2D組件的物體,就做一些事情 {if (hit.transform.gameObject.name == "plane")//如果碰到的是飛機 {//Debug.Log(hit.transform.name);//打印出碰撞到的節點的名字this.is_touch = true;//點到飛機 }}if (is_touch)//如果點到飛機 {//獲得鼠標的初始點擊位置this.start_mouse_pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);//獲得飛機的初始位置this.start_plane_pos = this.transform.position;}}//鼠標滑動的情況else if (Input.GetMouseButton(0) && this.is_touch){Vector3 w_pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);//獲得偏移量Vector3 offset = w_pos - this.start_mouse_pos;//設置飛機偏移后的位置this.transform.position = this.start_plane_pos + offset;}// 子彈發射邏輯控制,update里面嵌套自定義的update,自定義刷新函數this.shoot_update(Time.deltaTime);}void shoot_update(float dt){if (!this.is_shooting){return;}this.shoot_time += dt;if (this.shoot_time < this.shoot_rate){return;}this.shoot_time = 0;this.shoot_bullet();} }轉載于:https://www.cnblogs.com/HangZhe/p/7090543.html
總結
以上是生活随笔為你收集整理的关于Unity的入门游戏飞机大战的开发(上)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: bzoj1059: [ZJOI2007]
- 下一篇: docker - 启动container