How to make a shot follow a character, Only when it is created??

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

Hello,

I have no idea how to do this :confused:
Can someone help me?
please

When you create a question, try specifying more on what you want to do. Is it 2D or 3D? What kind of shot is it? Can you give an example using other games?

henriquelalves | 2016-12-24 22:35

Thank you, the next I will put more details

ismaelgame7 | 2016-12-25 01:31

:bust_in_silhouette: Reply From: Zylann

Here is an example in 2D off top of my head. It shows how to create a shot, that heads toward a target but only “aims” when it is created (if the target moves, the shot continues forward).
Warning: it’s not copy/paste-ready, just showing how this usually works:

# You can design the shot in a scene so you can instance it multiple times
var shot = preload("shot.tscn").instance()

# When the shot gets created it should be placed at its start position
shot.set_pos(gun.get_global_pos())

# Use some simple vector math to get the direction in which the shot will go
# (target could be a character node)
# I used global pos here because shots travel in the world, not locally to the gun.
var direction = (target.get_global_pos() - gun.get_global_pos()).normalized()

# Then we set the motion vector so the shot will know where to go, in pixels/seconds.
# This code assumes shot is a RigidBody2D, but if you handle it yourself it's fine too.
# You should also decide which speed you want it to have.
shot.set_linear_velocity(direction * speed)

# Don't forget to actually place the shot into the world
world.add_child(shot)

The same applies to 3D, with a bit of changes in function names.

“Invalid call. Nonexistent function ‘set_pos’ in base ‘PackedScene’.”.
shot.set_pos(pumpkin.get_global_pos())

The debugger say this.
“Gus” is one variable ? would be the position where the shot comes out?

“shot.set_linear_velocity(direction * speed)”
Can I use get_pos instead the of linar_velocity to my area2D?

ismaelgame7 | 2016-12-25 02:16

The “invalid call” on PackedScene means you forgot to call instance(). Calling instance on a PackedScene gives you a new instance of that scene on which you can call stuff like get_pos() if the root inherits Node2D.

“Gus”: I don’t see Gus written anywhere in this thread, maybe you meant “Gun”?
the variables I used in my code are supposed to exist in the context, I don’t know your whole project but I can give you an example how to achieve things. It just means that, in order to make a shot move towards something, you need to know where it comes from (the gun) and where it should go (the target) and at which speed (speed). You can probably get these variables by using get_node or having members defined in your scripts.

shot.set_linear_velocity is meant to tell a physical node to move in a given direction at a specific speed (until it eventually hits something). I used this example assuming it could be a RigidBody, but if you want to calculate motion manually, here is how you can do on your Shot node:

# How many pixels the shot travels vertically and horizontally per second
var velocity = Vector2(0,0)

func _ready():
	# Tell Godot to call _fixed_process at every physic frame
	set_fixed_process(true)

# Call this function when the shot is created so you can set the speed
func set_linear_velocity(v):
    velocity = v

func _fixed_process(delta):
	# This is a basic movement formula with which the node will move in a straight line
    set_pos(get_pos() + velocity * delta)

Zylann | 2016-12-25 15:07

I rephrase the first example you did and it worked!!

var speed = 100

func _ready():
set_process(true)
enemy = get_node("Area2D")
hero = get_parent().get_node("Player")
pass

func _process(delta):
shoot()
pass

func shoot():
var shot = preload("res://shot.tscn").instance()
shot.set_pos(enemy.get_global_pos())
var direction = (hero.get_global_pos() - enemy.get_global_pos()).normalized()
shot.set_linear_velocity(direction * speed)
get_parent().get_node(".").add_child(shot)
pass

Thanks for helping me! :smiley:

ismaelgame7 | 2016-12-25 23:44