文章目錄
- 一、準備開始
- 1.創建場景
- 1.1打開場景
- 1.2新建標簽
- 1.3設定標簽
- 1.4烘培導航
- 2.添加主角
- 2.1匯入標準資源包
- 2.2創建腳本
- 3.創建武器
- 3.1添加手槍
- 3.2添加武器標簽
- 4.創建常量檔案
- 4.1創建Constants腳本
- 5.武器邏輯
- 5.1切換武器
- 二、子彈彈藥
- 1.彈藥的邏輯
- 1.1創建Gun基類
- 1.2創建手槍腳本
- 1.3創建獵槍腳本
- 1.4 創建突擊步槍腳本
- 2.創建開槍影片
- 2.1創建影片控制器
- 2.2用代碼控制影片播放
- 2.3設定Animator組件
- 3.添加準心
- 3.1繪制手槍準心
- 3.2創建GameUI腳本
- 3.3修改GunEquipper腳本
- 4.彈藥管理
- 4.1創建Ammo類
- 4.2添加聲音
- 總結
一、準備開始
1.創建場景
1.1打開場景
首先,在Unity中打開啟動專案,在專案視圖中,打開“Scenes/Battle”,如下圖所示,

1.2新建標簽
-
首先,需要設定“Wall”的游戲物件,避免機器人AI撞到墻上,
Tag是一個用來標識游戲物件的文本,每個游戲物件只能有一個標記,通過給每個墻的游戲物件分配一個標簽,再為機器人設定一些尋路規則,這樣它們就可以繞開墻走動,
在層級視圖中,單擊“Inner Walls”游戲物件,在檢視視圖中,單擊“Tag”下拉串列,然后選擇“Add Tag”命令,

-
單擊“Tag”視窗中的加號按鈕,然后新建一個“Wall”標簽

1.3設定標簽
通過單擊層級視圖中“InnerWalls”游戲物件左邊的箭頭展開它,選擇它所有子物件 (名為“Wall”和“WallPost”),快速的方法是選擇第一個游戲物件,然后按住Shift鍵并單擊最后一個游戲物件,選中所有子物件后,單擊“Tag”下拉串列并選擇剛剛創建的“Wall”標簽,

注:當所有的墻壁都被標記為“Wall”時,可以開始著手為機器人添加“NavMesh”了,
1.4烘培導航
通過“Window/Navigation”打開“Navigation”視圖,確保選中了所以的“Wall”和“WallPost”游戲物件,并確保選中了“Object”選項卡中的“Navigation Static”復選框,

選擇“Bake”標簽并單擊“Bake”按鈕

可以看到場景中出現了淺藍色的面片,這個淺藍色的面片就是被限制后的機器人可移動區域,
)
2.添加主角
2.1匯入標準資源包
在層級視圖中,創建一個空的游戲物件并命名為“Player”,案例將使用Unity自帶的Character Controller(角色控制器),并稍作修改來實作玩家對主角的控制,選擇選單欄中的“Assets\ImportPackage\Characters”命令,匯入標準資源,
注意:如果在ImportPackage中看不到“Character Controller”選項,說明在安裝 Unity 時沒有匯入Standard Assets(標準資產),要修復此問題,需要重新執行Unity安裝程式,只安裝Standard Assets,標準的Unity資產就像任何常規包一樣,它只是一個檔案的集合,
單擊選單上的Import按鈕以匯入Characters資產,

2.2創建腳本
創建移動腳本,包含人物移動,跳躍和轉動攝像機,然后將腳本賦予Player確保各個功能的正常實作



創建好的腳本如圖所示,speed表示人物移動,jump表示人物跳躍,Gravity表示重力,camera_x和camera_y表示滑鼠移動時攝像機的轉動倍率,
Camera攝像機需要放在Player人物下,程式會自動獲取攝像機

