RigidBody

Qu'est-ce qu'un corps rigide ?

Un corps rigide est un corps qui est directement contrôlé par le moteur physique afin de simuler le comportement des objets physiques. Pour définir la forme du corps, il doit avoir un ou plusieurs objets Shape assignés. Notez que le réglage de la position de ces formes affectera le centre de masse du corps.

Comment contrôler un corps rigide

Le comportement d'un corps rigide peut être modifié en réglant ses propriétés, telles que la friction, la masse, le rebond, etc. Ces propriétés peuvent être définies dans l'inspecteur ou via un code. Voir RigidBody pour la liste complète des propriétés et leurs effets.

Il y a plusieurs façons de contrôler le mouvement d'un corps rigide, selon l'application désirée.

Si vous n'avez besoin de placer qu'une seule fois un corps rigide, par exemple pour définir son emplacement initial, vous pouvez utiliser les méthodes fournies par le nœud Spatial, telles que set_global_transform() ou look_at(). Cependant, ces méthodes ne peuvent pas être appelées toutes les images ou le moteur physique ne sera pas capable de simuler correctement l'état du corps. Par exemple, considérez un corps rigide que vous voulez faire pivoter pour qu'il pointe vers un autre objet. Une erreur courante lors de l'implémentation de ce type de comportement est d'utiliser look_at() chaque image, ce qui casse la simulation physique. Ci-dessous, nous allons montrer comment implémenter correctement ceci.

Le fait que vous ne puissiez pas utiliser les méthodes set_global_transform() ou look_at() ne signifie pas que vous ne pouvez pas avoir un contrôle total sur un corps rigide. Au lieu de cela, vous pouvez le contrôler en utilisant le callback _integrate_forces(). Dans cette méthode, vous pouvez ajouter des forces, appliquer des impulsions, ou régler la vitesse afin d'obtenir le mouvement que vous souhaitez.

La méthode "look at"

Comme décrit ci-dessus, l'utilisation de la méthode look_at() du nœud Spatial ne peut pas être utilisée pour chaque image pour suivre une cible. Voici une méthode personnalisée look_at() qui fonctionnera de manière fiable avec des corps rigides :

extends RigidBody

func look_follow(state, current_transform, target_position):
    var up_dir = Vector3(0, 1, 0)
    var cur_dir = current_transform.basis.xform(Vector3(0, 0, 1))
    var target_dir = (target_position - current_transform.origin).normalized()
    var rotation_angle = acos(cur_dir.x) - acos(target_dir.x)

    state.set_angular_velocity(up_dir * (rotation_angle / state.get_step()))

func _integrate_forces(state):
    var target_position = $my_target_spatial_node.get_global_transform().origin
    look_follow(state, get_global_transform(), target_position)
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);
    }
}

Cette méthode utilise la méthode set_angular_velocity() du corps rigide pour faire tourner le corps. Il calcule d'abord la différence entre l'angle actuel et l'angle désiré, puis ajoute la vitesse nécessaire pour tourner de cette valeur dans le temps d'une image.

Note

Ce script ne fonctionnera pas avec les corps rigides en character mode car la rotation du corps est alors verrouillée. Dans ce cas, vous devrez faire tourner le nœud de maillage attaché à la place en utilisant les méthodes spatiales standard.