Up to date

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

Using RigidBody

리지드 바디(rigid body)란?

A rigid body is one that is directly controlled by the physics engine in order to simulate the behavior of physical objects. In order to define the shape of the body, it must have one or more Shape3D objects assigned. Note that setting the position of these shapes will affect the body's center of mass.

리지드 바디를 제어하는 방법

A rigid body's behavior can be altered by setting its properties, such as mass and weight. A physics material needs to be added to the rigid body to adjust its friction and bounce, and set if it's absorbent and/or rough. These properties can be set in the Inspector or via code. See RigidBody3D and PhysicsMaterial for the full list of properties and their effects.

원하는 용도에 따라 리지드 바디의 움직임을 제어하는 몇 가지 방법이 있습니다.

If you only need to place a rigid body once, for example to set its initial location, you can use the methods provided by the Node3D node, such as set_global_transform() or look_at(). However, these methods cannot be called every frame or the physics engine will not be able to correctly simulate the body's state. As an example, consider a rigid body that you want to rotate so that it points towards another object. A common mistake when implementing this kind of behavior is to use look_at() every frame, which breaks the physics simulation. Below, we'll demonstrate how to implement this correctly.

set_global_transform()이나 look_at()의 방법을 사용할 수 없다는 사실이 리지드 바디를 완전히 통제할 수 없다는 것을 의미하지는 않습니다. 대신 _integrate_forces() 콜백을 사용하여 제어할 수 있습니다. 이 기능에서 원하는 이동을 달성하기 위해 forces를 추가하거나 impulses를 적용하거나 velocity를 설정할 수 있습니다.

"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 변형(transform) 사용하기.