Unity——滾動的小球


Unity——滾動的小球

工程理解

本游戲為通過鍵盤上的W、A、S、D鍵控制小球的運動軌跡來對固定位置上的小方塊進行碰撞,以此來進行加分計數的。

其中主要對象為小球和自轉的小方塊;在小球上,我們添加剛體和碰撞盒組件。剛體用於模擬真實的物理運動,碰撞盒子則用於與后面的

方塊進行碰撞檢測。

效果展示

核心代碼

PlayerController:

一、移動功能

用unity自帶的

 1 Input.GetAxis("") 

函數,Horizontal代表鍵盤的左右鍵(A和D鍵);Vertical代表鍵盤的上下鍵(W和S鍵)。然后用AddForce給予小球一個外力使其按照

相應的方向動起來。

 1 //通過鍵盤控制小球移動
 2 private void FixedUpdate()
 3     {
 4         var moveHorizontal = Input.GetAxis("Horizontal"); //水平方向
 5         var moveVertical = Input.GetAxis("Vertical");//垂直方向
 6         var movement = new Vector3(moveHorizontal, 0, moveVertical);
 7         //Vector3三維向量
 8         m_Rigidbody.AddForce(movement * Speed);
 9         //Speed 為速度 通過movement和Speed來控制小球的方向和速度
10     }

二、計數功能

  1. 定義了一個m_Count變量來計數小球碰到方塊的個數;

  2. 並通過

     1 GameObject.Destroy(other.gameObject); 

    語句,來對已經計數的方塊進行銷毀處理;(我們給方塊修改標簽”Tag”,如果小球碰撞的物體標簽是方塊的標簽名,我們則銷毀此方塊並讓分數加一)

  3. 調用

     1 SetCountText(); 

    函數,將計數傳給UI進行顯示。

 1 //計數功能
 2 private void OnTriggerEnter(Collider other)
 3     {
 4         if (other.gameObject.CompareTag("Pick Up"))
 5         {
 6             GameObject.Destroy(other.gameObject);//銷毀已記數方塊
 7             m_Count++;//計數
 8             SetCountText();//調用函數,將個數傳給UI進行顯示
 9         }
10     }
 

三、UI顯示功能

  1. 將計數功能所記的數目傳遞過來,通過

     1 CountText.text = m_Count.ToString();//計數UI顯示 

    語句,將所計數目通過UI顯示,其中CountText.text為UI計數的變量。

  2. 當所有小方塊都被碰撞到時,即m_Count >= 8(我這里給的小方塊個數為8個),輸出游戲成功信息,並儲存在WinText.text中。

1 private void SetCountText()
2     {
3         CountText.text = m_Count.ToString();//計數UI顯示
4 5         if (m_Count >= 8)
6         {
7             WinText.text = "You Win!";//成功提示
8         }
9     }
 

CameraController和Rotator:

 1 public class CameraController : MonoBehaviour
 2 {
 3     public GameObject Player;
 4     private Vector3 m_Offset;
 5     // Start is called before the first frame update
 6     void Start()
 7     {
 8         m_Offset = transform.position - Player.transform.position;
 9     }
10 
11     // Update is called once per frame
12     void Update()
13     {
14         transform.position = Player.transform.position + m_Offset;
15     }
16 }
1 public class Rotator : MonoBehaviour
2 {
3 
4     // Update is called once per frame
5     void Update()
6     {
7         transform.Rotate(new Vector3(15,30,45) * Time.deltaTime);
8     }
9 }

 

改進——框架

由於,假設將小方塊個數改為10個,則:

  1. 顯示得分的UI是寫在一起的,當修改相對應的限制條件時,會受到牽連

  2. 判定輸贏的邏輯也會受到牽連

  3. 顯示輸贏結算UI邏輯也在一起,也會受到牽連

所以利用框架進行改進

在框架中,

  • Player:負責接收玩家輸入並響應角色移動;當碰撞到小方塊時,通知Game Mode

  • Game Mode:對全局的游戲規則、玩法、計分等內容進行處理;在Player控制器通知Game Mode碰撞到小方塊后,Game Mode進行對應的計分和輸贏判斷等操作

  • 小方塊:在游戲啟動時把自己的存在告知Game Mode;這樣一來,Game Mode就完全直到當前場上有多少個小方塊,就可以動態的根據場上方塊數量來判斷輸贏,而不會在代碼中寫死邏輯了。

相關代碼:

PickupComponent:

1 public class PickupComponent : MonoBehaviour
2 {
3     // Start is called before the first frame update
4     private void Start()
5     {
6         //把自己注冊到GameMode
7         GameMode.Instance.RegisterPickUp(this);
8     }
9 }
 

PlayerController控制器:

 1 public class PlayerController : MonoBehaviour
 2 {
 3     public float Speed;
 4     
 5     private Rigidbody m_Rigidbody;
 6     
 7     private void Start()
 8     {
 9         m_Rigidbody = this.GetComponent<Rigidbody>();
10     }
11 12     private void FixedUpdate()
13     {
14         var moveHorizontal = Input.GetAxis("Horizontal");
15         var moveVertical = Input.GetAxis("Vertical");
16 17         var movement = new Vector3(moveHorizontal, 0, moveVertical);
18         
19         m_Rigidbody.AddForce(movement * Speed);
20     }
21 22     private void OnTriggerEnter(Collider other)
23     {
24         if (other.gameObject.CompareTag("Pick Up"))
25         {
26             var pickupComponent = other.gameObject.GetComponent<PickupComponent>(); 
27             if (pickupComponent == null)
28             {
29                 Debug.LogError("有一個Tag是Pickup的GameObject,卻沒有掛載Pickup相關組件");
30             }
31             GameMode.Instance.PlayerEnterPickup(pickupComponent);
32         }
33     }
34 35     
36 }
 

GameMode,統一管理游戲的玩法、得分判定、輸贏結果等內容的類:

 1 public class GameMode : MonoBehaviour
 2 { 
 3     public static GameMode Instance { get; private set; }
 4     [Header("計分Text")]
 5     public Text CountText;
 6  7     [Header("顯示Win的文本")]
 8     public Text WinText;
 9 10     private readonly List<PickupComponent> m_Pickups = new List<PickupComponent>();
11 12     private int _count;
13     private int m_Count
14     {
15         get => _count;
16         set
17         {
18             _count = value;
19             if (CountText != null)
20             {
21                 CountText.text = value.ToString();
22             }
23         }
24     }
25     
26     private void Awake()
27     {
28         if (Instance == null)
29             Instance = this;
30     }
31     public void RegisterPickUp(PickupComponent pickup)
32     {
33         m_Pickups.Add(pickup);
34     }
35     public void PlayerEnterPickup(PickupComponent pickup)
36     {
37         m_Pickups.Remove(pickup);
38         GameObject.Destroy(pickup.gameObject);
39         m_Count++;
40         if (m_Pickups.Count <= 0)
41         {
42             WinText.text = "You Win!";
43         }
44     }
45 46     private void Start()
47     {
48         WinText.text = string.Empty;
49         m_Count = 0;
50     }
51 52     private void Update()
53     {
54         if (m_Pickups.Count > 0)
55         {
56             var rotateValue = new Vector3(15, 30, 45) * Time.deltaTime;
57             foreach (var pickup in m_Pickups)
58             {
59                 pickup.transform.Rotate(rotateValue);
60             }
61         }
62     }
63 }
64

 

 




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM