Search Unity

How can I detect/catch the SendMessageOptions.RequireReceiver error message?

Discussion in 'Scripting' started by Renea, Jun 27, 2020.

  1. Renea

    Renea

    Joined:
    Nov 12, 2017
    Posts:
    9
    I have a mechanic that has two "modes" basic and advanced. I have two prefabs that represent these two modes. Both prefabs utilize one script where I use Broadcast message. The broadcast message really only applies to the advanced mode, and therefore I will get the error that is generated from ReqiureReceiver when I use the basic mode.

    Simplistically, I could just put in the option to not require a receiver, but I would like to catch the error the required receiver catches when advanced mode is active, but the basic prefab is being used. Then I could print a log message to use the advanced mode prefab.

    I want to do something like this:

    Code (CSharp):
    1. try
    2.             {
    3.                 BroadcastMessage("myMethod", myParam);
    4.             }
    5.             catch (SendMessageOption.RequireReceiver  error)
    6.             {
    7.                 Debug.LogError("You must use the Advanced Prefab or turn off Advanced mode");
    8.              
    9.             }
    Is this possible?
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,742
    SendMessage is kind of antiquated. The way to do things today is to make an interface.

    That way you say "is there this interface?" and check if it's not null, then call the method you want if it is.

    Don't be afraid, it's pretty simple, and it's way more powerful. Here, soooper-quickly:

    Code (csharp):
    1. // stick this in its own file, usually IMyInterface.cs
    2. public interface IMyInterface
    3. {
    4.   void MyMethod( int arg1, string arg2);
    5. }
    Now, in whatever Monobehaviors you have, you implement that interface, which basically involves:

    1. put that interface after a comma right after MonoBehavior in the class header:

    Code (csharp):
    1. public class FooClass : Monobehavior, IMyInterface
    2. {
    3. }
    2. make a public version of the above function in the FooClass, with body:

    Code (csharp):
    1. public void MyMethod( int arg1, string arg2)
    2. {
    3. // do your stuff!
    4. }
    Now, to find this interface you say:

    Code (csharp):
    1. var imyInterface = GetComponent<IMyInterface>();
    and to potentially call it you do:

    Code (csharp):
    1. if (imyInterface != null)
    2. {
    3.   imyInterface.MyMethod( 1, "yabo!");
    4. }
    That's it! Read more if you like but that is the tl;dr of using C# interfaces in Unity3D.
     
  3. Renea

    Renea

    Joined:
    Nov 12, 2017
    Posts:
    9
    Thanks for the quick response @Kurt-Dekker , however, I'm not sure you understand what I'm trying to do. As a side note, I am using interfaces in the way you are suggesting throughout my mechanic, but I felt that one wouldn't work here. below are screenshots of a very basic example of how I have the prefabs set up.

    upload_2020-6-26_20-50-29.png
    upload_2020-6-26_20-50-50.png
    upload_2020-6-26_20-51-5.png

    Here is an example of the scripts I have set up.

    Code (CSharp):
    1. public class MyScript : MonoBehaviour
    2. {
    3.     // Start is called before the first frame update
    4.     void Start()
    5.     {
    6.         try
    7.         {
    8.             BroadcastMessage("MyMethod", SendMessageOptions.RequireReceiver);
    9.         }
    10.         catch (SendMessageOptions.RequireReceiver error)
    11.         {
    12.  
    13.             Debug.LogError("You must use the advanced prefab or disable advanced mode.");
    14.         }
    15.      
    16.     }
    17.  
    18. }
    Code (CSharp):
    1. public class AdvancedScript : MonoBehaviour
    2. {
    3.     public void MyMethod()
    4.     {
    5.         //do something
    6.     }
    7. }
    Looking at this information, you should see that the "AdvancedScript" is only on the children of the Advanced Prefab. The two prefabs have exact same functionalities with the exception of the children on the Advanced one, which the part of the mechanic involving the children is done within their own "AdvancedScript"

    What I'm trying to accomplish is to give warnings to the developer that utilizes this mechanic when they are mixing and matching the prefabs with the mode that it's in. It seemed that a try/catch on the BroadcastMessage method would be the best place to put that message. But if I can't do a check against that error, then I will need to find another way to check for mismatch within the mechanic.
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,742