Godot physic problem

Godot Version

v4.1.1.stable.mono.official [bd6af8e0e]

Question

I’m making a game about space. I have zero gravity there. I noticed that moving objects (Rigidbody3D) slow down over time when no forces are acting on them. Although the Dump is 0. Most likely it’s about the object settings, but just in case, I’ll attach the code.

using Godot;
using System;
using System.Collections.Generic;

public partial class Player : RigidBody3D
{
	[Export]
	public float MouseSensitivity = 0.3f;
	[Export]
	public Camera3D Camera;
	[Export]
	public float Speed = 5.0f;

	private RigidBody3D Arm;
	private List<RigidBody3D> Brm = new List<RigidBody3D>();

	private Vector3 _rotation = new Vector3();
	private Vector3 _rotation2 = new Vector3();
	private Vector3 _movement = new Vector3();
	public override void _Ready()
	{
		LinearDamp = AngularDamp = 0;
		Input.MouseMode = Input.MouseModeEnum.Captured;
		GetNode<MultiplayerSynchronizer>("MultiplayerSynchronizer").SetMultiplayerAuthority(int.Parse(Name));
	}

	public override void _Input(InputEvent @event)
	{
		if (@event is InputEventMouseMotion mouseMotionEvent)
		{
			_rotation.X -= mouseMotionEvent.Relative.Y * MouseSensitivity;
			_rotation.Y -= mouseMotionEvent.Relative.X * MouseSensitivity;

			_rotation.X = Mathf.Clamp(_rotation.X, -90, 90);
			_rotation.Y = Mathf.Clamp(_rotation.Y, -90, 90);
		}
	}

	public override void _Process(double delta)
	{
		if (GetNode<MultiplayerSynchronizer>("MultiplayerSynchronizer").GetMultiplayerAuthority() == Multiplayer.GetUniqueId())
		{
			Camera.RotationDegrees = new Vector3(_rotation.X, _rotation.Y, 0);

			if (Arm != null)
			{
				_movement = new Vector3();
				_rotation2 = new Vector3();

				if (Input.IsActionPressed("forward"))
				{
					_movement -= GlobalTransform.Basis.Z;
				}
				if (Input.IsActionPressed("back"))
				{
					_movement += GlobalTransform.Basis.Z;
				}
				if (Input.IsActionPressed("left"))
				{
					_movement -= GlobalTransform.Basis.X;
				}
				if (Input.IsActionPressed("right"))
				{
					_movement += GlobalTransform.Basis.X;
				}
				if (Input.IsActionPressed("down"))
				{
					_movement -= GlobalTransform.Basis.Y;
				}
				if (Input.IsActionPressed("up"))
				{
					_movement += GlobalTransform.Basis.Y;
				}

				if (Input.IsActionPressed("rot-up"))
				{
					_rotation2 -= Transform.Basis.Z;
				}
				if (Input.IsActionPressed("rot-down"))
				{
					_rotation2 += Transform.Basis.Z;
				}
				if (Input.IsActionPressed("rot-forward"))
				{
					_rotation2 -= Transform.Basis.X;
				}
				if (Input.IsActionPressed("rot-back"))
				{
					_rotation2 += Transform.Basis.X;
				}
				if (Input.IsActionPressed("rot-left"))
				{
					_rotation2 -= Transform.Basis.Y;
				}
				if (Input.IsActionPressed("rot-right"))
				{
					_rotation2 += Transform.Basis.Y;
				}

				if (Input.IsActionPressed("stop"))
				{
					_movement = -LinearVelocity;
					_rotation2 = -AngularVelocity;

					foreach(var a in GetParent().GetChildren()){
						if (a.GetType() == typeof(sample))
							((sample)a).Unweld();
					}
				}

				_movement = _movement.Normalized() * Speed;
				_rotation2 = _rotation2.Normalized() * Speed;
			}
		}
	}

	private void ApplyMovement()
	{
		float playerMass = Mass;
		float targetMass = Arm.Mass;

		Vector3 playerVelocity = _movement;
		Vector3 fixRot = new Vector3(_rotation2.Y, _rotation2.Z, _rotation2.X);
		Vector3 targetVelocity = -(playerVelocity + fixRot) * (playerMass / targetMass);

		ApplyCentralImpulse(playerVelocity * playerMass);
		ApplyTorqueImpulse(_rotation2 * playerMass);
		Arm.ApplyCentralImpulse(targetVelocity * targetMass);
	}

	public override void _PhysicsProcess(double delta)
	{
		if (Arm != null)
			ApplyMovement();
	}

	private void body_entered(Node3D body)
	{
		if (body.GetType() == typeof(sample))
		{
			RigidBody3D rbody = (RigidBody3D)body;
			Brm.Add(rbody);

			foreach (var b in Brm)
			{
				if ((Arm == null || Arm.Mass < b.Mass) && Arm != this)
					Arm = b;
			}
		}
	}

	private void body_exited(Node3D body)
	{
		if (body.GetType() == typeof(sample))
		{
			RigidBody3D rbody = (RigidBody3D)body;
			if (Arm == rbody)
				Arm = null;

			Brm.Remove(rbody);

			foreach (var b in Brm)
			{
				if ((Arm == null || Arm.Mass < b.Mass) && Arm != this)
					Arm = b;
			}
		}
	}
}

Please help me fix this. What Rigibody3D settings should I change or fix the code somehow so that Newton doesn’t turn over in his grave.

what about can_sleep ? it is on by default maybe it is stopping your rigidbody after a while. Or try using constant_force, check the docs for it : RigidBody2D — Godot Engine (stable) documentation in English

Are both linear damps zero? There’s the damp in the project’s settings and the damp in the rigid body itself. The one in the project’s settings default to 0.1.

4 Likes