備注:想要實作shift奔跑只需要添加
private float moveSpeed=Speed;
然后將以下代碼添加進move函式中即可
if(Input.GetKeyDown(KeyCode.LiftShift))
{
Speed=跑步速度;
}else Speed=moveSpeed;
3.創建武器
3.1添加手槍
在Unity中,槍只是另一個游戲物件,最大的區別在于視角,把它靠近鏡頭,立刻就能找到第一人稱射擊的感覺,
選擇Camera游戲物件,然后右擊它并選擇“Create Empty”,創建一個空的子游戲物件,命名為“1Pistol”,名字前面的數字是指玩家將使用的裝備ID,
將專案視圖中“Models/RobotRampage_Pistol”模型拖到1Pistol 游戲物件上,
調整模型的位置大小,讓槍在攝像機中正常顯示,然后勾選下框,隱藏模型

根據此流程,添加獵槍和步槍,
3.2添加武器標簽
接下來要為每個武器設定標簽,
首先創建三個新的Tag,它們是Pistol、AssaultRifle和Shotgun,
然后給武器分配對應的標簽,
1Pistol設定Tag為Pistol,2AssaultRifle設定為AssaultRifle,3Shotgun設定為Shotgun,如下圖所示



4.創建常量檔案
4.1創建Constants腳本
在專案視圖中右擊Assets檔案夾,選擇“Create\Folder”命令創建一個新檔案夾,命名為“Scripts”,在Scripts檔案夾中,創建一個C#腳本,命名為“Constants”,
在腳本編輯器中打開Constants腳本,并將檔案的內容替換為:


5.武器邏輯
5.1切換武器
保存腳本,回到Unity,在Scripts檔案夾中新建一個C#腳本,將其命名為“GunEquipper”,添加以下變數,

保存腳本,回到Unity,在Scripts檔案夾中新建一個C#腳本,將其命名為“GunEquipper”,添加以下變數,

保存腳本,回到Unity,并將GunEquipper 腳本添加到Player游戲物體上
選擇Player游戲物件,并將1Pistol 游戲物件從層級視圖拖動到 GunEquipper 腳本組件中的相應欄位,以同樣的方法操作2AssaultRifle 和3Shotgun,


二、子彈彈藥
1.彈藥的邏輯
1.1創建Gun基類
首先,需要確定了一個攻擊頻率,當玩家持續開槍時,每顆子彈射出之間有一個停頓,這意味著必須跟蹤最后一顆子彈發射的時間,以便于判斷何時可以發射下一顆子彈,
創建一個C#腳本,命名為“Gun”,并添加下面的變數:

fire Rate表示攻擊的頻率,而lastFireTime表示最后一次攻擊的時刻,在Gun腳本中修改Start方法:


設定lastFireTime默認值為游戲開始的10秒前,10秒遠遠大于攻擊間隔,所以當游戲開始時,玩家將能夠立即發射子彈,最后,修改Update方法,代碼如左,

因為每個武器在具體實作上都有細微差異,所以稍后將在子類中對這些方法進行多載,
1.2創建手槍腳本
保存腳本,切換回Unity,創建一個C#腳本,將其命名為“Pistol”,并將其內容替換為:

這將檢查下一次射擊是否達到攻擊間隔,如果達到,將觸發下一次射擊動作,
保存腳本,回到Unity,并將Pistol腳本添加到1Pistol游戲物體,
選中1Pistol游戲物體,將fireRate設定為0.6,
1.3創建獵槍腳本
選擇Pistol腳本,然后按下Ctrl+d鍵,復制腳本,把名字改成Shotgun,在代碼編輯器中打開該腳本,將如下代碼:

與手槍一樣,這也是一個半自動武器,但因為它是一把獵槍,所以它需要更長的發射間隔,保存腳本,回到Unity,將Shotgun腳本附加到3Shotgun 游戲物體上,并將 fireRate 設定為1,
1.4 創建突擊步槍腳本
最后,需要對突擊步槍做同樣的操作,創建一個名為“AssaultRifle”的腳本,將其附加到2AssaultRifle 游戲物件上,并將其內容替換為:

