0 votes

The context for this can be seen in the related question.
This is in the Slime enemy scene. At the top of the script I put

signal Slime_attacked(damage)

This is in the _physics_process(delta: float) func of the Slime scene.

if $AttackRaycast1.is_colliding() or $AttackRaycast2.is_colliding():
    $AnimationPlayer.play("Attack")
    emit_signal("Slime_attacked", damage)

This is in the script for the root node of the level scene where the player, hearts and enemy instances are:

var health: int = 6
   func _ready():
    $Background/AnimationPlayer.play("GameHeart1Full")
    $Background/AnimationPlayer.play("GameHeart2Full")
    $Background/AnimationPlayer.play("GameHeart3Full")
  $Background.connect("Slime_attacked",$Enemies/Slime1,"_on_Slime_attacked")

And this is the signal func here:

func _on_Slime_attacked():
    print("Boo")
    health= health -1

    if health == 6:
        $Background/AnimationPlayer.play("GameHeart1Full")
        $Background/AnimationPlayer.play("GameHeart2Full")
        $Background/AnimationPlayer.play("GameHeart3Full")

I really have no experience with this side of Godot so some extra help to finish this would be amazing :)

Godot version 3.2.3
in Engine by (46 points)
retagged by

1 Answer

+1 vote
Best answer

you don't even need signal for something like this.
use the get_collider() function which returns the node the raycast is colliding with or null if it doesn't collide with anything, save the collider in a variable and check wether the collider is the player, if it is you can just directly run any function from the variable. in this case:

var collider = $AttackRaycast1.get_collider()
if collider != null and collider.name == "Player":
   collider._on_Slime_attacked()

you create seperate animations for different health states, and change them in the hurt function depending on how much health you have after the attack.

func _on_Slime_attacked():
  print("Boo")
  health= health -1

  if health <= 2:
    $Background/AnimationPlayer.play("VeryHurt")
  elif health <= 4:
    $Background/AnimationPlayer.play("Hurt")
  else:
    $Background/AnimationPlayer.play("Healthy")
by (253 points)
edited by

So, I tried

 var collider = $AttackRaycast1.get_collider()
if collider.name == "Player":
   collider._on_Slime_attacked()

But whenever the player enters the raycast now, the game crashes and the debugger says: Invalid get index 'name' (on base: 'null isntance'). Any further tips?

ah sorry for the bad code... use this if statement instead:

if collider != null and collider.name == "Player":
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.