Arrow to shoot at the direction of the mouse , facing towards it

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Ninku
:warning: Old Version Published before Godot 3 was released.

I have a archer shooting arrow straight, every-time the mouse button is clicked.
I want the arrow to shoot at the direction of the mouse , facing towards it.

What function can I use and How would i go about writing this code ?

Thanks.

:bust_in_silhouette: Reply From: rustyStriker

I’m no expert at Godot but you can calculate the angle by using the delta X and delta Y of the mouse and archer, and using the opposite tan function. But be aware of the units since tan is usually in Rads and while the rotation is in degrees
hope i helped

Thanks for the comment. I am not sure how to implement that in a code but maybe my programmer friend might be able to.

Ninku | 2016-09-01 09:09

Well with a bit of trigonometry you can get the direction(what i wrote before) and the speed is determined by you so you are able to make a Vector2 for the speed using sin and cos functions

rustyStriker | 2016-09-01 12:26

:bust_in_silhouette: Reply From: ericdl

Instance the arrow and set it’s rotation toward the mouse pointer via get_angle_to andset_rot:

extends RigidBody2D
var shoot_speed = 10
var arrow = preload("res://path_to_arrow.tscn")

func _shoot_arrow():
var new_arrow = arrow.instance()
var arrow_rotation = get_angle_to(get_global_mouse_pos()) + self.get_rot()
new_arrow.set_rot(arrow_rotation)
new_arrow.set_global_pos(self.get_global_pos())
get_parent().add_child(new_arrow)
new_arrow.apply_impulse(Vector2(), ( get_global_mouse_pos() - self.get_global_pos() ) * shoot_speed)

Example project download: https://drive.google.com/file/d/0BwnfZQAEnciAOEU3YzhtUm40d1k/view?usp=sharing

Brilliant answer. Not my question (not the OP) but thank you. Learning every day in here.

Robster | 2016-09-01 04:51

Thanks that helped a lot and learned something new as well.

Is it possible to use the above code with
set_linear_velocity(Vector2( ) function ?
or
does it only work with apply_impulse(Vector2() function ?

Ninku | 2016-09-01 09:14

Sure you can use set_linear_velocity, it’s up to you. You will need to find the vector from the arrow to the mouse pointer, and you have two choices for setting the arrow speed:

Constant arrow velocity:

var shoot_speed = 10000
var arrow = preload("res://path_to_arrow.tscn")

#NOTE: need to pass in delta from func _fixed_process or func _process
func _shoot_arrow(delta):
	var new_arrow = arrow.instance()
	var arrow_rotation = get_angle_to(get_global_mouse_pos()) + self.get_rot()
	new_arrow.set_rot(arrow_rotation)
	new_arrow.set_global_pos(self.get_global_pos())
	get_parent().add_child(new_arrow)
	
	var rigidbody_vector = (get_global_mouse_pos()- self.get_pos()).normalized()
	new_arrow.set_linear_velocity(rigidbody_vector * shoot_speed * delta)

Velocity determined by mouse distance:

var shoot_speed = 50
var arrow = preload("res://path_to_arrow.tscn")

#NOTE: need to pass in delta from func _fixed_process or func _process
func _shoot_arrow(delta):
	var new_arrow = arrow.instance()
	var arrow_rotation = get_angle_to(get_global_mouse_pos()) + self.get_rot()
	new_arrow.set_rot(arrow_rotation)
	new_arrow.set_global_pos(self.get_global_pos())
	get_parent().add_child(new_arrow)
	
	var rigidbody_vector = (get_global_mouse_pos()- self.get_pos()).normalized()
	var mouse_distance = self.get_pos().distance_to(get_global_mouse_pos())
	new_arrow.set_linear_velocity(rigidbody_vector * shoot_speed * mouse_distance * delta)

ericdl | 2016-09-01 17:56

I see. Thanks alot.

Ninku | 2016-09-03 11:57