看上去這個腳本與Pistol腳本幾乎相同,但有一個關鍵區別:該腳本使用 GetMouseButton來監聽玩家是否按住滑鼠左鍵,而不是用GetMouseButtonDown監聽單次按下滑鼠左鍵,
保存腳本,回到Unity,在檢視面板中將AssaultRifle腳本的fireRate設定為0.1,
2.創建開槍影片
2.1創建影片控制器
右擊“Animations”檔案夾,選擇“Create\Animator Controller”命令,并將其命名為“Pistol”,右擊Pistol.AnimatorController,然后單擊“Open”按鈕,打開Animator視窗,
在Animator視窗的網格區域中右鍵單擊,然后選擇“Create State\Empty”創建一個新的狀態,單擊新狀態,并在檢視視圖中,將其重命名為“Fire”,
單擊Motion框右側的控制元件,然后在搜索框中查找“Fire”,在結果串列中找到Assets/Models/RobotRampage_Pistol.fbx,然后雙擊它,如下圖所示,

需要為影片創建默認狀態,和之前一樣,在影片視窗中創建另一個空狀態,命名為“Base”,
右擊“Fire”,然后選擇“Make Transition”命令,從Fire拖到Base,如圖2-2-2所示,

Fire影片播放后,影片應該回到Base狀態,右鍵單擊Base狀態,然后選擇“Set as Layer Default State ”,使其成為基本影片,如下圖所示,

2.2用代碼控制影片播放
打開Gun腳本,并將以下代碼添加到Fire ()方法:
GetComponentInChildren<Animator>().Play("Fire");
這需要在代碼中獲取Animator,并告訴它何時播放Fire影片,在這之前,需要先在游戲物件上添加Animator組件,
當然,目前只創建一個手槍影片控制器,還需要創建獵槍和突擊步槍的影片控制器,
在專案視圖中,選擇Animations檔案夾下的Pistol影片控制器,按下Ctrl+D兩次,復制出兩個影片控制器,其中一個命名為“Shotgun”,另一個命名為“AssaultRifle”,
打開Shotgun影片控制器,并選擇Fire狀態,在檢視視圖中,設定Motion為Grip|Fire,來源于Assets/Models/ RobotRampage_Shotgun.fbx 模型,
最后,打開 AssaultRifle 影片控制器,并選擇Fire狀態,在檢視視圖中,設定Motion為Grip|Fire,來源于Assets/Models/RobotRampage_AssaultRifle.fbx模型,
所有的影片已經設定到位,下面需要將它們添加到武器上,
2.3設定Animator組件
回到Unity,選擇1Pistol 游戲物件,單擊Add Component按鈕,輸入Animator,在搜索結果中選擇Animator,單擊剛才添加的動Animator的Controller欄,然后從彈出視窗中選擇Pistol影片控制器,如下圖所示,

接下來點擊Animator的Avatar框,并設定為 RobotRampage_PistolAvatar,如圖2-2-5所示,

Avatar告訴影片系統如何在影片程序中變換模型,匯入模型時,需要配置Avatar,為了簡單起見,Avatar已經被提前配置好
對于突擊步槍,選擇2AssaultRifle 游戲物件,并將AssaultRifle影片控制器拖到檢視視圖,在所有現有組件之下,Unity會自動將Animator添加到游戲物件上,把Avatar設定為RobotRampage_AssaultRifleAvatar,

對3Shotgun做同樣的操作,拖動它的Shotgun影片控制器,并設定Avatar為 RobotRampage_ShotgunAvatar,如下圖所示,

運行游戲,測驗武器,通過鍵盤上的1鍵、2鍵或3鍵在它們之間切換,
3.添加準心
3.1繪制手槍準心
原理很簡單,只是一個放置在攝像機前的簡單的2D影像,這不是什么很高明的技術,但是很實用,
在開始放置UI元素前,首先需要一個畫布,Unity提供了幾種型別的畫布,本游戲將使用疊加畫布,即overlay canvas,
在層級視圖中的空白處,右擊選擇“UI\Canvas”命令創建一個畫布,重命名為“GameUI”,右擊Canvas游戲物件,選擇“UI\Image”命令創建一個圖片,并重命名為“Reticle”,
在檢視視圖中,單擊Source Image右側的控制元件,然后選擇reticleRed,

可以看到螢屏中央的紅色準心,

