Wierd Unity Javascript Function Error

I’m getting a wierd error when I call a function I wrote in Unity Javascript.

The function header looks like this:

function LevelDone (levelScore, levelOutcome) {

}

And the function call looks like this:

objectwithfunction.SendMessage(“LevelDone”, levelScore, 1);

The problem is, when I execute the functon call, I get the following error message:

System.MissingMethodException: The best match for method SendMessage has some invalid parameter.

I was hoping someone could clue me in to what might be wrong with my call, or maybe ellucidate that error message. I’m wondeirng, is SendMessage even the best way to call a function in another object?

The best way to call a function, if you know the receiver, is to actually call the function.

ie.

var componentWithFunction : SomeClass;
function Update ()
{
   componentWithFunction.LevelDone(1, 2);
}

or if you have a reference to the game object. Just get the component in that game object and call the function. If you know the receiver.

var someGameObject : GameObject;
function Update ()
{
   var someComponent = someGameObject.GetComponent(SomeClass);
   someComponent.LevelDone(1, 2);
}

Only if you don’t know the receiver you should use SendMessage.
SendMessage looks in all scripts attached to the game object and calls the function if it exists. SendMessage can only take one parameter.

var someGameObject : GameObject;
function Update ()
{
   someGameObject.SendMessage("LevelDone", 1);   
}

Thanks, Joe.

I’m curious though, in the Scriptng Tutorial that you and DaveyJJ developed, you use FindObject-ish calls to communicate with classes and objects in your game, such as these:

FindObjectOfType (text_time).guiText.text = levelTime.ToString(“#,##0.0”);
var controller = FindObjectOfType(game_controller);

Why did you do this, instead of using static, or more direct, references to the objects you wanted to reach?

You can do both.

If you know that there will ever only be one instance of that particular class in your scene then it makes sense to use FindObjectOfType. This way you don’t need to connect the variable in the inspector at all.

If you directly connect a variable in the inspector, you will know exactly what it connects to, even if you attached the connected to script to several game objects. But you have to manually connect the variable in the inspector.

Is all of this any different with script instances that are persistent across scenes (i.e. have been DontDestroyOnLoad-ed)?

I ask because I have created a game controller script (based on the excellent DaveyJJ-Joe Unity Scripting tutorial) but my game controller does not seem to be receiving function calls from other scripts.

I have initialized references to the script instances that I want to make calls to like this:

var controller = FindObjectOfType(game_controller);
var scorer = FindObjectOfType(score);
var timer = FindObjectOfType(timer);

While I can make functons calls to the ‘score’ and ‘timer’ objects instanced in the current scene, the ‘game_controller’ instance (created in a previous scene but told not to unload on new scenes) does not appear to “hear” function calls made using the ‘controller’ variable (i.e. controller.DoFunction).

Any idea what might be wrong?

Are you sure the game_controller is actually there?
Can you see it in the hierarchy view?
Is the game object active?

FindObjectOfType works regardless of objects marked DontDestroyOnLoad or not.

Here’s what I did:

In the first scene of my project, I have an empty game object called ‘controller’ that I have attached an instance of the game_controller script to.

As new scenes are loaded, the ‘controller’ object continues to appear in the hierarchy, with the instance of my game controller script attached.

I’m not sure how I can tell whether or not the script instance is still active, but do know that I have not (knowingly) done anyhing to deactivate it.

So when do you call
var controller = FindObjectOfType(game_controller);?

Can you post the full script?

Also you might want to try if GameObject.Find works?

I’m calling the function in the game_controller script from another script in the scene. That calling script is attached to an object in the scene which is attached to a mesh that is manipulated by the human player. Below is an abbrevated listing of the calling script:

function Update () {

// tell controller the level is complete and pass the score
controller.LevelDone(scorer.AddToScore(0), 1);

}

The script seems fine. Probably an error in your setup.

Maybe you should explicitly warn when any of the instances is not found:
eg.

if (scorer == null)
Debug.Log(“Scorer couldn’t be found”);
if (controller == null)
Debug.Log(“Controller couldn’t be found”);

Yeah, I tried that - you and DaveyJJ hinted at such an approach in your Scripting Tutorial.

Unfortunately, no help - it looks like the instance is being found.

Have you tried creating and calling a new function in the game_controller script?..

function Test() { print(“gotcha”); }

just a thought to flesh out more details.

Actually, that’s the problem, no calls to functions in the controller work.

Other script instances see the controller script instance, they can make calls to it - and all without any errors being reported, even if I require receivers for the calls. THe only problem is that the functions don’t appear to be executing.

It’s downright wierd! :wink:

Being a newb, I don’t know that it makes any real difference but, maybe…

If it’s really called game_controller, have you tried renaming it to GameController instead?

Just another random thought.

Turns out the problem was that I had my target function set up as a coroutine, and thus could only accept one argument, instead of the two that I was passing.

Thanks to everyone who posted help on this!

And thanks in particualr to Joe, who as always, saved the day.