C# call method only if a parameter object contains it

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

I’m trying to convert a tutorial script that’s in gdscript to c# as I am more comfortable with it. However, in the tutorial script they are able to call a method from an object, whose datatype will be a RigidBody child, from the function parameters only if it exists, i.e. after checking the existence with the has_method function. However, I can’t seem to find a way to call the function from the object in c# as it’s a function that’s going to be a custom method in a child class (of a RigidBody). Is there a way to do this in c# or is it only usable for gdscript?

Can you show us the GDscript example?

juppi | 2022-01-30 10:01

The GDScript example goes as shows:

func collided(body):
	if hit_something == false:
		if body.has_method("bullet_hit"):
			body.bullet_hit(BULLET_DAMAGE, global_transform)

hit_something is a property of the overall object. bullet_hit is a method of a different class that will be created later in the tutorial. For c#, is there a way to call it even if the class has not been created yet similar to the gdscript or will I only be able to call the function once the class is created and the function is defined?

wooshuwu | 2022-01-30 10:36

:bust_in_silhouette: Reply From: juppi

Let’s assume your RigidBody has a C# script named “Player” attached (class Name) and the Player has a public method named “BulletHit”.

This should fit your needs:

private void Collided(Node body) 
{
    if (!hitSomething && body is Player player)
    {
        player.BulletHit(BULLET_DAMAGE, GlobalTransform);
    { 
}

You just check if the colliding Node is of type Player.

Probably late to the reply, but I think this is probably where you leverage C# with interfaces. Instead of calling hasMethod or checking if the bullet hits the player. Which tightly couples your collide method with Player, what you can do is have Player implement the interface IHitable.

interface IHittable
{
    void bulletHit();
}
public partial class Player : CharacterBody2D, IHittable
{
    void bulletHit(){
      ... do something cool.
  }
}
private void Collided(Node body) 
{
    if (body is IHittable hitMeBaby)
    {
        hitMeBaby.BulletHit(BULLET_DAMAGE, GlobalTransform);
    { 
}