3.2創建GameUI腳本
當切換成獵槍和突擊步槍時,應該更新顏色,
創建一個新腳本,命名為“GameUI”,將GameUI腳本附加到GameUI游戲物件上,
在代碼編輯器中打開GameUI,并將以下內容添加到腳本的頂部,
using UnityEngine.UI;
這使腳本可以訪問Unity基本的UI 類,接下來,在類中添加以下變數
[SerializeField] Sprite redReticle;
[SerializeField] Sprite yellowReticle;
[SerializeField] Sprite blueReticle;
[SerializeField] Image reticle;
SerializeField 屬性允許開發者向 C# 運行時傳遞有關特定類的資訊,Sprite(精靈)代表了一個匯入的紋理,可以被使用在2D游戲或用戶界面,通過將紋理型別設定為Sprite,可以將其添加到用戶界面中,
現在有三個精靈作為影像的源資料,但是只有一個會被顯示,所以只需要一個Image,
在最后一個變數下面添加以下方法:
public void UpdateReticle() {
switch (GunEquipper.activeWeaponType)
{
case Constants.Pistol:
reticle.sprite = redReticle;
break;
case Constants.Shotgun:
reticle.sprite = yellowReticle;
break;
case Constants.AssaultRifle:
reticle.sprite = blueReticle;
break;
default:
return;
}}
選中GameUI游戲物體,添加適當的精靈,拖動Reticle游戲物件到Reticle欄,如下圖所示,

3.3修改GunEquipper腳本
在代碼編輯器中打開 GunEquipper 腳本,為其添加一個GameUI 變數,創建對 GameUI 的參考,代碼如下,
[SerializeField] GameUI gameUI;
保存腳本,回到Unity,在層級視圖中選擇Player游戲物件,并將 GameUI 物件拖拽到GunEquipper組件中的GameUI欄位,如下圖所示,

在代碼編輯器中打開GunEquipper 腳本,并在 Update () 方法中的每個 if 陳述句的末尾添加以下代碼,
gameUI.UpdateReticle();
Update()現在應該如下所示,每次玩家改變武器將更新準心,
void Update() {
if (Input.GetKeyDown("1")) {
loadWeapon(pistol);
activeWeaponType = Constants.Pistol;
gameUI.UpdateReticle();}
else if (Input.GetKeyDown("2")) {
loadWeapon(assaultRifle);
activeWeaponType = Constants.AssaultRifle;
gameUI.UpdateReticle();}
else if (Input.GetKeyDown("3")) {
loadWeapon(shotgun);
activeWeaponType = Constants.Shotgun;
gameUI.UpdateReticle();}}
4.彈藥管理
4.1創建Ammo類
游戲中應該提供一些聲音的反饋,使玩家知道什么時候快沒子彈了,如果玩家有足夠的彈藥,在開火時播放開火的聲音,如果沒有足夠彈藥,播放空彈夾的聲音,并且不播放開火影片,
創建一個C#腳本,命名為“Ammo”,在代碼編輯器中打開它,在頂部添加如下代碼,
using System.Collections.Generic;
這里可以使用字典型別,添加以下變數,
[SerializeField] GameUI gameUI;
[SerializeField]private int pistolAmmo = 20;
[SerializeField]private int shotgunAmmo = 10; [SerializeField]private int assaultRifleAmmo = 50;
public Dictionary<string,int> tagToAmmo;
變數 pistolAmmo、shotgunAmmo、assaultRifleAmmo表示三種槍各自的彈藥數,
tagToAmmo是一個由字串映射int型別的字典,可以通過槍的型別找到其對應彈藥計數,
在游戲開始時初始化Dictionary,添加如下代碼,
void Awake()
{
tagToAmmo = new Dictionary<string,int>
{
{ Constants.Pistol ,pistolAmmo},
{ Constants.Shotgun ,shotgunAmmo},
{ Constants.AssaultRifle ,assaultRifleAmmo}
};
}
Awake方法是在Start方法之前呼叫的一種特殊方法,在本例中,為了防止null 訪問錯誤,需要在所有Start方法執行之前對字典進行初始化,
該方法只是簡單地讓每支槍在字典中鍵入一個鍵,并將值設定為適當的彈藥型別,如果希望添加另一個彈藥型別,可以簡單地擴展字典,
添加如下方法:
public void AddAmmo(string tag,int ammo)
{
if (!tagToAmmo.ContainsKey(tag))
{
Debug.LogError("Unrecognized gun type passed: " + tag);
}
tagToAmmo[tag] += ammo;
}
這個方法將增加特定型別的彈藥,如果字典中不存在tag傳入的型別,則會報錯,
接下來添加以下方法:
// Returns true if gun has ammo
public bool HasAmmo(string tag)
{
if (!tagToAmmo.ContainsKey(tag))
{
Debug.LogError("Unrecognized gun type passed: " + tag);
}
return tagToAmmo[tag] > 0;
}
這個方法將會判斷是否還存在某型別的子彈,如果有,回傳true,
同時添加以下方法:
public int GetAmmo(string tag) {
if (!tagToAmmo.ContainsKey(tag)) {
Debug.LogError("Unrecognized gun type passed:"
+ tag);
}return tagToAmmo[tag];
}
這個方法只是簡單地回傳某種型別的槍的彈藥數量,
最后,需要一個方法來實作彈藥的消耗,添加如下代碼,
public void ConsumeAmmo(string tag) {
if (!tagToAmmo.ContainsKey(tag)) {
Debug.LogError("Unrecognized gun type passed:" +
tag);}
tagToAmmo[tag]--;}
與所有其他方法一樣,首先會檢查彈藥名是否正確,如果正確,它將會找到對應的彈藥,并減去一顆子彈,
保存腳本,回到Unity,并將Ammo腳本添加到Player游戲物件上,點擊Player游戲物體,將 GameUI 游戲物體拖拽到Ammo組件中的 GameUI 欄位上,如下圖所示,

