is there an easy way to test in code, whether a target game object received a message via SendMessage (implemented the message function)?
I want to write some kind of event system, where events are sent to child gameobject’s and the “bubble upwards” until they got delivered successfull.
As I see it, “SendMessageUpwards” will always deliver messages and does not stop sending the message if one game object received the message successfully.
I am more fluent in code. So an example:
public class Parent : MonoBehaviour
{
void OnFoobar()
{
// not called, since Child does implement OnFoobar as well
}
void OnBarfoo()
{
// will be called, since Child does not implement OnBarfoo
}
}
// not a child in terms of inheritance, but in terms of "transform.parent"
public class Child : MonoBehaviour
{
void OnFoobar()
{
}
}
// meanwhile somewhere else..
var childObj = GameObject.Find("...");
childObj.MyUberSendMessageUpwards("OnFoobar") // will only call Child.OnFoobar
childObj.MyUberSendMessageUpwards("OnBarfoo") // will only call Parent.OnBarfoo
I could implement “MyUberSendMessageUpwards” by myself, if I had an easy way to test whether the target game object actually received the message.
SendMessage and similar functions don’t give us any useful clue about the receivers - they only print a message error, but don’t throw an exception (I tried the try-catch approach). Maybe some .NET feature could help you to write your own SendMessage, like InvokeMember (take a look at this article).
Another possibility - a lot less flexible, for sure - would be to use a static boolean flag and call SendMessage (with DontRequireReceiver option) for each parent. The function called via SendMessage should set this variable to true, signalling that a receiver was found and the loop could be ended - something like this:
// script SendMessageUp.js:
static var receiverFound: boolean;
function SendMsgUp(trf:Transform, func: String){
receiverFound = false; // initialize flag
while (!receiverFound && trf.parent){ // while flag==false and there's a parent...
trf = trf.parent; // go one level above in the hierarchy
// try to call the specified function
trf.SendMessage(func, SendMessageOptions.DontRequireReceiver);
// if receiver found, the function sets receiverFound to true
}
}
// Example call:
SendMsgUp(someObject.transform, "AnyFunction");
Remember that the function called must set receiverFound to true:
function AnyFunction(){
SendMessageUp.receiverFound = true;
// code of AnyFunction
}
Maybe youre over thinking? Im sorry if im misunderstanding the question. If a child receives a message and has the receiver, that is your way of knowing if the child received the message.
this is my setup, each object has the “BubbleUp” script attached
[118582-1.jpg*_|118582]
here is a script demonstrating how a message can be sent to a child object and have it “bubble up” to the parent. In the script the parent will send a message to the last child
using UnityEngine;
public class BubbleUp : MonoBehaviour {
[HideInInspector]
public int childIndex;
BubbleUp[] children;
bool isParent = false;
private void Start()
{
if (transform.parent == null)
{
isParent = true;
this.gameObject.name = "Parent";
children = GetComponentsInChildren<BubbleUp>();
for (int i = 0; i < children.Length; i++)
{
children*.childIndex = i + 1;*
public void Receiver(string from) { if (!isParent) { Debug.Log(this.gameObject.name + " received message from " + from); transform.parent.SendMessage(“Receiver”, from + " / " + this.gameObject.name); } else { Debug.Log(this.gameObject.name + " is the parent and received message from " + from); } } } and here is the result [118583-2.jpg|118583]