• 2D
  • 2D movement: rotation to direction

Hello

I'm trying to get an object to move based on its rotation. I have the left and right keys turning the object in their respective direction. However, I can't figure out how to move the object forward or backward based on the direction. the code used to rotate the object is:


extends KinematicBody2D

var speed = 100
var trav = 50
var vel = Vector2()



func _ready():
    set_process(true)


func _process(delta):
	#anticlockwise rotation
	if Input.is_key_pressed(KEY_RIGHT):
		set_rotd(get_rotd() - trav * delta)
	#clockwise rotation
	elif Input.is_key_pressed(KEY_LEFT):
		set_rotd(get_rotd() + trav * delta)
	#forward movement
	elif Input.is_key_pressed(KEY_UP):
		vel = Vector2(speed , delta )	
	#backward movement
	elif Input.is_key_pressed(KEY_DOWN):
		vel = Vector2(-speed , delta)
	else:
		 vel = Vector2(0, 0)
	if Input.is_key_pressed(KEY_X):
		print(get_rotd())
	
	set_pos(get_pos() + vel * delta)

essentially, when KEY_UP is pressed, I want it to move forward relative to the rotation it is, and when KEY_DOWN is pressed it moves backward. How could I accomplish this?

You need to get the local Z-axis from the transform of the node to move a node forward in 3D (assuming the Z-axis is forward). Like this:

func _fixed_process(delta):
  var local_forward = get_transform().basis.z.normalized();
  if(Input.is_key_pressed(KEY_UP)):
    vel = local_forward * speed;
  elif (Input.is_key_pressed(KEY_DOWN)):
    vel = local_forward * speed * -1;

For 2D, you need to get the rotation, convert it to a vector, and multiple by speed. Like this:

func _fixed_process(delta):
   var rot = get_rot();
   if (Input.is_key_pressed(KEY_UP)):
     vel = Vector2(sin(rot), cos(rot)) * speed;
   elif (Input.is_key_pressed(KEY_DOWN)):
     vel = Vector2(sin(rot), cos(rot)) * speed * -1;

Thanks for answering the question, but I also have a follow up question:

I eventually want the object to be able to change direction whilst moving, i.e with the current state in the code, the object can rotate and move in the direction of rotation, but only independently of each other. Is there a way the code can be modified to let this occur:

extends KinematicBody2D

var speed = 100 var trav = 50 var vel = Vector2()

func _ready(): set_process(true)

func _process(delta): var rot = get_rot(); #anticlockwise rotation if Input.is_action_pressed("KEY_RIGHT"): set_rotd(get_rotd() - trav delta) #clockwise rotation elif Input.is_action_pressed("KEY_LEFT"): set_rotd(get_rotd() + trav delta) #forward movement elif Input.is_action_pressed("KEY_UP"): vel = Vector2(sin(rot), cos(rot)) speed; #backward movement elif Input.is_action_pressed("KEY_DOWN"): vel = Vector2(sin(rot), cos(rot)) speed -1; else: vel = Vector2(0, 0) if Input.is_action_pressed("KEY_DEBUG"): print(get_rotd()) set_pos(get_pos() + vel delta)

(note: does it have something to do with normalisation?)

The problem is how your looking for input, or rather the way your doing it. You need to change your code so that more than one key can be detected at once. Using your code above, it would look like this:

 Func _process(delta):
 
    var rot = get_rot()
 
   # Move left and right, but not at the same time. If both keys are pressed, then we will move right!
   if Input.is_action_pressed("KEY_RIGHT"):
      set_rotd(get_rotd() - trav * delta)
   elif Input.is_action_pressed("KEY_LEFT"):
      set_rotd(get_rotd() + trav * delta)
 
   # Move up and down, but not at the same time. If both keys are pressed, then we will move forward!
   if Input.is_action_pressed("KEY_UP"):
      vel = Vector2(sin(rot), cos(rot)) * speed;
   elif Input.is_action_pressed("KEY_DOWN"):
      vel = Vector2(sin(rot), cos(rot)) * speed * -1;
 
   # Other stuff...

As far as normalization goes, it takes a vector and clamps it's values from 0-1, sorta. I would recommend searching vector math, specifically normalization for more detail if your curious. In this case, normalization isn't the problem, but rather the problem is how your 'if' and 'elif' statements are setup.

Thanks! Looks like I've got some researching to do...