Could anyone please help a noob struggling to understand a shooting mechanic? (I am not good with physics)

Godot Version

4.3

Question

Any help is greatly appreciated, I am missing something so simple and this is the third night I am frustrated!

I have a projectile with the following code attached:

  • I think this code should fire the projectile towards the mouse position.
func _ready():
	var direction = (get_local_mouse_position() - to_local(global_position)).normalized()
	apply_impulse(direction * bullet_force, Vector2.ZERO)

I draw a line from the player to the mouse position so the player knows where the projectile will fire to:

func _process(delta: float) -> void:
	draw_trajectory(to_local(global_position), get_local_mouse_position())

func draw_trajectory(start_position: Vector2, end_position: Vector2):
	var array = [start_position, end_position.normalized() * line_length]
	line.points = array

Issue: The trajectory the projectile follows off.

  • The angle in which the projectile fires seems related to the distance from mouse to starting point.
  • I checked things like node positions, centre of gravity and physics settings.

The projectile ( a box ) is following the red path not the yellow path I want the box to follow.

func _ready():
	var direction = (get_local_mouse_position() - to_local(global_position)).normalized()
	apply_impulse(direction * bullet_force, Vector2.ZERO)

Have you confirmed with print statements that the direction is same as the line draw?

Also, have you tried global pos to get direction to see what that does?

1 Like

I think you overengineered some of the formulas with global/local conversions. I simplified your functions to use only global positions:

func _ready():
	var direction = (get_global_mouse_position() - global_position).normalized()
	apply_impulse(direction * bullet_force)
func _process(delta: float) -> void:
	draw_trajectory(global_position, get_global_mouse_position())

func draw_trajectory(start_position: Vector2, end_position: Vector2):
	line.clear_points()
	line.add_point(start_position)
	line.add_point(end_position)

And I was able to achieve this behavior, which I think is what you’re after:

1 Like

Can you confirm if the Godot symbol is a child of a Node?

In my scene, everything is a child of “Node” called main. so all objects are a child of Node that is why I used local rather than global.

My Global mouse position is off screen and local mouse correctly on the mouse.

Yep there is something off with my calculations!
LINE DIRECTION = (-345.2271, 277.3568)
IMPULSE DIRECTION = (0.642802, -0.766032)
IMPULSE DIRECTION * FORCE = (1285.605, -1532.064)
LINE DIRECTION = (-396.0638, 150.5798)
IMPULSE DIRECTION = (0.729159, -0.684345)
IMPULSE DIRECTION * FORCE = (1458.317, -1368.689)
LINE DIRECTION = (-436.3825, 80.47266)
IMPULSE DIRECTION = (0.780787, -0.624797)
IMPULSE DIRECTION * FORCE = (1561.575, -1249.594)

assuming these are the correct calculations:

	var direction = (get_local_mouse_position() - to_local(global_position)).normalized()
	print("IMPULSE DIRECTION = %s" % [direction])
	print("IMPULSE DIRECTION * FORCE  = %s" % [direction * bullet_force])
	apply_impulse(direction * bullet_force)

print("LINE DIRECTION = %s" % [to_local(global_position)-get_local_mouse_position()])

Can’t you use position instead of to_local(global_position)?
position returns a local position.