Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
Utilizzare i RigidBody
Che cos'è un corpo rigido?
Un corpo rigido è un corpo controllato direttamente dal motore di fisica per simulare il comportamento di oggetti fisici. Per definire la forma del corpo, è necessario che gli siano assegnati uno o più oggetti Shape3D. Si noti che l'impostazione della posizione di queste forme influenzerà il centro di massa del corpo.
Come controllare un corpo rigido
Il comportamento di un corpo rigido si può modificare impostandone le proprietà, come massa e peso. È necessario aggiungere un materiale fisico al corpo rigido per regolarne l'attrito e il rimbalzo, e impostarne la capacità di assorbimento e/o la ruvidità. Queste proprietà si possono impostare nell'Ispettore o tramite codice. Consultare RigidBody3D e PhysicsMaterial per l'elenco completo delle proprietà e dei relativi effetti.
Esistono diversi modi per controllare il movimento di un corpo rigido, a seconda dell'applicazione desiderata.
Se è necessario posizionare un corpo rigido una sola volta, ad esempio per impostarne la posizione iniziale, è possibile utilizzare i metodi forniti dal nodo Node3D, come set_global_transform() o look_at(). Tuttavia, questi metodi non si possono chiamare a ogni frame, altrimenti il motore di fisica non sarà in grado di simulare correttamente lo stato del corpo. Ad esempio, si consideri un corpo rigido che si desidera ruotare in modo che punti verso un altro oggetto. Un errore comune nell'implementazione di questo tipo di comportamento è utilizzare look_at() a ogni frame, interrompendo la simulazione fisica. Di seguito, mostreremo come implementarlo correttamente.
Il fatto che non sia possibile utilizzare i metodi set_global_transform() o look_at() non significa che non si possa avere il pieno controllo di un corpo rigido. È possibile controllarlo attraverso il callback _integrate_forces(). In questo metodo, è possibile aggiungere forze, applicare impulsi o impostare la velocità per ottenere qualsiasi movimento desiderato.
Il metodo "look at"
Come descritto in precedenza, il metodo look_at() di Node3D non si può utilizzare per seguire un obiettivo a ogni frame. Ecco un metodo look_at() personalizzato con il nome look_follow() che funziona con i corpi rigidi:
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)
using Godot;
public partial class MyRigidBody3D : RigidBody3D
{
private float _speed = 0.1f;
private void LookFollow(PhysicsDirectBodyState3D state, Transform3D currentTransform, Vector3 targetPosition)
{
Vector3 forwardLocalAxis = new Vector3(1, 0, 0);
Vector3 forwardDir = (currentTransform.Basis * forwardLocalAxis).Normalized();
Vector3 targetDir = (targetPosition - currentTransform.Origin).Normalized();
float localSpeed = Mathf.Clamp(_speed, 0.0f, Mathf.Acos(forwardDir.Dot(targetDir)));
if (forwardDir.Dot(targetDir) > 1e-4)
{
state.AngularVelocity = forwardDir.Cross(targetDir) * localSpeed / state.Step;
}
}
public override void _IntegrateForces(PhysicsDirectBodyState3D state)
{
Vector3 targetPosition = GetNode<Node3D>("MyTargetNode3DNode").GlobalTransform.Origin;
LookFollow(state, GlobalTransform, targetPosition);
}
}
Questo metodo utilizza la proprietà angular_velocity del corpo rigido per ruotarlo. L'asse attorno al quale ruotare è ricavato dal prodotto vettoriale tra la direzione in avanti attuale e la direzione in cui si desidera guardare. clamp è un metodo semplice utilizzato per impedire che la quantità di rotazione vada oltre la direzione in cui si desidera guardare, poiché la quantità totale di rotazione necessaria è data dall'arcocoseno del prodotto scalare. Questo metodo si può utilizzare anche con axis_lock_angular_*. Se è necessario un controllo più preciso, potrebbero essere necessarie soluzioni come quelle basate su Quaternion, come discusso in Utilizzare le trasformazioni 3D.