The rigid body of physics in game development

The rigid body of physics in game development

What is a rigid body?

A rigid body is a rigid body that is directly controlled by the physics engine to simulate the behavior of physical objects. In order to define the shape of the body, one or more Shape objects must be assigned to it. Please note that setting the position of these shapes will affect the center of gravity of the human body.

How to control a rigid body

The behavior of a rigid body can be changed by setting its properties (for example, friction, mass, bounce, etc.). These properties can be set in the inspector or through code. For a complete list of attributes and their effects, see RigidBody.

There are multiple ways to control the motion of a rigid body, depending on the application you need.

If you only need to place a rigid body once (such as setting its initial position), you can use the methods provided by the Spatial node, such as set_global_transform() or look_at(). However, these methods cannot be called every frame, otherwise the physics engine will not be able to simulate the state of the human body correctly. For example, consider a rigid body to be rotated so that it points to another object. A common mistake in implementing this behavior is to use look_at() every frame, which would break the physics simulation. Below, we will demonstrate how to correctly implement this.

The fact that you cannot use the set_global_transform() or look_at() methods does not mean that you cannot fully control the rigid body. Instead, you can control it by using the _integrate_forces() callback. In this method, you can add force, apply pulses or set speed to achieve any movement you want.

"Look" method

As mentioned above, the look_at() method using spatial nodes cannot follow the target in every frame. This is a custom method that looks_at() can be reliably combined with rigid bodies:

class Body : RigidBody
{
    
    
    private void LookFollow(PhysicsDirectBodyState state, Transform currentTransform, Vector3 targetPosition)
    {
    
    
        var upDir = new Vector3(0, 1, 0);
        var curDir = currentTransform.basis.Xform(new Vector3(0, 0, 1));
        var targetDir = (targetPosition - currentTransform.origin).Normalized();
        var rotationAngle = Mathf.Acos(curDir.x) - Mathf.Acos(targetDir.x);

        state.SetAngularVelocity(upDir * (rotationAngle / state.GetStep()));
    }

    public override void _IntegrateForces(PhysicsDirectBodyState state)
    {
    
    
        var targetPosition = GetNode<Spatial>("my_target_spatial_node").GetGlobalTransform().origin;
        LookFollow(state, GetGlobalTransform(), targetPosition);
    }
}

This method uses the set_angular_velocity() method of the rigid body to rotate the body. It first calculates the difference between the current angle and the required angle, and then adds the speed required for rotation within one frame.

note

This script is not suitable for rigid bodies in character mode, because that will lock the rotation of rigid bodies. In this case, you will have to use standard Spatial methods to rotate the additional mesh nodes.

Guess you like

Origin blog.csdn.net/qq_44273429/article/details/111312043