0 votes

How to call function after collision
Help

Hello,

So I have an Enemy object (scene)

it is a kinematicBody2D with a script.... in said script is a function called takeDamage(damage):

So I am checking for collision with the player using a ray, I am able to get the collision, but when I call the object it says that kinematicBody2D doesn't have such a function (script is for sure attached to it)

So how do i correctly call a function of an object I am colliding with?

Current Version:

if ray.is_colliding():
    #doing some position stuff here
    var object = ray.get_collider()
    if object.is_in_group("Enemy"): <-----returns true btw
        object.takeDamage(damage)

Exact error message: "Invalid Call. Nonexistent function 'takeDamage' in base 'KinematicBody2D'

Code of Enemy Script:

extends KinematicBody2D

export (PackedScene) var scene_export

class_name Enemy

var maxHP
var HP
var speed = 64

var tile_Size = 16

var spriteNode

var tile
var lastPosition = Vector2() #where moving from
var targetPosition = Vector2() #where moving to

#const EnemyScene = preload("res://Scenes/Enemy.tscn")

var dead = false
var playerDetected = false
# Called when the node enters the scene tree for the first time.

func _init(x, y):
    maxHP = 5
    HP = maxHP
    tile = Vector2(x, y)

    #spriteNode = EnemyScene.instance()

    self.position = position.snapped(Vector2(tile_Size, tile_Size))
    lastPosition.x = position.x - 8
    targetPosition.x = position.x - 8

    lastPosition.y = position.y - 8
    targetPosition.y = position.y - 8

func _on_body_enter(body):
    if body.is_in_group("Player"):
        print("hit player")
        takeDamage(1)

func takeDamage(dmg):
    print("enemy took damage")
    if dead:
        return

    HP = HP - dmg
    spriteNode.get_Node("HPBar").rect_size.x = tile_Size * HP / maxHP

    if HP <= 0:
        self.dead = true

func _process(delta):
        self.position = position.snapped(Vector2(tile_Size, tile_Size))

Code from Player script where I try to call function:

if ray.is_colliding():
    moveState = false
    position = lastPosition
    targetPosition = lastPosition
    var object = ray.get_collider()
    if object.is_in_group("Enemy"):
        #object.takeDamage(damage)
        print("object collided name: ", object.name)
        pass
asked Dec 12, 2019 in Projects by dormccar (12 points)

That is strange but try changing

var object = ray.get_collider()

to

var object = get_node(ray.get_collider().get_path())

Sadly it doesn't work either, same result

I went and tested it myself and as Magso said it is strange because it should work. The only way I see it not working is if you are colliding with your KinematicBody2D but your script is attached to a parent of that Node, in which case you would need to do this:

var object = ray.get_collider() # Get's the KinematicBody2D
var parent = object.parent # Get's the parent/owner of the script
parent.takeDamage(damage) # Calls the takeDamage method on the owner of the script

1 Answer

0 votes

Maybe your script is not attached in the correct node?
I see this line in your enemy script code though you comment it:

#const EnemyScene = preload("res://Scenes/Enemy.tscn")

Or if your script is in right place, add this code in the if statement: object.has_method('takeDamage')

answered Dec 13, 2019 by SpkingR (126 points)

that was added as an earlier attempt to fiddle with node selected, based on someone else's advice elsewhere. The script is attached to the KinematicBody2D that is being collided with. I have a screenshot, but can't share it.... i did on my reddit post : https://www.reddit.com/r/godot/comments/e9rtw8/how_to_call_function_after_collision/

and that if statement would only prevent it from ever attempting to run.. since it is saying that the object doesn't have the method -- tested, it does prevent it

Hey, maybe you can remove the group tag in node CollisionShape2D, I think the ray.get_collider returns the CollisionShape2D but not the Enemy itself.

I tried it, to no effect

and it's returning the KinematicBody2D not the CollisionShape2D

This is weird, can you post your code, I will test it and try to figure out the problem.

Hey, I saw two Enemy.gd scripts in your editor, is that the problem?

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.