0 votes

I'm very new to Godot, so it's likely I'm making some simple mistake. I've done my best to look online and in the docs, but I haven't found anything.

My project is very simple. The main scene has a camera, a flat cube mesh as a floor, and a (space)ship. The ship is a RigidBody. It has six MeshInstance and a CollisionShape, all direct children of the RigidBody. The only change I've made to the project settings is to add some things to the input map and to set the default gravity to zero.

There's only one script file, and it's attached to Main2 (the root node of my scene). I've deleted a lot of stuff and I think this is the bare-bones script that will reproduce the problem. I've included the entire script file at the bottom of the post. If you press "Q" (bound to "gamerollleft"), the ship rolls left, and if you press "W", the ship pitches down.

The problem is: if I alternate Q and W quickly, the ship transforms as expected, but after about a dozen total keypresses, the entire ship disappears, and I get the following error:

0:00:05:0887 - Condition ' p_axis.is_normalized() == false ' is true.
----------
Type:Error
Description: 
Time: 0:00:05:0887
C Error: Condition ' p_axis.is_normalized() == false ' is true.
C Source: core/math/matrix3.cpp:751
C Function: set_axis_angle

I have no idea what's going on. It's not always the exact same number of inputs, but it's usually at least ten. I assume I'm misusing some function or have set up my ship node wrong somehow, but I have no clue. Please help!

Main2.gd

extends Spatial

var ship

var yaw_rate = 30
var pitch_rate = 30
var roll_rate = 30

func _ready():
    ship = get_node("/root/Main2/Ship4")

func _process(delta):
    if Input.is_action_just_pressed("ui_accept"):
        get_tree().reload_current_scene()

func _physics_process(delta):           
    if Input.is_action_just_pressed("game_pitch_down"):
        ship.rotate(ship.get_global_transform().basis.x,-deg2rad(pitch_rate))

    if Input.is_action_just_pressed("game_roll_left"):
        ship.rotate(ship.get_global_transform().basis.z,deg2rad(roll_rate))
asked Aug 7 in Engine by SrMeowMeow (17 points)

1 Answer

0 votes
Best answer

When working with a RigidBody, especially when altering its physics state, you need to use _integrate_forces() as your callback, rather than _physics_process().

More information here:
http://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html

http://docs.godotengine.org/en/latest/tutorials/physics/rigid_body.html
Note: The "look_at" function demonstrated in this tutorial is very similar to what you're trying to do.

answered Aug 7 by kidscancode (4,890 points)
selected Aug 7 by SrMeowMeow

That's the kind of thing I was afraid of. Thanks! I'll look into it.

This is beyond the scope of the question, but it sounds like if I want to manually rotate instead of applying forces, a RigidBody is the wrong node type. Do you have a suggestion for what I should use instead?

Not necessarily. You just have to be aware of the fact that you have to work with the physics engine not against it when using one. Kinematic body is another option, but it all depends on what kind of behavior you're going for. If you don't need physics at all, but just collision, use kinematic. If you don't need collision or physics, and want to manually control rotation/movement, use a plain Spatial.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.