傳送門
Unity官方實例教程 Space Shooter(一)
Unity官方實例教程 Space Shooter(二)
Unity官方實例教程 Space Shooter(三)
Unity官方實例教程 Space Shooter(四)
Unity官方實例教程 Space Shooter(五)
前言
在Unity官方實例教程 Space Shooter(一)中,我們學會了:
- 如何下載和導入資源
- 如何設置游戲視窗大小
- 添加了飛船和飛船噴射效果
- Capsule Collider和Mesh Collider的用法
但是我們還沒有為游戲添加任何的操作,現在還只是一個可以看,但不能玩的版本,所以今天我就讓游戲可以玩起來!
你將學到什么?
- 如何控制飛船移動
- 如何限制飛船的移動范圍
- 如何整理公共變量
- 添加游戲背景
- 如何創建一個新材質
- 如何讓飛機發射子彈
一、調整攝像機的位置
我們進入Game窗口,可以看到現在飛船是出于屏幕的正中間的,對于我們最終的游戲來說,這不是一個合適的位置,所以我們首先調整一下攝像機的位置,來改變飛船在屏幕中的位置
這邊其實也可以調整飛船的位置,來達到同樣的目的,但是讓飛船處于(0,0,0)的位置,會利于我們之后的制作,所以本例中我們采用調整攝像機的位置的方法來實現
我們選中Main Camera,然后將其的Position的Z值調整為5,然后我們看一下飛船的位置,如下:
這是一個不錯的位置,接下來我們便可以來實現飛船的移動功能了
二、控制飛船移動
為了實現飛船的移動,首先我們給飛船也就是我們的Player添加一個腳本(Script),關于如何添加腳本請參見Unity官方實例教程 Roll-a-Ball(一),在這里我們將腳本的名字命名為PlayerController,然后我打開腳本,添加以下代碼:
- 首先我們定義了公共的變量speed
- 然后我們用兩個變量moveHorizontal和moveVertical記錄玩家輸入的方向數據
- 然后我們新建一個Vector3類型的變量movement,并且將moveHorizontal和moveVertical分別賦值給movement的X和Z
- 最后我們獲取Player的剛體的速度屬性,將movement乘上speed的值賦給它
代碼寫完之后,我們保存一下代碼,然后回到Unity編輯器,將speed設置為10,接著運行游戲來檢測我們剛剛的代碼是否起到作用了。如無意外,現在我們可以控制飛船上下左右移動了!
不過現在飛船移動好像不是那么的生動,我們在給飛船左右移動的時候,讓飛船整個身體傾斜一點,這樣更加性感,我們再次打開腳本,增加以下代碼:
- 首先我們添加一個公共變量tilt,來設置飛船傾斜的幅度
- 然后我們獲取Player剛體屬性的rotation,將我們移動的速度x值乘上-tilt賦值給rotation屬性
關于Quaternion的詳細信息有興趣的朋友可以去查閱官方文檔,后面會出專門的文章來詳細講解,這邊就不做詳細介紹了,大家只需要知道這句話的作用就是實現飛船左右移動時的傾斜功能
代碼寫完之后,我們保存一下,然后回到Unity編輯器,將tilt設置為5,接著運行游戲,我們就可以檢查剛剛的代碼是否起到作用,如無意外,飛船左右移動的時候就會有傾斜效果了
三、限制飛船的移動范圍
我們實現了飛船移動功能后,會發現一個問題,就是飛船可以移動到屏幕外面去,這樣玩家就看不到飛船了,這不是好的體驗,就像馬航失聯一樣,所以我們需要限制一下飛船的移動范圍,讓它無法飛出我們的屏幕外
讓我們來思考一下,如何來限制飛船的移動范圍呢?首先我們飛船的移動范圍,換句話說就是飛船的Position屬性,而它的范圍呢,就是我們的屏幕邊界,由于我們游戲視角是俯視角,飛船的Y軸位置不會變,所以我們只需限制飛船在X和Z軸上的位置即可,我們在編輯器拖動飛船到屏幕的最左邊,可以看到飛船的X大約在-6左右,我們使用同樣的方法,可以測試飛船在X和Z軸上的范圍分別是(-6,6)和(-3,8)。
接下來我們看看如何在代碼中來限制飛船的位置:
- 首先序列化了一個Boundary類,用來保存飛船在X和Z軸上的范圍,也就是xMin、xMax、zMin、zMax
- 然后我們定義了一個變量boundary
- 最后我們獲取飛船的位置屬性,然后通過Mathf.Clamp來確保飛船在X和Z軸上的范圍處于我們設定的值內
將xMin、xMax、zMin、zMax整合到Boundary類里面,是方便分類管理公共變量,如下圖:可以通過小三角來收起/展開,這樣讓公共變量更加整潔
Paste_Image.png
寫完代碼后,我們保存一下,然后回到Unity編輯器,將xMin、xMax、zMin、zMax的值分別設置為(-6,6,-3,8),然后運行游戲測試一下,就可以發現,現在飛船無法跑出屏幕外了,Nice!
四、添加游戲背景
和官方視頻不同,我們這邊到這一步才添加游戲背景,原因是游戲背景和后面馬上要講到的子彈,都用到了同一個GameObject——Quad,所以兩個東西放到一起來講
首先我們新建一個Quad對象,然后進行兩個標準動作,將名稱命名為BackGround,新建成功后,我們在Game視窗中可以看到,沒有任何變化,為什么呢?我們回到Scene視圖來看一下,Quad到底是個什么東西
我們可以看到,Quad就是一個類似平面(Plane)的對象,它使垂直與攝像機的,所以我們看不到他,所以我們需要將它在X軸上旋轉90°,然后我們就可以在Game視窗中看到了
我們觀察一下BackGround的Inspector屬性,由于我只是做背景用,所以Mesh Collider我們根本不需要,這里我們就將該組件給移除掉
接下來我們將背景圖片資源,直接拖入BackGround里面,Unity自動為我們生成了一個材質,此時我們可以看到BackGround變成了如下的樣子:
這就是我們的背景,額,作為一個背景,它好像還是有很多問題,太小、太暗,比例失調,所以首先第一步,我們就是將它的大小調整到合適的尺寸,我們選中背景圖片資源,觀察一下他的信息
我們可以看到,背景圖片的尺寸為10242048,為了讓圖片比例不會失調,我們需要將BackGround*的X設置為Y一半,我們將XY分別設置為(15,30)
我們可以看到,現在BackGround的比例已經正常了,大小也合適,但是圖片還是太暗了,這是由于我們選中的材質渲染模式有關系,
我們將Shader修改為Unlit/Texture后,圖片顏色就會變得正常了
最后一步,作為背景,我們發現它有一部分將飛船給遮擋了
所以我們需要將背景往下移動一些,而且由于我們的攝像機是選用的正交模式,所以背景下移并不會改變他的顯示效果,我們將BackGround的Position Y設置為-10,這樣背景就不會在擋住飛船了
五、制作子彈
為了視覺效果和邏輯分離,我們首先新建一個空的GameObject,命名為Bolt,然后繼續新建一個Quad,命名為VFX,將VFX拖入到Bolt下面,然后我們選中VFX,把它的Rotation X設置為90,同樣的,作為Quad,我們也需要像背景一樣,將一個圖片顯示在上面,但是,這里我們和設置背景圖片不一樣,我們使用一種新的辦法來設置,首先我們新建一個材質
新建材質
首先我們選中Create->Material,創建一個新的材質,命名為fx_Bolt_orange
然后我們選中剛剛新建的材質,修改它的Shader模式為Particles/Additive
然后將子彈的圖片和材質關聯起來,如下圖:
最后我們將我們做好的材質拖入VFX中
我們便可看到子彈的效果做好了!
給子彈添加碰撞
一開始我們說了要視覺效果和邏輯分離,所以我們移除VFX中的Mesh Collider組件,然后給Bolt添加剛體和膠囊碰撞(Capsule Collider),同時按下圖設置他們的屬性:
讓子彈飛一會兒
到這里,子彈的視覺效果和物理屬性我們都已經設置好了,下一步我們讓子彈可以在發射后往前移動,如果子彈不能移動那還怎么打到人呢?
所以我們給Bolt添加一個新的腳本,命名為Mover,然后打開并編輯它,如下圖:
- 首先我們定一個公共變量speed用來調節子彈飛行的速度
- 然后我們在子彈生成時賦予它一個往前的速度
寫完代碼后,我們保持一下,然后回到Unity編輯器,將speed速度設置為20
制作成Prefab
做完子彈的所有準備工作后,我們將Bolt制作成一個Prefab(預制件),方便以后使用
最后我們邊可以運行一下,看到子彈飛出去的效果了
六、飛船發射子彈
現在我們有了飛船,有了子彈,下一步就應該把它們聯合起來,讓飛船可以發射子彈,那么開始之前,我們思考一下,要實現飛船發射子彈的功能,我們需要一些什么?
- 首先我們要知道子彈從哪里發射
- 然后我們需要檢查用戶按鍵,來接受發射信號
- 然后我們需要設置子彈發射的頻率
- 然后我們還需要知道如何生成一個子彈
我們一個個來看
設置子彈發射點(Shot Spawn)
在實現子彈發射之前,我們將場景中現有的Bolt刪除,因為我們不需要他了
首先我們新建一個空的GameObject,命名為Shot Spawn,作為飛船的一個武器掛載點,確保所有的子彈都是從這個點出發,然后我們把Shot Spawn拖入到Player下面,并調整Shot Spawn的位置到合適的點,本例中置為飛船前方就可以了,如下圖:
實現發射功能的代碼
然后我們打開PlayerController腳本,新增以下代碼:
- 首先我們定義一個私有變量nextFire,用來記錄下一發子彈的時間
- 然后我們定義一個公共變量fireRate,用來控制子彈發射的間隔時間
- 接著我們定義一個公共變量shot,用來保存我們發射的子彈Prefab,也就是告訴程序,我們發射的是哪個子彈
- 然后我們定義一個公共變量shotSqawn,用來保存子彈的發射點,也就是告訴程序,子彈從哪里發射出去
- 接著我們在Update函數中,判斷用戶是否有按下Fire1鍵,這邊的Fire1鍵就是鍵盤上的左Ctrl鍵和鼠標左鍵,同時當前時間超過我們下一發子彈所需的時間,換句話來說,這個if的作用就是確保我們武器沒有在冷卻時間時按下發射鍵,才會發射子彈
- 當if條件通過后,我們先記錄下一發子彈的時間,然后通過Instantiate方法生成一發子彈,他有3個參數,一個是發射的對象,一個是發射對象的position,一個是發射對象的rotation
寫完代碼后,我們保存一下,然后回到Unity編輯器,并分別設置我們剛剛定義的幾個公共變量,如下:
所有操作做完后,我們邊可以運行游戲,看看實際效果了!
下集內容
在下一集,我們將學會:
- 如何回收子彈
- 如何創建障礙物
- 如何通過代碼創建無盡波數的障礙
- 如何實現子彈擊碎障礙功能