I’m trying to use the SendMessage() method to activate a script on an object on my scene, however the target object is disabled (using SetActiveRecursively(false)), resulting in this error message:
“SendMessage ExecuteOnCommand has no receiver!”
code:
public GameObject[] LinkedObjects;
public void ExecuteComponentScript()
{
foreach (GameObject target in LinkedObects)
{
target.SendMessage("ExecuteOnCommand");
}
}
the ExecuteOnCommand() script then simply changes SetActiveRecursively to true or false.
However, this only works when the object is already active (i.e. it sets it to false and everything works). If the object is NOT active the SendMessage cannot find a receiver.
So, simple question: how do I send a message to an object that is NOT active?
EDIT: for reference, I am using Unity 3.5.4, so I do not have access to SetActive(). I will be migrating my project over to Unity 4 eventually, will this solve this SendMessage receiver problem? But in the mean time I’m hoping to find a solution using 3.5.
2 Answers
2
SendMessage won’t deliver messages to deactivated GameObjects. You can call a function directly if you have a reference to the script component. You can use GetComponent to get that reference. Keep in mind that GetComponentInChildren won’t work because it also skips deactivated GameObjects. GetComponent works even with deactivated GOs:
public GameObject[] LinkedObjects;
public void ExecuteComponentScript()
{
foreach (GameObject target in LinkedObects)
{
target.GetComponent<MyScript>().ExecuteOnCommand();
}
}
Of course you have to know the component you want to reach and the function has to be public. Usually it’s easier to store those references in the array instead of GameObjects:
public MyScript[] LinkedObjects;
public void ExecuteComponentScript()
{
foreach (MyScript target in LinkedObects)
{
target.ExecuteOnCommand();
}
}
This way you can still easily access the gameobject with target.gameObject but you have direct access to the script on that gameobject. In most cases you have more interaction with your script components than with the GameObject itself.
Thanks for the help everyone. After looking at these answers and speaking to some friends I came up with a solution that works well for my project. Any object that was previously the target of a SendMessage is now the child of another GameObject. This Parent object contains nothing but the scripts controlling the children, and when code needs to be run on it I call a script directly to turn the parent on but not the child. The parent can then receive SendMessage to do it’s thing.
Thus I can run code on the parent without actually needing to turn on the child (so I don’t have to turn it on until it needs to be on). This also allows me to have multiple children for multiple states of the object.
You can't. You can never call any methods on a script which is not active. That is pretty much the point of not beeing active.
– Lockstep@Lockstep: That statement is not entirely correct. You can call any method ona script even when the GameObject is deactivated or the script is disabled. Those properties just prevent certain Unity generated events from being executed. Unity simply don't dispatch any messages to the gameobject when it's deactivated. This includes Update, LateUpdate, ... and SendMessage calls. However you can still call the function directly or change the state of the object (the position, rotation for example).
– Bunny83