#RigidBody3D boat simulation not turning, wants to align force to the positive X axis

1 messages · Page 1 of 1 (latest)

thorn mantle
#

I have a RigidBody3D boat simulation that I'm working on. I have buoyancy set up and working, and I'm working on getting the propeller and rudder simulations working.

Here's the code I'm using for my ruddered propeller simulation. The node this runs from is an immediate child of the boat's rigidbody. effected_body is a reference to the boat body passed through export. _apply_thrust() is running in _physics_process():

func _ready():
    thrust_vector = Vector3(-1, 0, 0) * current_thrust_force
    steer_slider.min_value = -max_rudder_angle
    steer_slider.max_value = max_rudder_angle
    rudder_position_bar.min_value = -max_rudder_angle
    rudder_position_bar.max_value = max_rudder_angle
    
func _apply_thrust(delta):
    rudder_angle = target_rudder_angle#lerpf(rudder_angle, target_rudder_angle, rudder_response)
    rudder_position_bar.value = rudder_angle
    rotation_degrees.y = 180 - rudder_angle
    thrust_vector = -global_basis.x
    %InverseBasisArrow.global_basis = global_basis.inverse()
    effected_body.apply_force(current_thrust_force * thrust_vector, position)

TL;DR: why is my linear velocity only moving the boat along the global X axis? How would I make the linear velocity move the boat forward in the direction it's facing?

Additional Info
I also have a little slider set up in the game that changes the turning angle of the rudder.

Now with the way the script is running now, it physically rotates the rudder node and should be applying the thrust force along the negative x-axis of the rudder's global basis, and it should be happening at the rudder node's local position relative to the boat body (towards the end of the boat). I've also had it set up so that just the thrust vector is rotated() to match the rudder angle, but both do the same thing.

What actually happens in-game is different. Regardless of how I rotate the boat before starting the game, it always wants to move on the global x-axis only. If I change the rudder angle, the boat will sort of turn to face a certain angle, but it never turns completely around, and the linear velocity stays on the X axis. (see video)

After some testing around, I figured out that the angle the boat tries to face when turning is actually the boat node's global_basis.inverse(). I also figured out the angle it tries to align with is never more than 90 degrees to either side of the X- axis.

I tried setting thrust_vector to basis.x instead of thrust_vector = -global_basis.x, and that actually applies the angular force like I wanted, but the linear velocity is still only moving on the x axis.

My question
How can I get my linear velocity to move the boat forward in the direction it's facing? I feel like I have all of the clues as to why this isnt working, but I just can't seem to figure it out... I'm a little green on using transforms anyways, so that's probably not helping... Anyways, any help you can give is greatly appreciated!

(Picture: the gizmo shows where the propeller node is on the boat)

#

Here's the Video. The grey arrow points in the direction of the rudder's inverse global basis.

pine current
#

That rotation_degrees is most likely the problem. And forward is typically -Z in Godot (it even has a constant, Vector3.FORWARD)

pine current
# thorn mantle I have a RigidBody3D boat simulation that I'm working on. I have buoyancy set up...

Here's a new rudder (untested code), no putting non-rudder stuff inside, no references to the parent.

extends Node3D

@export_range(0, 360, 0.1, "radians_as_degrees") var rudder_range := deg_to_rad(45.0)

@export var rudder_speed := 1.0

var _target := 0.0
var _value := 0.0

func control_rudder(wire_value: float) -> void:
  _target = clampf(wire_value, -1.0, 1.0)

func _physics_process(delta: float):
  _value = move_toward(_value, _target, rudder_speed * delta)
  basis = Basis(Vector3.UP, _value * rudder_range)

var thrust_vector -> Vector3:
  get: return global_basis.z
thorn mantle
thorn mantle
#

I fixed the problem, it turned out to be something different. I have to apply the forward force from the center of the body, not from the end. It was causing the weird turning problems since some of the forces were canceling each other out. Thanks again for your help, though! I wouldn't have solved it without you pointing me in the right direction

#

Here's what I ended up doing to fix this:

basis = Basis(Vector3.UP, deg_to_rad(rudder_angle))
thrust_vector = (effected_body.basis.z)
effected_body.apply_force(current_thrust_force * basis.z * Vector3(1, 1, 0), position)
effected_body.apply_central_force(current_thrust_force * thrust_vector)