0 votes

Hello! I posted this on the subreddit but haven't had much luck so wanted to try posting it here, too.

I've been following this tutorial.

Where in the tutorial I have reached is the culmination of episodes 1-8 of the series. I will link the episodes I think are relevant to my situation here:

Creating an enemy

Knockback

Enemy health

Enemy tileset

I also edited my default animation code to match what another reddit post on the same issue suggested

I have a creature (slime) in my game, which has a little animation that should be playing continually ("default"). When I play the scene for the slime by itself, it animates.

If I put more than one instance of the slime in my main scene (with a dungeon etc), only one of them animates. This has happened both when I drag them into the scene, and when the enemies are tied to a tilemap.

I get no errors when I run the game, until I kill the specific slime that animates. When I do that, the errors I get are:

E 0:00:18:0089   Node not found: ../slime/Sprite:frame
  <C Source>     scene/main/node.cpp:1382 @ get_node()

E 0:00:18:0099   On Animation: 'default', couldn't resolve track:  '../slime/Sprite:frame'
  <C Source>     scene/animation/animation_player.cpp:243 @ _ensure_node_caches()

These errors are repeated several times.

I looked this issue up on the subreddit and found someone suggesting that the animations are being reset every frame. I set the code to what they suggested. At the moment, the lines of code related to the slimes' animations are:

In slime.gd

func _ready():
    if not get_node("anim").current_animation == "default":
        get_node("anim").play("default")
    movedir = dir.rand()

In entity.gd, which slime.gd extends

func _ready():
    if TYPE == "ENEMY":
        set_collision_mask_bit(1,1)
        set_physics_process(false)
    texture_default = $Sprite.texture
    texture_hurt = load($Sprite.texture.get_path().replace(".png","_hurt.png"))

Also in entity.gd, when a creature is hurt

func damage_loop():
    if hitstun > 0:
        hitstun -= 1
        $Sprite.texture = texture_hurt #This triggers
    else:
        $Sprite.texture = texture_default

        if TYPE == "ENEMY" && health <= 0:
            var death_animation = preload("res://enemies/enemy_death.tscn").instance()
            get_parent().add_child(death_animation)
            death_animation.global_transform = global_transform
            queue_free() 

    for area in $hitbox.get_overlapping_areas():
        var body = area.get_parent()
        if hitstun == 0 and body.get("DAMAGE") != null and body.get("TYPE") != TYPE:
            health -= body.get("DAMAGE")
            hitstun = 10
            knockdir = global_transform.origin - body.global_transform.origin

Thank you in advance for any tips or advice you have!

in Engine by (12 points)

1 Answer

0 votes

You have to make sure that when you kill the enemy, any linked node in the script stops running completely. Also, make sure that there are not many objects sharing the same properties. Make sure that every object controls its own things, so it won't have problems detecting others that are similar.

by (343 points)

That makes sense! I'm not sure how to do it, though.
Both my player.gd and slime.gd scripts extend a script called entity.gd. Do I need to also stop that script running? If so, how do I make sure the player keeps existing? Do I need a separate script for every instance of the enemy that I am going to have in the game?

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.