How to call function after collision

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

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

That is strange but try changing

var object = ray.get_collider()

to

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

Magso | 2019-12-13 01:32

Sadly it doesn’t work either, same result

dormccar | 2019-12-13 04:47

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

tastyshrimp | 2019-12-13 12:54

:bust_in_silhouette: Reply From: SpkingR

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')

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 : Reddit - Dive into anything

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

dormccar | 2019-12-13 19:16

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.

SpkingR | 2019-12-14 03:43

I tried it, to no effect

and it’s returning the KinematicBody2D not the CollisionShape2D

dormccar | 2019-12-14 06:41

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

SpkingR | 2019-12-14 09:19

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

SpkingR | 2019-12-14 09:46