4.2添加聲音
在代碼編輯器中打開Gun腳本,并添加如下變數,
public Ammo ammo;public AudioClip liveFire;
public AudioClip dryFire;
這將跟蹤槍的彈藥數量和保存開火和空彈的音效,修改Fire方法,代碼如下,
protected void Fire()
{if (ammo.HasAmmo(tag))
{ GetComponent<AudioSource>().PlayOneShot(liveFire);
ammo.ConsumeAmmo(tag);}
else
{ GetComponent<AudioSource>().PlayOneShot(dryFire);}
GetComponentInChildren<Animator>().Play("Fire");}
這將檢查玩家是否有剩余的彈藥,如果有,播放liveFire的聲音;否則,播放dryFire的聲音,如果開槍成功,花費一顆子彈,
接下來需要為每支槍單獨設定彈藥和音效,
單擊1Pistol游戲物體,并拖動Player游戲物體到Ammo屬性欄,表示對玩家Ammo腳本的參考,單擊LiveFire欄位右側的控制元件,然后選擇pistolShot音頻檔案,單擊dryFire欄位右側的控制元件并旋轉dryFire音頻,如下圖所示,

對3Shotgun和2Assaultrifle做同樣的操作,
剩下的就是添加AudioSource組件,選中1Pistol、2AssaultRifle和3Shotgun游戲物件,在檢視視圖中單擊AddComponent,鍵入AudioSource并選擇AudioSource組件,如下圖所示,

運行游戲,檢查每只槍的射擊音效,
突擊步槍有一個問題,槍的射擊速度比影片播放速度快,這使運動與動作不同步,為了解決這個問題,需要回到Animator那里,
如果影片視窗已關閉,可以通過單擊“Window\Animator”重新打開它,在層級視圖中,選擇2AssaultRifle 游戲物體,將會在Animator視圖中看到它的影片狀態,
默認情況下,影片在過渡程序中會有一段混合程序,這種混合程序被稱為退出時間,選擇從Fire到Base的轉換,在檢視視圖中,可以看到退出時間的可視化效果,如下圖所示

有兩種方法可以取消退出時間,第一種,取消選中“Has Exit Time”屬性,但是只有在有過渡條件時才能這樣做,第二種,將時間軸中的右邊的藍色箭頭拖到左側,然后按Enter鍵將其保存,


這將導致新的影片會中斷任何正在播的放影片,運行游戲,切換到突擊步槍,測驗修改過的內容,
總結
共同學習
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/287236.html
標籤:其他
