Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

使用 RigidBody

什麼是剛體?

剛體是直接由物理引擎控制以類比物理物件行為的物體. 為了定義物體的形狀, 必須分配一個或多個 Shape 對象. 注意, 設定這些形狀的位置將影響物體的重心.

如何控制剛體

剛體的行為可以通過設定其屬性來改變,比如品質和重量。需要給剛體新增一個物理材質來調整它的摩擦力和反彈力,並設定它是否具有吸收性、粗糙度。這些屬性可以在屬性面板中或通過程式碼來設定。參見 RigidBodyPhysicsMaterial 獲取完整的屬性列表和它們的效果。

有幾種方法可以控制剛體的運動, 這取決於您的應用程式.

如果你只需要放置一次剛體, 例如設定它的初始位置, 你可以使用 Spatial 節點提供的方法, 例如 set_global_transform()look_at() . 但是, 這些方法不能每一影格都被呼叫, 否則物理引擎將無法正確地類比物體的狀態. 舉個例子, 考慮一個剛體, 你想旋轉它, 使它指向另一個對象. 在實作這種行為時, 一個常見的錯誤是每一影格都使用 look_at() , 這樣會破壞物理類比. 下面, 我們將演示如何正確地實作這一點.

你不能使用 set_global_transform()look_at() 方法並不意味著你不能完全控制一個剛體. 相反, 你可以通過使用 _integrate_forces() 回呼函式來控制它. 在這個方法中, 你可以新增 , 應用 脈衝 , 或者設定 速度 , 以實作你想要的任何運動.

“look at”方法

As described above, using the Node3D's look_at() method can't be used each frame to follow a target. Here is a custom look_at() method called look_follow() that will work with rigid bodies:

extends RigidBody3D

var speed: float = 0.1

func look_follow(state: PhysicsDirectBodyState3D, current_transform: Transform3D, target_position: Vector3) -> void:
    var forward_local_axis: Vector3 = Vector3(1, 0, 0)
    var forward_dir: Vector3 = (current_transform.basis * forward_local_axis).normalized()
    var target_dir: Vector3 = (target_position - current_transform.origin).normalized()
    var local_speed: float = clampf(speed, 0, acos(forward_dir.dot(target_dir)))
    if forward_dir.dot(target_dir) > 1e-4:
        state.angular_velocity = local_speed * forward_dir.cross(target_dir) / state.step

func _integrate_forces(state):
    var target_position = $my_target_node3d_node.global_transform.origin
    look_follow(state, global_transform, target_position)

This method uses the rigid body's angular_velocity property to rotate the body. The axis to rotate around is given by the cross product between the current forward direction and the direction one wants to look in. The clamp is a simple method used to prevent the amount of rotation from going past the direction which is wanted to be looked in, as the total amount of rotation needed is given by the arccosine of the dot product. This method can be used with axis_lock_angular_* as well. If more precise control is needed, solutions such as ones relying on Quaternion may be required, as discussed in 使用 3D 變換.