+1 vote

I'm making an Asteroids clone. When the player presses spacebar, the player's ship shoots a bullet. I want the bullet to inherit the velocity of the ship, as well as moving forward like a bullet does.

I've tried simply copying the velocity of the ship into the bullet when the bullet is created:

extends KinematicBody2D

const MOVE_SPEED = 7

var vel = Vector2()

func _ready():
    set_fixed_process(true)

    # inherit player velocity
    vel = get_node("/root/bg-root/game-root/player").get_linear_velocity()
    # add bullet velocity
    # vel += Vector2(sin(get_rot()), cos(get_rot())) 

func _fixed_process(delta):
    move(-vel) # negate to move aligned with sprite

For now I've commented out the line where I add the bullet's velocity, because I want to make sure I'm getting the ship's velocity correct first.

What happens is the bullet moves several times faster than the ship does. I've used print statements and the debugger and I've verified that the velocity being passed to the bullet is the same as the velocity of the ship. The bullet is added as a sibling of the ship, not a child, so its velocity should be relative to world space. The ship is a RigidBody2D, while the bullet is a KinematicBody2D, but I wouldn't think that makes any difference.

FWIW the velocity is typically in the range of 50 - 100 for both parts of the vector2, and I don't know what units it's supposed to be in but it seems high. Anyways, it shouldn't matter, if that's the velocity of the ship, then it should act the same on the bullet.

So, what's happening?

in Engine by (44 points)

Maybe OT & heavy BTW :) Bullet as KinematicBody2D is overkill, i tried it few days ago and have big problems with recognizing who i hit :) I ended up with Area2D (signal body_enter(other_body), checking what body i collide with, duct typing other_body.hit(dmg) and self.remove_from_bullet_space() (i use special layer for bullets & bullet manager to recycle nodes)) for bullets and RayCast2D (with is_colliding and get_collision_point() and setting scale to cut laser in length) for lasers :)

Thanks, that's a good idea. Originally I was even going to make the bullets RigidBody2D, as I wanted the impact of the bullet to affect the velocity of the hit object. But since there is only one case where the object would actually be affected (normally objects are deleted when a bullet hits them), it's definitely overkill.

I haven't worked with raycasts at all before, but since lasers in my game are just bullets with a different sprite, I don't think it's necessary.

1 Answer

+2 votes
Best answer

In 2D, units are pixels by default.
Did you checked the parent of the bullet stays in (0,0) ?

Also, I think that you should multiply the velocity by delta because get_linear_velocity() gets you a result in pixels/second, while move() expects pixels.

by (27,603 points)
selected by

Thank you! Multiplying by the delta worked. My fixed process now looks like this:

func _fixed_process(delta):
    move(vel * delta)

For some reason, doing that meant that I no longer have to negate vel. I'm not sure why.

As far as the parent goes, the node game-root is a plain old Node (not even Node2D), so it has no position, and is just used a container anyways, I'm not touching it at all in code.

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.