0 votes

Hi ! I'm actually having troubles figuring out an issue I have with a skill that can be a melee aoe around the player, or a projectile if a condition's true.

It goes well for first enemy, but when it's focusing a second one, it derps and seems to go in the opposite y axis ? Not very good with vectors yet.

Here are the codes used in this portion :

func _loading_skills(selected_skill):
_get_closest_enemy()
match character:
    "Shade" :
        match selected_skill :
            "Reap":
                if min_enemy != null:
                    if reap_cd == false:
                        reap_cd = true
                        is_attacking = true
                        var reap_instance = reap_scene.instance()
                        reap_instance.damage = atk
                        if boosted == true:
                            reap_instance.damage = atk*2
                            reap_instance.pen = true
                            reap_instance.transform = $Muzzle.global_transform
                            reap_instance.projectile = true
                        reap_instance.position = position
                        reap_instance.hit_radius = PlayerData.character_skills_data["Shade"]["Reap"]["radius"]
                        stamina -= PlayerData.character_skills_data["Shade"]["Reap"]["cost"]
                        owner.add_child(reap_instance)
                        yield(get_tree().create_timer(PlayerData.character_skills_data["Shade"]["Reap"]["cooldown"]), "timeout")
                        reap_cd = false
                        is_attacking = false

This one's for launching the function getting the closest enemy as well as setting up and instancing the skill.

func _get_closest_enemy():
var min_dist = 99999
var enemies = get_tree().get_nodes_in_group("enemies")
for enemy in enemies:
    var dist = pos.position.distance_to(enemy.position)
    if (dist < min_dist):
        min_dist = dist
        min_enemy = enemy
    if enemy != null:
        $Muzzle.look_at(min_enemy.position)
if enemies.empty():
    min_enemy = null
return min_enemy

This one returns the closest enemy to the function that called it.

var damage
var hit_radius
var projectile = false
var speed = 250
var damaged = []
var pen = false


func _ready():
    _Animation()
    $CollisionShape2D.shape.radius = hit_radius 

func _process(delta):
    if projectile == true:
        position += transform.y * speed * delta

func _Animation():
    get_node("AnimationPlayer").play("Reap")
    yield(get_tree().create_timer(1.95), "timeout")
    queue_free()


func _on_Reap_body_entered(body):
    if body.is_in_group("enemies") and !damaged.has(body):
        body._on_hit(damage)
        #body.append(damaged)
        if pen == false:
            queue_free()

And this one is the script on the skill.

I can't figure out how to fix this issue, so I'd take any help and tips you guys could give me.

Here's an additional video is it helps understand how the projectile is acting : https://youtu.be/ttm3h8KfoF8

Godot version 3.3.3 stable
in Engine by (86 points)

Not sure if it's related to the problem or not, but...

  • You say that _get_closest_enemy() returns the closest enemy to the caller, and it does but...
  • When you call _get_closest_enemy(), you don't actually store (or use) that return value
  • That implies that min_enemy is a global variable of some sort. You don't show where it's created.

Are you potentially modifying the global min_enemy variable elsewhere?

Also, you don't show where a dead enemy is queue_free()'d. Is the enemies collection accurate (as expected) each time you call _get_closest_enemy()?

Oh sorry, guess I forgot that..

minenemy is a variable stored in the player script running the _loadingskills function ! So yeah, it's a global one.

#Detection stats
    var min_enemy
    var character

For the enemy, I'm using a script on a healthbar which gets inherited by each enemy and player, since I havea kind of zelda heart thingy. Here's where the objects get queue_freed on death :

var bar = get_tree().get_nodes_in_group("health " + get_parent().name).size() - damage
    if bar <= 0:
        if parent.is_in_group("enemies"):
            parent._achievement_count()
        parent.queue_free()

I could give the whole code, but it's pretty long...

For explaining, it actually counts how much object there's in the container after the damage, and if there's none left, it queue_free the parent.

I'm also not changing the minenemy elsewhere than the function _get_closest_enemy(), and it's only used to get the Muzzle to look at the enemy, and I then take the globaltransform of the Muzzle and apply it's transformation to the children

I also tried to print each body and which one was the closest, and it indeed seemed to work as intended

Please log in or register to answer this question.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.