unity实战:狂暴机器人游戏教程(下篇)
文章目錄
- 前言
- 三、敵人
- 3.1創建機器人
- 步驟1 創建腳本
- **步驟2 定義生命周期**
- **步驟3添加射擊動畫**
- 3.2發射機器人導彈
- 步驟1 創建導彈運動邏輯
- 步驟2 添加導彈發射方法
- 3.3增加傷害
- 步驟1 添加玩家受擊方法
- 步驟2 導彈檢測碰撞
- 步驟3 添加機器人受擊方法
- 步驟4 實現聚焦
- 步驟5 添加射線
- 3.4創建補給
- 步驟1 添加拾取補給的方法
- 步驟2 創建補給邏輯
- 步驟3 添加補給的漂浮動畫
- 3.5補給刷新點生成
- 步驟1 創建補給點
- 步驟2 設置所有補給點
- 步驟3 創建傳送點
- 步驟4 設置所有傳送點
- 步驟5 創建游戲管理器
- 3.6添加聲音
- 步驟1 添加音頻
- 步驟2 實現聲音播放
- 總結
前言
不了解或者看不懂的可以去看
unity實戰:狂暴機器人游戲教程(上篇)
提示:以下是本篇文章正文內容,下面案例可供參考
三、敵人
3.1創建機器人
步驟1 創建腳本
單擊“Resources”文件夾,然后將RedRobot、YellowRobot和BlueRobot拖到玩家面前的某個位置(位于地面之上)
如下圖所示。
同時選中RedRobot、YellowRobot和BlueRobot游戲對象,在檢視視圖中單擊Add Component按鈕,然后選擇New Script命令。命名腳本為Robot。這將在Assets文件夾中創建一個新腳本。將Robot腳本從Assets文件夾移動到Scripts文件夾。在代碼編輯器中打開Robot腳本。添加以下變量。
robotType表示機器人的類型:RedRobot、BlueRobot或YellowRobot。
health是機器人生命值,
range是它能射擊的距離,
fireRate 是它能射擊的速度。
agent是對NavMeshAgent組件的引用,
player是機器人跟蹤的對象,
isDead表示機器人是否死亡。
保存腳本并切換回Unity。單擊RedRobot游戲對象,然后在 robotType字段中輸入 RedRobot。將Health設置為 14,Range值為 150,Fire Rate為2。單擊Apply按鈕,將這些更改應用到預置。如下圖所示。
對YellowBot執行相同的操作:Robot Type設為YellowRobot,Health設為20,Range設為300,Fire Rate設為3。
單擊Apply按鈕。
對BlueRobot執行相同的操作:Robot Type設為BlueRobot,Health設為10,Range設為200,Fire Rate設為1。
單擊Apply按鈕。
Missile Fire Spot參數是機器人發射導彈的位置。
單擊RedRobot游戲對象旁邊的箭頭以顯示其子對象。拖動其子游戲對象 MissileFireSpot 到Missile Fire Spot屬性欄。
對YellowBot和BlueRobot執行同樣的操作。如下圖所示。
步驟2 定義生命周期
現在在代碼編輯器中打開Robot腳本,修改代碼。
void Start() {// 1 isDead = false; agent = GetComponent<UnityEngine.AI.NavMeshAgent>(); player = GameObject.FindGameObjectWithTag("Player").transform;} // Update is called once per frame void Update() {// 2 if (isDead) { return;} // 3 transform.LookAt(player); // 4 agent.SetDestination(player.position); // 5 if (Vector3.Distance(transform.position,player.position) < range && Time.time - timeLastFired > fireRate) { // 6 timeLastFired = Time.time; fire();}} private void fire() { Debug.Log("Fire");}下面是對應編號代碼中操作的解釋:
①默認情況下,所有的機器人都是活的。然后將代理和player值分別設置為 NavMesh 代理和player組件。
②檢查機器人是否已死。
③讓機器人面對玩家。
④告訴機器人使用 NavMesh 找到玩家。
⑤檢查玩家是否在射擊范圍內,并且是否攻擊冷卻完畢。
⑥更新timeLastFired到當前時間,并調用Fire方法,它只是暫時將消息記錄到控制臺。
接下來需要為玩家游戲對象分配一個合適的標簽,以便于讓機器人找到它。
保存腳本,回到Unity。點擊Player游戲物體,點擊標簽下拉菜單,并選擇Player標簽。
運行游戲,將看到機器人向玩家移動,并且“Fire”日志不斷出現在控制臺中,如下圖所示。
現在機器人在向玩家靜態地移動。如果他們腳下的輪子滾起來的話,看起來會好得多。而且,機器人在向玩家開火時也應該有射擊動作。
步驟1 添加足部動畫
在隨便哪個機器人上單擊一個 RobotRampage_BotBall_v1 的游戲對象(展開其子對象上的箭頭找到它),
然后轉到Window\Animation以打開Animation窗口。
單擊Create按鈕: 在名稱處輸入Ball,保存到Animations文件夾下,然后單擊保存按鈕。
單擊AddProperty按鈕,單擊Transform旁邊的箭頭,然后單擊Rotation旁邊的+號,如圖下所示。
一對關鍵幀(灰色菱形)將出現在時間軸上的1秒的位置。
單擊最后一個關鍵幀,并注意到游戲對象的Rotation字段已在檢視視圖的轉換組件中變為紅色。將Rotation X值設置為-360。這將導致球旋轉360度。
同時選擇其他兩個機器人的RobotRampage_BotBall_v1子游戲對象。選中所有RobotRampage_BotBall_v1游戲后,將RobotRampage_BotBall_v1拖到檢視視圖中。如下圖所示。
運行游戲,會看到機器人腳下的球在旋轉。
步驟3添加射擊動畫
全選三個RobotRampage_Bot游戲對象,并通過單擊Controller字段旁邊的圓圈選擇Robot,如下圖所示。
逐個選擇每個RobotRampage_Bot,單擊Prefab欄的Apply按鈕,應用對預制體的修改,如下圖所示。
現在打開Robot腳本。添加變量,然后修改Fire ()方法:
保存腳本,回到Unity。選擇YellowRobot并將子物體RobotRampage_Bot拖入Robot屬性。應用對預制體的修改。
如下圖所示。
在RedRobot和BlueRobot上執行同樣的操作。確保在完成操作后應用對預制體的更改。
運行游戲,看到機器人開火了
3.2發射機器人導彈
步驟1 創建導彈運動邏輯
新建一個C#腳本,命名為“Missile”。
將RobotMissileBlue、RobotMissileRed和RobotMissileYellow的預制體從項目視圖的Resources文件夾拖到層級視圖上。
保持選中層級視圖中的RobotMissileBlue、RobotMissileRed和RobotMissileYellow游戲對象,然后將Missile腳本拖到檢視面板。
在代碼編輯器中打開Missile腳本并添加以下變量:
speed是導彈飛行的快慢。
damage是導彈命中玩家時造成的傷害。
現在,在damage變量下面添加以下方法:
//1 void Start() { StartCoroutine("deathTimer");} // 2 void Update() { transform.Translate(Vector3.forward * speed * Time.deltaTime); } // 3 IEnumerator deathTimer() { yield return new WaitForSeconds(10); Destroy(gameObject); }在計算機術語中,會經常聽到“線程”這個詞。這是一種讓計算機同時做多種事情的方法。在Unity中,可以使用coroutines(協程)來模擬線程。
協同方法返回IEnumerator。這些決定了協同的持續時間。下面是代碼對應的注釋:
①當實例化一個導彈,將開始一個名為“deathTimer”的協同方法。
②每幀向正前方移動相應的距離。
③該方法立即返回一個 WaitForSeconds,設置為10。意為該方法將在yield語句等待十秒后恢復。如果導彈沒有擊中球員,它將會自毀。
保存腳本,回到Unity。依次單擊RobotMissileBlue、RobotMissileRed和RobotMissileYellow游戲對象上的Prefab欄的Apply按鈕,應用對預制體的更改。
步驟2 添加導彈發射方法
打開Robot腳本。在該文件的頂部,在類的“{”下面添加以下內容:
[SerializeField] GameObject missileprefab;missilePrefab 是導彈的預制體。修改Fire方法,代碼如下。
private void fire() { GameObject missile = Instantiate(missileprefab); missile.transform.position=missileFireSpot.transform.position; missile.transform.rotation=missileFireSpot.transform.rotation; robot.Play("Fire"); }這將實例化一個新的 missilePrefab,并設置其位置和旋轉到機器人的射擊點。保存腳本回到Unity。
從層級視圖中刪除RobotMissileBlue、RobotMissileRed和RobotMissileYellow游戲對象。
單擊RedRobot游戲對象,將RobotMissileRed預置體從Resources文件夾拖到Robot組件的Missile prefab欄中,然后單擊Apply按鈕。如圖3-3-1所示。
在YellowRobot和BlueRobot游戲對象上執行同樣的操作,確保最后單擊了Apply按鈕。
運行游戲,看到機器人發射導彈
3.3增加傷害
步驟1 添加玩家受擊方法
導彈會傷害到玩家,玩家也會損壞機器人。新建一個新的C#腳本,命名它Player并添加以下變量:
public int health; public int armor; public GameUI gameUI; private GunEquipper gunEquipper; private Ammo ammo;health是玩家的剩余生命值。當生命值為零,游戲結束。
armor是一個玩家的裝甲,減少50%的傷害。
一旦裝甲變成0,玩家將受到100%傷害。
gameUI和gunEquipper是對腳本的引用。
ammo是提前建立的彈藥類。將以下內容添加到Start方法:
這只是初始化對Ammo和GunEquipper組件的引用。添加以下方法:
public void TakeDamage(int amount) { int healthDamage = amount; if (armor > 0) { int effectiveArmor = armor * 2; effectiveArmor -= healthDamage; if (effectiveArmor > 0) { armor = effectiveArmor / 2; return;} armor = 0; }health -= healthDamage; Debug.Log("Health is " + health); if (health <= 0) { Debug.Log("GameOver");}}TakeDamage ()根據玩家剩余的裝甲量來計算傷害減免。
如果玩家沒有盔甲,那么將會受到完整傷害。
如果生命值達到0,游戲將會結束;
現在,只需要將其記錄到控制臺。
保存腳本,回到Unity。
將Player腳本添加到Player游戲對象。
設置Health為100,Armor為 20,
并拖動GameUI游戲對象到GameUI字段。
步驟2 導彈檢測碰撞
當導彈與玩家的碰撞器相撞,它將通過OnCollisionEnter()處理傷害玩家的計算。在代碼編輯器中打開Missile腳本并添加以下方法:
void OnCollisionEnter(Collision collider) { if(collider.gameObject.GetComponent<Player>()!=null&&collider.gameObject.tag == "Player") { collider.gameObject.GetComponent<Player>().TakeDamage(damage); } Destroy(gameObject); }導彈通過檢查與它碰撞的游戲對象Tag是否為Player來判斷是否擊中玩家。
它還要檢查是否Player腳本處于激活狀態,因為Player組件將在游戲結束后被禁用。
如果兩個條件都滿足,它將通過調用Player腳本上的TakeDamage方法來計算傷害。
導彈還會同時銷毀自身。
保存腳本,回到Unity。
運行游戲。讓炮彈擊中自己,查看控制臺播放的玩家受擊信息
步驟3 添加機器人受擊方法
當玩家的生命值到0時,記錄游戲結束。稍后,將會實現更好的處理方法。
目前機器人仍然是無敵的。因為它們還沒有添加受擊方法。打開Robot腳本并添加以下方法:
①這與玩家TakeDamage()方法的邏輯大致相同。唯一不同的地方是,機器人將在生命值為0的時候先播放死亡動畫再調用DestroyRobot ()銷毀自身。
②這在摧毀機器人之前增加了一個1.5秒的延遲,為Die動畫播放完成提供了足夠的時間。
保存腳本。
步驟4 實現聚焦
不同的槍支應該有不同的攻擊范圍、破壞力以及通過鼠標右鍵可以實現不同程度的聚焦。
打開Gun腳本,并添加以下變量:
當玩家點擊鼠標右鍵時,zoomFactor控制縮放級別。
zoomFOV是最終縮放視角。
range是槍的射程。獵槍的射程最短,而手槍最長。
damage是槍造成的傷害。
保存腳本回到Unity。
單擊1Pistol游戲對象,并將其ZoomFactor設置為1.3,Range為60,Damage為3。
單擊2AssaultRifle游戲對象,并將其ZoomFactor設置為1.4,Range為30,Damage為1。
單擊3Shotgun游戲對象,并將其ZoomFactor設置為1.1,Range為10,Damage為10。
打開Gun腳本并更新Start ()方法到以下內容:
void Start() { zoomFOV = Constants.CameraDefaultZoom / zoomFactor; lastFireTime = Time.time - 10;}這只是初始化了縮放因子。修改Update()方法,代碼如下。
protected virtual void Update() { // Right Click (Zoom) if (Input.GetMouseButton(1)) { Camera.main.fieldOfView=Mathf.Lerp(Camera.main.fieldOfView,zoomFOV,zoomSpeed * Time.deltaTime); } else { Camera.main.fieldOfView = Constants.CameraDefaultZoom;}}如果玩家點擊鼠標右鍵,這將通過 Mathf Lerp平滑地播放縮放效果。
步驟5 添加射線
為了確定機器人是否被擊中,將使用光線。光線是一個隱形的射線,但是可以檢測到碰撞。首先,必須定義命中的方法。添加以下內容:
private void processHit(GameObject hitObject) { if (hitObject.GetComponent<Player>() != null) {hitObject.GetComponent<Player>().TakeDamage(damage);} if(hitObject.GetComponent<Robot>()!=null){ hitObject.GetComponent<Robot>().TakeDamage(damage);}}這個方法將傷害值傳遞給正確的游戲對象。為了實現光線,將以下內容添加到Fire方法的底部。
Ray ray = Camera.main.ViewportPointToRay(new Vector3(0.5f,0.5f,0)); RaycastHit hit; if (Physics.Raycast(ray,out hit,range)) { processHit(hit.collider.gameObject);}這將創建一個射線,并檢查射線的命中。道理很簡單,如果射線在槍的射程內與一個游戲對象碰撞就會觸發processHit方法。
processHit判斷命中的是否是機器人,如果是,機器人將會受到傷害。
保存腳本,回到Unity。運行游戲,按住鼠標右鍵縮放,然后攻擊那些機器人,直到他們死掉。
3.4創建補給
步驟1 添加拾取補給的方法
玩家需要一種方法來恢復生命值、護甲和彈藥。案例將在場景的隨機位置添加一些漂浮的補給物讓玩家拾取。在代碼編輯器中打開Player腳本,并添加以下內容:
// 1 private void pickupHealth() { health += 50; if (health > 200) {health = 200;}} private void pickupArmor() { armor += 15;} // 2 private void pickupAssaultRifleAmmo() { ammo.AddAmmo(Constants.AssaultRifle,50);} private void pickupPisolAmmo() { ammo.AddAmmo(Constants.Pistol,20);} private void pickupShotgunAmmo() { ammo.AddAmmo(Constants.Shotgun,10);}這些方法實現了玩家撿到補給物時獲得的增益效果。
現在添加以下內容:
PickUpItem方法通過傳入int參數,獲取正在拾取的補給物的類型。
步驟2 創建補給邏輯
Constants文件引用所有補給物類型的ID。這些ID對應了五種類型的補給物。這些ID將作為參數傳遞到PickUpItem 方法中。
保存腳本,回到Unity。新建一個C#腳本,命名為“Pickup”,并添加字段,代碼如下。
這表示補給物的類型。現在添加以下內容
void OnTriggerEnter(Collider collider) { if(collider.gameObject.GetComponent<Player>()!=null&&collider.gameObject.tag == "Player") { collider.gameObject.GetComponent<Player>().PickUpItem(type);Destroy(gameObject); }}這會讓補給物監聽與玩家的碰撞,從而調用玩家身上Player腳本上的PickUpItem方法,并傳入自身的補給類型,然后銷毀自身。
保存腳本,回到Unity。
在Resources文件夾中,選擇PickupAmmoAssaultRifle、PickupAmmoPistol、PickupAmmoShotgun、PickupHealth和PickupArmor預設。選中所有這些選項后,單擊腳本類別中的Add Component按鈕,選擇Pickup腳本。
接下來,添加Rigidbody。勾選Is Kinematic。
最后,添加BoxCollider。勾選Is Trigger,并設置Size為(1.5、1.5、1.5)。如下圖所示
現在來配置每個補給物的類型。
選擇Resources文件夾中的PickupAmmoPistol,
并將其Type設置為1,
將PickupAmmoAssaultRifle設置為2,
PickupAmmoShotgun為3,
PickupHealth為4,
PickupArmor為5。
步驟3 添加補給的漂浮動畫
現在要做的事情是再補給物上添加旋轉和浮動的動畫。動畫已經預先創建好了,現在只是需要創建Animator。在項目視圖的Animations文件夾中創建一個Animator Controller,命名為“Pickup”。
雙擊Pickup動畫控制器打開Animator視圖。在空網格處右擊喚出快捷菜單,然后選擇Create State\Empty命令。在檢視視圖中,更名為“Spin”并將Motion設置為cubeSpin,如下圖所示。
接下來,返回到項目視圖并選擇Resources文件夾。
展開PickupAmmoAssaultRifle、PickupAmmoPistol、PickupAmmoShotgun、PickupHealth和PickupArmor預設,
選中它們的子物體。
將項目視圖中Animations文件夾里的Pickup拖到檢視視圖。
現在,將這五個補給物(不是子物體)復制到場景上,位置略高于地面,如下圖所示。
運行游戲。控制玩家移動到每個補給上。
當主角接觸到補給的時候,會獲得增益,并且補給物會消失。
如圖所示。下一章將會添加一個UI來查看這些增益效果。
3.5補給刷新點生成
步驟1 創建補給點
在層級視圖中刪除所有的Pickup和Robot游戲對象。
創建一個新的C#腳本,將其命名為“PickupSpawn”,并添加字段。
pickups將保存所有補給類型。現在添加以下方法:
// 1void spawnPickup() {// Instantiate a random pickup GameObject pickup = Instantiate(pickups[Random.Range(0,pickups.Length)]); pickup.transform.position = transform.position; pickup.transform.parent = transform;} // 2IEnumerator respawnPickup() { yield return new WaitForSeconds(20); spawnPickup();} // 3void Start() { spawnPickup();} // 4public void PickupWasPickedUp() { StartCoroutine("respawnPickup");}下面是每個方法的工作:
①實例化一個隨機類型的補給,并設置它的位置。
②在調用spawnPickup方法之前等待20秒。
③在自身實例化時生成一個補給。
④當玩家撿起補給時,重置協同方法。
保存腳本。打開Pickup腳本,然后在Destroy(gameObject)上添加以下行:
當補給與主角相撞時,將在PickupSpawn腳本上啟動生成計時器。
保存腳本回到Unity。
創建一個空的游戲對象,命名為“PickupSpawn”,并添加PickupSpawn腳本。
選中PickupSpawn的游戲對象,設置其Pickups屬性的Size為5。
Lock檢視視圖。將Resources文件夾中的PickupAmmoAssaultRifle、PickupAmmoPistol、PickupAmmoShotgun、PickupHealth和 PickupArmor預設分別拖入到Pickups元素中。
最后,UnLock檢視視圖。
步驟2 設置所有補給點
現在,將PickupSpawn游戲對象拖到Resources文件夾中,創建一個預制體。
創建一個空的游戲對象,命名為“PickupSpawns”。將其Position設置為 (0、0、0)。將PickupSpawn拖入到PickupSpawns,使其成為PickupSpawns的子物體。然后再復制出六個。
為了保持整潔,將每個子對象名稱都更改為“PickupSpawn”。
如下圖所示。
從最頂部PickupSpawn的游戲對象開始設置位置:
運行游戲,會看到七個補給生成在場景中。走過去,把它們撿起來。
步驟3 創建傳送點
現在,補給已經可以自動生成了,下面來實現機器人的自動生成。
將Teleporter預置從Resources文件夾拖到場景的根目錄下。
創建一個C#腳本,將其命名為“RobotSpawn”。
在代碼編輯器中打開它,并在類的“{”之后添加以下變量:
Robots保存了將要用來實例化的所有類型的機器人預制體。
healthBonus 是每個機器人每波獲得多少生命值,當玩家活得越久,游戲將變得越難。
timesSpawned 是機器人的生成周期。
接下來添加以下方法:
public void SpawnRobot() { timesSpawned++; healthBonus += 1 * timesSpawned; GameObject robot = Instantiate(robots[Random.Range(0,robots.Length)]); robot.transform.position=transform.position; robot.GetComponent<Robot>().health += healthBonus; }SpawnRobot ()方法用來實例化一個機器人,并設置它的生命值和位置。
保存腳本回到Unity。
將RobotSpawn腳本拖到Teleporter游戲對象上。在層級視圖中選擇Teleporter游戲對象,然后將RedRobot、YellowRobot和BlueRobot預制體從Resource文件夾中拖到檢視視圖的Robots字段中。
步驟4 設置所有傳送點
在層級視圖中,創建一個空的游戲對象,將其命名為“RobotSpawns”,并將其位置設置為 (0、0、0)。將Teleporter拖到RobotSpawns中,然后通過該Ctrl+D鍵復制三個。都重命名為“Teleporter”,如下圖所示。
從最上面的Teleporter游戲對象開始,依次設置他們的位置
步驟5 創建游戲管理器
創建一個C#腳本,將它命名為“Game”,并將文件的內容替換為:
private static Game singleton; [SerializeField] RobotSpawn[] spawns; public int enemiesLeft;singleton引用自身,實現單例模式。因為只有一個游戲,所以只需要一個Game對象來跟蹤得分、剩余機器人數量和當前的波數。
這些數據將在下一章實現,現在Game類只實現初始化機器人傳送器。
spawns是機器人傳送器的數組,它們每波產生機器人。
enemiesLeft跟蹤游戲中有多少機器人還活著。
接著添加以下方法:
// 1 void Start() { singleton = this; SpawnRobots();} // 2 private void SpawnRobots() { foreach (RobotSpawn spawn in spawns) { spawn.SpawnRobot();enemiesLeft++; }}代碼說明如下:
①初始化單例并調用SpawnRobots ()。
②遍歷數組中的每個 RobotSpawn 并調用 SpawnRobot () 來生成一個機器人。
保存腳本回到Unity。
創建一個空的游戲對象,命名為“Game”。將Game腳本拖到這個對象上,如下圖所示。
選中Game游戲對象并鎖住檢視視圖。將Teleporter游戲對象全部拖到Spawns字段上。
運行游戲,會看到生成了四個機器人
3.6添加聲音
步驟1 添加音頻
大部分內容已經建立完畢,現在還差一點點的聲音。打開Robot腳本并在頂部添加以下內容:
[SerializeField]private AudioClip deathSound; [SerializeField]private AudioClip fireSound; [SerializeField]private AudioClip weakHitSound;保存腳本,回到Unity。
在Resources文件夾中通過Ctrl鍵加鼠標左鍵同時選中YellowRobot、RedRobot和BlueRobot預制體,
并將Fire Sound設置為missile、Death Sound設置為deadRobot,以及Weak Hit Sound設置為weakHitSound。
步驟2 實現聲音播放
打開Robot腳本,在Fire ()方法的“}”前添加如下代碼。
GetComponent<AudioSource>().PlayOneShot(fireSound);現在,修改 TakeDamage ()方法來播放一些聲音。使用如下代碼替換掉if (health <= 0)的內容。
if (health <= 0) { isDead = true; robot.Play("Die"); StartCoroutine("DestroyRobot"); GetComponent<AudioSource>().PlayOneShot(deathSound);} else {GetComponent<AudioSource>().PlayOneShot(weakHitSound);}保存腳本,回到Unity。運行游戲,會聽到更多的聲音!
總結
提示:終于把這個教程做完了,之前有些忙,導致16號才出,不好意思!!!
總結
以上是生活随笔為你收集整理的unity实战:狂暴机器人游戏教程(下篇)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c语言程序设计西南交通大学出版社答案,C
- 下一篇: android的contentprovi