Sending a message to script of another game object

Hi, I’ve been going through the reference docs and UA for the last couple of days trying to figure out how to have my “collectable” prefab use SendMessage to add 5 to the score of my “game manager” object’s Score_beh script.

#pragma strict
 var gameManager : GameObject;

 function OnTriggerEnter(collision : Collider){

      if(collision.gameObject.name == ("Player")){
      Destroy(this.gameObject);
      gameManager = gameObject.Find("GameManager").GetComponent("Score_beh");
      Component.("Score_beh").SendMessage("ScoreAdd",5);

}
}
GameManager is a cube located in the scene, with Score_beh attached

Thanks If someone could point me in the right direction it would be greatly appreciated.

On your game manager:

    static var Instance : GameManager;

    function Awake() {
        Instance = this;
    }

On your other script:

   if(collision.gameObject.name == "Player") {
         Destroy(gameObject);
         GameManager.Instance.SendMessage("ScoreAdd", 5);
         //Or if ScoreAdd is public - this is much faster
         //GameManager.Instance.ScoreAdd(5);
   }

In this instance you might want your Score to be easily accessible, and instead of finding the GameObject and sending messages to it, I favour having a singleton instance for things like this, so that in Awake() you would do something like:

public class Score : MonoBehaviour
{
   public int CurrentScore { get; set; }

   public Score Instance { get; private set;}

   void Awake()
   {
      // you may optional want some kind of ASSERT here
      Instance = this;

      CurrentScore = 0;
   }
}

Then in your OnTriggerEnter, you would have:

void OnTriggerEnter(collision col)
{
    if(collision.GameObject.name == "Player")
    {
       Destroy(this.gameObject);
       Score.Instance.CurrentScore += 5;
    }
}

Sorry, the above is C#, but I am sure the same is possible in JS, but not being proficient I won’t attempt it.

In my case I tend to have Singletons for larger items, so not just a Score item, I have a UIManager and Player, so other data/functions hang off my singleton instances.

By doing the above you don’t need to Find things all the time and you call concrete methods that don’t to be discovered and won’t be called on all components where the exist on the GameObject in question.

I looked for a JS example and found one blinding close to your use-case:

http://forum.unity3d.com/threads/47976-Singleton-in-javascript

Their GameManager class and instance is quite typical - I have several for distinct disciplines.

above answers are mostly good…

The line “Destroy(gameObject);” would need to be the last line of the code though, since the object gets destroyed at that point…

to point out a few other flaws in your original code, for clarification:

 var gameManager : GameObject;

 function OnTriggerEnter(collision : Collider){

      if(collision.gameObject.name == ("Player")){
      Destroy(this.gameObject); //no need for "this",Destroy(gameObject) refers to this object
     // and again, this needs to go AFTER the next two lines
      gameManager = gameObject.Find("GameManager");
    
    // .GetComponent("Score_beh"); don't need this, SendMessage goes to all Monobehaviors on the 
         //gameObject
     //also, don't use quotes with GetComponent, just say GetComponent(Score_beh)

      gameManager.SendMessage("ScoreAdd",5); // every script with a function "ScoreAdd" on 
                                                          //this object will be called

} }