When i instance the scene the projectile doesn't move and cannot be fired. How do i fix this?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By javrocks

I can instance my Projectile scene into the main scene with

if Input.is_action_just_released(“ui_touch”):
var scene_instance = load(“res://Projectile.tscn”).instance()
add_child(scene_instance)

and then control/ fire the projectile, but when i instance the scene again by releasing ui_touch the projectile appears but it doesn’t move and cannot be fired. How do i fix this?

Do you have code that actually moves/animates the projectile?

Ertain | 2021-09-02 05:19

extends Area2D

onready var node := get_parent().get_node(“Area2D/Projectile/Arrow”)
var vec_start := Vector2.ZERO
var vec_fin := Vector2.ZERO

func _input(_event: InputEvent) → void:

                       #VECTOR
if Input.is_action_just_pressed("ui_touch"):
	vec_start = get_local_mouse_position().floor()
	vec_fin = vec_start
	
if Input.is_action_just_released("ui_touch"):
	vec_fin = get_local_mouse_position().floor()
			         #MOVEMENT
if Input.is_action_just_released("ui_touch"):
	node.dir = ((vec_start - vec_fin).normalized()*5000)

#Then in my projectile scene i move it by

extends KinematicBody2D #(Projectile)

var dir := Vector2.ZERO

func _physics_process(_delta: float) → void:
dir = move_and_slide(dir, Vector2.ZERO)

javrocks | 2021-09-02 14:15

Could you please edit that post she reformat that code? It’s hard to read.

Ertain | 2021-09-02 17:21

extends Area2D

onready var node := getparent().getnode("Area2D/Projectile/Arrow")
var vecstart := Vector2.ZERO
var vecfin := Vector2.ZERO


func _instance():
     var scene_instance = preload("res://Projectile.tscn").instance()
     add_child(scene_instance)

func input(event: InputEvent) -> void:

                   #VECTOR
  if Input.is_action_just_pressed("ui_touch"):
     vec_start = get_local_mouse_position().floor()
     vec_fin = vec_start

  if Input.is_action_just_released("ui_touch"):
      vec_fin = get_local_mouse_position().floor()

                 #MOVEMENT
  if Input.is_action_just_released("ui_touch"):
     _instance()
     node.dir = ((vec_start - vec_fin).normalized()*5000)

             #then in my Projectile scene the script is:

extends KinematicBody2D #(Projectile)

var dir := Vector2.ZERO

func _physics_process(_delta: float) -> void:
   dir = move_and_slide(dir, Vector2.ZERO)

javrocks | 2021-09-02 19:29

The values from the input may not be reaching the desired node. Have you been able to check the value of dir after it’s been applied to node? Also, the code instantiates the node (the “Arrow” I think). It would be a good idea to preload the node, then instantiate it when it’s ready to be launched/fired, so that the engine doesn’t have to always load it and waste resources.

Ertain | 2021-09-02 20:40

Ok so i instantiated the node when ui_touch is released by creating a function _instance():
and it adds the projectile to the scene but the node doesn’t move even though the value of dir is updating it just creates more and more arrows that don’t move every time i release ui_touch

Also idk if this is relevant but get_tree().get_root().get_node(“Arrow”) was’t working so i had to drag and drop the projectile scene from the res:// folder and put it as a child under Area 2D in order to create the path between the two nodes.

When i run the game the first arrow does not need to be instantiated because its already in my main scene and that arrow fires properly. But the arrows that were added to the scene via script don’t move.

javrocks | 2021-09-02 21:13

What kind of code does the Arrow node have? Btw, it would be a good idea to instantiate the Arrow nodes from a base Arrow node so that any changes to instantiated nodes don’t affect the base node.

In the _physics_process() function for the Arrow node, it may be a good idea to check for whether the dir variable is a Vector2.ZERO. Maybe it could look like this:

var dir: Vector2 = Vector2.ZERO
func _physics_process( delta ):
    if dir == Vector2.ZERO:
        return
     # Factoring in 500 may be unnecessary here if the vector already has a long length.
    dir = move_and_slide( dir * 500, Vector2.ZERO )

Ertain | 2021-09-02 23:43

I move the Arrow node with this:

extends KinematicBody2D #(Projectile)

var dir := Vector2.ZERO

func _physics_process(_delta: float) -> void:
    dir = move_and_slide(dir, Vector2.ZERO)

How would you instantiate the Arrow node from a base Arrow node?

javrocks | 2021-09-03 00:20

How would you personally go about moving a projectile located in another scene?

javrocks | 2021-09-03 00:21

Here’s a trick that helps with keeping track of scenes (especially if you don’t want to deal with their NodePath).

The following code will put a PackedScene widget/selector in the Inspector.

# Put this near the top of the script.
export (PackedScene) var base_arrow: PackedScene

From the scene selected in the Inspector, an object can be instantiated from base_arrow in the desired scene.

var vecstart: Vector2 = Vector2.ZERO
var vecfin: Vector2 = Vector2.ZERO

# Feel free to change some names here to suit your needs, e.g. changing the word "arrow" to "projectile".
func input(event: InputEvent) -> void:
  if Input.is_action_just_pressed("ui_touch"):
     vec_start = get_local_mouse_position().floor()
     vec_fin = vec_start

  if Input.is_action_just_released("ui_touch"):
      vec_fin = get_local_mouse_position().floor()

  if Input.is_action_just_released("ui_touch"):
     var arrow = base_arrow.instance()
     # Put the arrow in the scene tree.
     var scene_root = get_tree().get_root().get_children()[0]
     scene_root.add_child(arrow)
     var direction = (vec_fin - vec_start).normalized()
     # Put the arrow where the user is touching.
     arrow.global_position = global_position
     # Assign a value to the "dir" property in the instantiated object.
     arrow.dir = direction

After that, all that is needed is to have the “arrow” object execute its code:

var dir: Vector2 = Vector2.ZERO
func _physics_process( delta ):
    if dir == Vector2.ZERO:
        return
dir = move_and_slide( dir * 500, Vector2.ZERO )

It might be a good idea to put in a “self destruct” mechanism into the projectile so that it doesn’t keep flying after it has left the screen.

Ertain | 2021-09-04 05:45