「開火」就是發射子彈的意思,在戰爭類型的電影或者電視劇中,主角們就愛這麼說!本節打算爲精靈添加發射子彈的能力。由於本遊戲在後面會引入敵人,而精靈最好具有開火的能力,不然會被敵人輕易幹掉!具體的實現方法是:函數
(1)導入一個表示子彈的圖片到Unity,本示例中選用的子彈圖片,名爲PlayerBullet,如圖2-23所示。動畫
圖2-23 導入到遊戲項目的表示子彈的圖片ui
(2)拖動此圖片到Scene視圖,便可在當前的遊戲場景中添加此對象,爲此對象添加RigidBody 2D組件,並設置組件的下列屬性,如圖2-24所示。spa
q Gravity Scale:0。表示子彈對象將不受重力的影響,因此不會偏離預約的發射軌道;orm
圖2-24 設置子彈對象上各組件的屬性對象
(3)在Project視圖裏,新建一個C#腳本,命名爲PlayerBulletController,爲此腳本添加下面的代碼:教程
01 using UnityEngine;遊戲
02 using System.Collections;事件
03 圖片
04 public class PlayerBulletController : MonoBehaviour
05 {
06 public GameObject playerObject = null; //表示精靈對象
07 public float bulletSpeed = 15.0f; //表示子彈的速度
08 private float selfDestructTimer = 0.0f; //表示子彈自我銷燬的時間
09 void Update()
10 {
11 //在一段時間之後銷燬子彈對象
12 if(selfDestructTimer > 0.0f)
13 {
14 if(selfDestructTimer < Time.time)
15 Destroy(gameObject);
16 }
17 }
18 //調用此函數發射子彈
19 public void launchBullet()
20 {
21 //肯定精靈對象的朝向
22 float mainXScale = playerObject.transform.localScale.x;
23 Vector2 bulletForce; //對子彈施加的力的方向
24 //若是精靈對象面朝左,則向左發射子彈
25 if(mainXScale < 0.0f)
26 {
27 bulletForce = new Vector2(bulletSpeed * -1.0f,0.0f);
28 }
29 //若是精靈對象面朝右,則向右發射子彈
30 else
31 {
32 bulletForce = new Vector2(bulletSpeed,0.0f);
33 }
34 //施加給子彈對象一個指定方向的力
35 rigidbody2D.velocity = bulletForce;
36 //在1秒後銷燬子彈對象
37 selfDestructTimer = Time.time + 1.0f;
38 }
39 }
將此腳本賦予場景中的子彈對象,選中後者,而後在Inspector視圖裏能夠設置此腳本組件的Bullet Speed屬性,用於修改子彈的發射速度,如圖2-25所示。
圖2-25 腳本組件的屬性設置
將Hierarchy視圖裏的子彈對象,拖動到Project視圖,便可建立一個子彈對象的預置資源,以備後面腳本中的代碼使用。
(4)在PlayerStateController腳本中,添加精靈開火的狀態,且指定當玩家按下鼠標左鍵的時候,精靈將進入開火狀態,要添加的代碼以下:
01 using UnityEngine;
02 using System.Collections;
03
04 public class PlayerStateController : MonoBehaviour
05 {
06 //定義遊戲人物的各類狀態
07 public enum playerStates
08 {
09 … //省略
10 falling, //表示降落過程
11 firingWeapon //表示開火
12 }
13 //定義委託和事件
14 public delegate void playerStateHandler(PlayerStateController.playerStates newState);
15 public static event playerStateHandler onStateChange;
16 void LateUpdate ()
17 {
18 … //省略
19 //當玩家按下鼠標的左鍵時,進入開火狀態
20 float firing = Input.GetAxis("Fire1");
21 if(firing > 0.0f)
22 {
23 if(onStateChange != null)
24 onStateChange(PlayerStateController.playerStates.firingWeapon);
25 }
26 }
27 }
(5)在Hierarchy視圖裏,新建一個Empty對象,命名爲BulletSpawnPoint。拖動它到Player對象下,使其成爲Player對象的子對象。而後調整BulletSpawnPoint對象的位置,使其位於精靈發射子彈時,子彈的出現位置。在本示例中,它們的相對位置如圖2-26所示。
圖2-26 設置開火時,子彈的發射位置
(6)在PlayerStateListener腳本中,添加代碼用於處理精靈進入開火狀態時,開火的遊戲邏輯,要添加的代碼以下:
01 using UnityEngine;
02 using System.Collections;
03
04 [RequireComponent(typeof(Animator))]
05 public class PlayerStateListener : MonoBehaviour
06 {
07 … //省略
08 public GameObject bulletPrefab = null; //表示子彈對象
09 public Transform bulletSpawnTransform; //表示建立子彈的位置
10 … //省略
11 //當角色的狀態發生改變的時候,調用此函數
12 public void onStateChange(PlayerStateController.playerStates newState)
13 {
14 //若是狀態沒有發生變化,則無需改變狀態
15 if(newState == currentState)
16 return;
17 //判斷精靈可否由當前的動畫狀態,直接轉換爲另外一個動畫狀態
18 if(!checkForValidStatePair(newState))
19 return;
20 //經過修改Parameter中Walking的值,修改精靈當前的狀態
21 switch(newState)
22 {
23 … //省略
24 case PlayerStateController.playerStates.firingWeapon:
25 //實例化一個子彈對象
26 GameObject newBullet = (GameObject)Instantiate(bulletPrefab);
27 //設置子彈的起始位置
28 newBullet.transform.position = bulletSpawnTransform.position;
29 //創建與子彈對象上PlayerBulletController組件的聯繫
30 PlayerBulletController bullCon = newBullet.GetComponent<PlayerBulletController>();
31 //設定子彈對象上的PlayerBulletController組件的player object屬性
32 bullCon.playerObject = gameObject;
33 //發射子彈
34 bullCon.launchBullet();
35 break;
36 }
37 //記錄角色當前的狀態
38 currentState = newState;
39 }
40 //用於確認當前的動畫狀態可否直接轉換爲另外一動畫狀態的函數
41 bool checkForValidStatePair(PlayerStateController.playerStates newState)
42 {
43 bool returnVal = false;
44 //比較兩種動畫狀態
45 switch(currentState)
46 {
47 … //省略
48 case PlayerStateController.playerStates.jump:
49 if( newState == PlayerStateController.playerStates.landing
50 || newState == PlayerStateController.playerStates.kill
51 || newState == PlayerStateController.playerStates.firingWeapon
52 )
53 returnVal = true;
54 else
55 returnVal = false;
56 break;
57 case PlayerStateController.playerStates.landing:
58 if( newState == PlayerStateController.playerStates.left
59 || newState == PlayerStateController.playerStates.right
60 || newState == PlayerStateController.playerStates.idle
61 || newState == PlayerStateController.playerStates.firingWeapon
62 )
63 returnVal = true;
64 else
65 returnVal = false;
66 break;
67 case PlayerStateController.playerStates.falling:
68 if(
69 newState == PlayerStateController.playerStates.landing
70 || newState == PlayerStateController.playerStates.kill
71 || newState == PlayerStateController.playerStates.firingWeapon
72 )
73 returnVal = true;
74 else
75 returnVal = false;
76 break;
77 case PlayerStateController.playerStates.firingWeapon:
78 returnVal = true;
79 break;
80 }
81 return returnVal;
82 }
83 }
對於此腳本,有如下幾點須要說明:
q 腳本08、09行的代碼,使得腳本組件中多出了兩個屬性設置框,如圖2-27所示。須要依次設置爲子彈預置對象和子彈的生成位置。
圖2-27 腳本組件上增長的兩個屬性,須要手動設置屬性值
q 腳本12行,定義的方法onStateChange()裏面添加的代碼,表示精靈處於開火狀態時,將在指定位置上實例化一個子彈的預置對象,而後經過給子彈施加一個力來將它發射出去。
q 腳本41行,定義的方法checkForValidStatePair()裏面添加的代碼,表示處於jump、landing和falling狀態的精靈,能夠轉換爲firingWeapon,即開火狀態。
(7)運行遊戲,當按下鼠標的左鍵時,精靈將發射子彈,並且精靈能夠在任何狀態下發射子彈,如圖2-28所示。
圖2-28 精靈開火狀態的運行效果
本文選自:Unity 2D遊戲開發快速入門大學霸內部資料,轉載請註明出處,尊重技術尊重IT人!