0
\$\begingroup\$

Inspired by this question I made a small demo for an enemy that has a HP component. Basically there is a main enemy script and a HP script that considers you died on collision and lets the enemy script know on different ways. I could think of three different ways how to let the main script know that you died and included a basic implementation of each. The focus is more on how to let the main script know that you died.

Broadcast

public class EnemyBroadcast: MonoBehaviour
{
    void HandleDeath()
    {
        Debug.Log("Died via broadcast");
    }
}

public class HPBroadcast: MonoBehaviour
{
    private void OnCollisionEnter2D(Collision2D other)
    {
        BroadcastMessage("HandleDeath");
    }
}

Pro: This seems to be the shortest code.

Con: IDE can't see the call and you need to know the broadcastevent

Interface

public interface IDeathHandler
{
    void HandleDeath();
}

public class EnemyInterface: MonoBehaviour, IDeathHandler
{
    public void HandleDeath()
    {
        Debug.Log("Death via Interface");
    }
}

public class HPInterface: MonoBehaviour
{
    private void OnCollisionEnter2D(Collision2D other)
    {
        GetComponent<IDeathHandler>().HandleDeath();
    }
}

Pro: Not possible to forget to implement methods

Con: Possible overhead of methods, reusibility

Delegate

public class EnemyDelegate: MonoBehaviour
{
    void Start()
    {
        GetComponent<HPDelegate>().handleDeathDelegate = HandleDeath;
    }
    void HandleDeath()
    {
        Debug.Log("Died via delegate");
    }
}

public class HPDelegate: MonoBehaviour
{
    public delegate void voidDelegate();
    public voidDelegate handleDeathDelegate;
    private void OnCollisionEnter2D(Collision2D other)
    {
        handleDeathDelegate();
    }
}

Pro: Outside objects are able to observe changes/ events

Con: more complicated to setup/ longer code

Now the question is, what other ways are there in a component based approach, are there more pro/ con for each approach and when is which kind of implementation prefered over the others?

\$\endgroup\$
  • \$\begingroup\$ Since you're in Unity, I might recommend using a UnityEvent - it behaves effectively like your delegate approach, but allows you to wire up the specific method to call in the Inspector, and it supports multiple subscriptions without the overhead of broadcasting. The receiver then doesn't need to know anything about the sender, so you don't have any rigid coupling between them. \$\endgroup\$ – DMGregory Jan 10 at 22:06
  • \$\begingroup\$ @DMGregory thanks, I will take a look at it tomorrow and update the question with an UnityEvent example implementation as well \$\endgroup\$ – Zibelas Jan 10 at 22:10
  • \$\begingroup\$ I think a lot of this will come down to developer preference and style. You've accurately assessed the pros and cons of these methods. Now you have a judgement call to make about which pros are more vital for your needs or more comfortable for your style of working, and which cons are the most painful. Different developers might well come to different conclusions here, so there's not really a "correct" answer for when to use each approach. \$\endgroup\$ – DMGregory Jan 10 at 22:15
  • \$\begingroup\$ I know that, I just wanted to make sure if there is a method I missed (like UnityEvent) or if that's it. \$\endgroup\$ – Zibelas Jan 10 at 22:21
  • 1
    \$\begingroup\$ "List everything I haven't thought of" also tends to be a bit too broad to fit the Q&A format here. Want to float it in Game Development Chat, instead? Informally, I'd say I think you've covered the go-to approaches, so I wouldn't recommend spending much energy searching for others unless you have a specific use case in mind that none of these solve to your satisfaction. \$\endgroup\$ – DMGregory Jan 10 at 22:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.