使用 Update() 與 FixedUpdate() 函數
在Unity中,Update()
和 FixedUpdate()
是兩個常用的函數,它們在處理遊戲物體的更新時有不同的應用場景。了解這兩個函數的區別,並在適當的情況下使用它們,是編寫高效且穩定的遊戲邏輯的關鍵。
1. Update() 函數
用途:
Update()
函數是每一幀都會被調用的函數,用於處理遊戲中與時間無關的更新邏輯。它通常用於處理玩家輸入、非物理驅動的物體運動、動畫控制等。
特點:
- 每幀調用:
Update()
在每個渲染幀都會被調用。幀率越高,Update()
的調用頻率就越高。 - 時間間隔不固定:由於幀率不固定,
Update()
函數的調用間隔也會隨著每幀的時間而變化。這意味著如果你的遊戲在不同設備上運行,Update()
的執行頻率可能會有所不同。
範例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public float moveSpeed = 5f;
void Update()
{
// 檢測玩家輸入並移動物體
float moveX = Input.GetAxis("Horizontal");
float moveY = Input.GetAxis("Vertical");
// 計算移動向量
Vector3 move = new Vector3(moveX, 0f, moveY) * moveSpeed * Time.deltaTime;
// 移動物體
transform.Translate(move);
}
}
在這個範例中,Update()
函數用來檢測玩家輸入並移動遊戲物體。由於移動不涉及物理引擎,使用 Update()
是合適的選擇。
2. FixedUpdate() 函數
用途:
FixedUpdate()
函數專門用來處理物理更新,如力、碰撞、剛體運動等。它保證在固定的時間間隔內被調用,因此非常適合用來處理物理計算,確保物理行為的一致性和穩定性。
特點:
- 固定時間間隔調用:
FixedUpdate()
的調用頻率與遊戲的物理時間步(通常為0.02秒)一致,這與幀率無關。 - 適用於物理運算:因為它在固定的時間間隔內調用,使用
FixedUpdate()
來處理物理運算可以保證物理模擬的一致性,即使在不同的幀率下也是如此。
範例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using UnityEngine;
public class PlayerPhysicsMovement : MonoBehaviour
{
public float moveForce = 10f;
private Rigidbody rb;
void Start()
{
// 獲取剛體組件
rb = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
// 檢測玩家輸入並應用力來移動物體
float moveX = Input.GetAxis("Horizontal");
float moveY = Input.GetAxis("Vertical");
// 計算並應用力
Vector3 force = new Vector3(moveX, 0f, moveY) * moveForce;
rb.AddForce(force);
}
}
在這個範例中,FixedUpdate()
用來處理玩家輸入並應用力來移動帶有剛體(Rigidbody)的物體。因為力的應用涉及物理運算,所以 FixedUpdate()
是更合適的選擇。
3. Update() 和 FixedUpdate() 的區別
- 調用頻率:
Update()
的調用頻率取決於遊戲的幀率,幀率越高,Update()
調用的次數越多。FixedUpdate()
以固定的時間間隔調用,與幀率無關,通常每秒調用50次(對應0.02秒的物理時間步長)。
- 適用場景:
- 使用
Update()
來處理非物理相關的遊戲邏輯,如玩家輸入、動畫更新、非物理驅動的物體運動等。 - 使用
FixedUpdate()
來處理涉及物理引擎的運算,如剛體運動、力的應用、碰撞檢測等。
- 使用
- 時間補償:
Update()
函數內的操作通常需要乘以Time.deltaTime
來補償幀率的波動,確保物體運動的一致性。FixedUpdate()
自動補償時間步,因此通常不需要額外的時間補償。
4. 組合使用 Update() 和 FixedUpdate()
在一些情況下,你可能需要同時使用 Update()
和 FixedUpdate()
來處理不同的邏輯。例如,在 Update()
中檢測玩家輸入,但在 FixedUpdate()
中應用物理運動:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using UnityEngine;
public class CombinedMovement : MonoBehaviour
{
public float moveForce = 10f;
private Rigidbody rb;
private Vector3 moveInput;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
// 在 Update 中檢測玩家輸入
float moveX = Input.GetAxis("Horizontal");
float moveY = Input.GetAxis("Vertical");
moveInput = new Vector3(moveX, 0f, moveY);
}
void FixedUpdate()
{
// 在 FixedUpdate 中應用力來移動物體
rb.AddForce(moveInput * moveForce);
}
}
在這個範例中,Update()
用來檢測玩家的輸入,而 FixedUpdate()
用來處理物理運動,這樣可以在不同幀率下保持物理行為的一致性。
小結
Update()
和 FixedUpdate()
是Unity中處理不同遊戲邏輯的關鍵函數。了解它們的區別和適用場景,並根據遊戲需求選擇適當的函數,可以讓你的遊戲邏輯更加穩定和高效。
本文章以 CC BY 4.0 授權