0 votes

I wrote a simple code for rotate an object, but when it's arrive to target angle, rotation does not stop and it's continuously rotate with no stop.

Character

var target_rotation = 0

func _physics_process(delta):
    var eps = 0.001
    if  abs(rotation_degrees.y - target_rotation) > eps:
        rotation_degrees.y += sign(target_rotation - rotation_degrees.y)
    else:
        # Rotation completed! Lets move it

func setAngle(a):
    target_rotation = a

Main

$Character.setAngle(225)
in Engine by (81 points)

1 Answer

0 votes

I tried your code and it behaves as expected. Rotation stops when it has to. I guess you are doing something wrong with how you call the setAngle() function. Try writing this in your main scene:

extends Spatial
onready var obj = $Character

func AngleSetter():
    obj.setAngle(360)

func _process(delta):
    if Input.is_action_pressed('ui_down'):
        AngleSetter()

It might be the case that you are trying to reference your Character object before it is initialized by the game. That's why we use the onready var obj = $Characterbit.

Also check that your else statement is correct. Try printing something when rotation comes to a stop just to see whether your else statement works properly.

by (1,859 points)

I use something similar to below code for calling setAngle() method:

func _input(event):
if event is InputEventKey:
    if event.pressed:
        if event.scancode == KEY_R:
            $Character.setAngle(225)

When I print rotation_degrees.y for debug, although the numbers are thought to be integers, they are decimal with precision part. So it's never reach exactly to 0. When I check it more accurate, I see that when I want to move the object with the below code inside else statement:

var direction = -global_transform.basis.z
velocity.y += gravity * delta
velocity.x += direction.x * speed
velocity.z += direction.z * speed
velocity = move_and_slide(velocity, Vector3.UP)

It seems that rotation_degrees.y changes with unknown reason, so when once again _physics_process(delta) called, The conditions goes true and so again rotation starts.

Rounding issues seem to cause this. Can you upload your project? And what exactly is it that you want to do? If you just want to check whether the object has reached its final rotation, then it will be suffice to create a variable that goes true when rotation is reached. Then check this variable to move the object as intended or emit a signal or something.
Furthermore, I was able to rotate the object using the in-built lerp method:

if rotation_degrees.y!=target_rotation:
        rotation_degrees.y = lerp(rotation_degrees.y, target_rotation, 0.02)

this works a little better because it doesn't check whether the result of abs(rotation_degrees.y - target_rotation) > eps

Having said that, I haven't been able to reproduce your issue. I do not see why your rotation resets, but it might be teh case that when you mess with its velocity, rotation also changes. That's why I suggest you do the check elsewise.

Here is what I'm doing, I use lerp as you said in my project, but as you can see rotation does not stop ever (on top left corner a label shows the status of object between rotating or moving). Also I commented my _physics_process(delta) which is based on my old way.

https://drive.google.com/file/d/1JQLpTJHOXDTdWi8ZujySLOEMv5RdREcX/view?usp=sharing

So lets clarify what I want to do:

  1. I want to set a target angle (not relative, but absolute on global space, ex: 0 degrees is -X and means North, 90 degrees is +Z and means West and so on) for object (0 to 360 or -180 to +180) and then smoothly (with adjustable speed) rotate to achieve that. Just rotating around one axis, Y. After rotation completed, move the object.

  2. So on, I want to set target angle for two axis Y and X, and smoothly rotate object to achieve both of them. After rotation completed, move the object.

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.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.