Gets active camera only once (on process(), only the first frame)

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

I’m getting the wrong camera (object?). It gets the active camera only once, and then it goes for something else.

onready var everyone = get_children()
var coordinates = [] setget list_update

func list_update(haha):
    coordinates = haha

func _process(delta):
    var new_coordinates = []
    for enemy in everyone:
        var target = get_node(enemy.name + "/target")
        var local_trans = enemy.get_global_transform().origin
    
        target.translate(get_transform().basis.xform(local_trans))
        var pos = target.get_translation()
        var camera = get_tree().get_root().get_camera()
        var screen_pos = camera.unproject_position(pos)
        new_coordinates.append(screen_pos)

    list_update(new_coordinates)

Basically this converts Vector3 from Spatials into Vector2 based on the camera. I append the values to an array because I want another script to use them.

Printing the first index is how I discovered this issue:

(284.538025, 465.474213)
(643.855469, 1740.325562)
(642.883728, 1736.87793)
(642.561035, 1735.732788)
(642.399902, 1735.161133)

what kind of node is the “target”? why are you translating it?
Could it be the target has shared properties among all the enemies (like a mesh) and when you translate it on the first enemy it does it on the remaining ones as well?
try unprojecting the enemy position directly instead of the target and see what happens

Andrea | 2020-05-26 10:29

“The target” is one target per enemy. Before this code there’s another for loop that generates a Spatial (the one I mentioned for the vector conversion, AKA “target”) when the player enters an area. Each target is a child of its enemy.

I just tried the enemy’s position directly and it made disappear each of them… And a few seconds later it froze MY COMPUTER. Had to do a hard reset.

SereneMango | 2020-05-26 11:30

lol, sorry!
share the project so we can have a look

Andrea | 2020-05-26 11:35

At this point I don’t mind, so give it a try. If some comments on scripts look weird or very ambiguous, they’re just placeholders.

Please read the README file so you can learn what I’m trying to achieve.

SereneMango | 2020-05-26 14:15

Dont know if this is what you were looking for, but as i wrote before i made the unprojection directly on the enemy position, modifying your

var screen_pos = camera.unproject_position(pos)

to

var screen_pos = camera.unproject_position(enemy.global_transform.origin)

Now when i select “Attack=>normal” some red arrows appear at the bottom of the enemy position.
I guess you wanted to use target to control the position of the arrow: if that’s true you found a pretty convoluted way to do it, i would simply have done a

var arrow_offset=Vector3(x,y,z)
screen_pos=camera.unproject_position(enemy.global_transform.origin+arrow_offset)

Andrea | 2020-05-26 15:29

Ummm yup!!! This is what I was trying to do! Thank you so much!

By the way, this still doesn’t answers my original question, so I don’t know what to do with this page, lol.

SereneMango | 2020-05-26 16:36

:bust_in_silhouette: Reply From: Andrea

By the way, i double checked the code, the error is in the

target.translate(get_transform().basis.xform(local_trans))

because translate(x) does not place the object into x, but move the object by x. And since you were calling it every frame, every frame was going to move the targe a bit, exiting the viewport after a couple frames.
You should use

target.translation=(get_transform().basis.xform(local_trans))

Okay once again thank you so much. I still kind of wanted the spatial node because I realized I could use it to point at specific elements. I’ll use both this answer and your other comment in my code.

Btw I’ll just delete my project from Dropbox now.

Hugs!

SereneMango | 2020-05-26 16:47