Search Unity

SendMessage

Discussion in 'Scripting' started by littlelingo, Aug 16, 2006.

  1. littlelingo

    littlelingo

    Joined:
    Jul 18, 2006
    Posts:
    372
    I was trying to figure out how to call a function attached to another GameObject and recalled from other discussions the SendMessage call. Is that the only / proper way to do this? If there are others, where could I get more information about them?

    Thanks!

    -- Clint
     
  2. Der Dude

    Der Dude

    Joined:
    Aug 7, 2006
    Posts:
    213
    If you have a reference of the GameObject, you can try to get the relevant script:

    var yourScript : YourScript = someGO.GetComponent( YourScript );

    If "yourScript" (variable) is null, then the GameObject "someGO" doesn't have this particular component.

    If it is not null, you can proceed like this:

    yourScript.CallRelavantFunction();

    However, I have no idea if this is better than to call SendMessage on it.
     
  3. littlelingo

    littlelingo

    Joined:
    Jul 18, 2006
    Posts:
    372
    Okay, I tried that and get this weird error that makes no sense to me.

    Code (csharp):
    1.  
    2. gun.Fire();
    3.  
    I am making that call and Fire is a function on the gun GameObject. Up above I define the var gun this way:

    Code (csharp):
    1.  
    2. var gun : GameObject;
    3.  
    And I assigned that GameObject to a game object.

    The error is:

    'Fire' is not a member of 'UnityEngine.GameObject'

    Any ideas?

    Thanks,

    -- Clint
     
  4. hsparra

    hsparra

    Joined:
    Jul 12, 2005
    Posts:
    750
    If your script is type "Gun" (i.e. the script name), then you can probably use:
    Code (csharp):
    1.  
    2. var gun : Gun;
    3.  
    Since you are currently declaring you gun variable as a GameObject type, the compiler is complaining because when it looks at the GameObjectt class, it does not find a fire function.
     
  5. littlelingo

    littlelingo

    Joined:
    Jul 18, 2006
    Posts:
    372
    I see what you are saying. I tried that and it doesn't seem to be working for me. The object gun is actually under the object robot. Robot is where I want to make the call to Fire which lives in a script on gun.

    Does that make sense?

    Thanks,

    -- Clint
     
  6. yellowlabrador

    yellowlabrador

    Joined:
    Oct 20, 2005
    Posts:
    562
  7. freyr

    freyr

    Joined:
    Apr 7, 2005
    Posts:
    1,148
    If you declare the gun variable public, you can drag the robot object onto it in the inspector, and the variable will automatically get assigned the Gun component.

    The code could look something like this:
    Code (csharp):
    1.  
    2. // GunShooter.js
    3. //   -- a script attached to some other game object
    4.  
    5. var theGun : Gun; // <-- drag the robot object onto
    6.                   //     this variable
    7.  
    8. // This one requires the object also to have a collider
    9. // or a GUIText or GUITexture
    10. function OnMouseUp() {
    11.     if(theGun) { // test that the gun is there
    12.         theGun.Fire(); // fire the gun
    13.     }
    14.     else { // if theGun is not assigned
    15.         Debug.Log("You need to assign a value to the Gun");
    16.     }
    17. }
    18.  
    19.  
    You should also take a look at the pages about Accessing Other Components and Accessing Other Game Objects in the scripting overview.
     
  8. littlelingo

    littlelingo

    Joined:
    Jul 18, 2006
    Posts:
    372
    I have read the reference material and some of that I have read multiple times. Overall it makes sense and I am slowly piecing together how the messaging works but are still struggling a bit. I used the last example provided (mine looked like this, stripped down a bit):

    Code (csharp):
    1.  
    2. var theGun : gun;
    3.  
    4. function Update () {
    5.      theGun.Fire();
    6. }
    7.  
    gun is actually a GameObject which is a child to robot. robot has the script the above code is in.

    I am getting this error now:

    The name 'gun' does not denote a valid type

    Thanks for all the help!

    -- Clint
     
  9. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    Javascript is case-sensitive. So most likely you just need to change gun to Gun.
    Or whatever the name of the script as seen in project view or Fnder.
     
  10. littlelingo

    littlelingo

    Joined:
    Jul 18, 2006
    Posts:
    372
    gun is the name of the GameObject and is lowercase.

    Thanks,

    -- Clint
     
  11. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    Ok. You are calling a function called Fire. This function must be defined somewhere. If i got your intention right, that is in a script called "Gun" or just for clarity lets call the script "GunScript".

    Now since you are calling the function directly, you need a reference the gun script.

    So thats why you write:
    So what happens here is that you expose a variable to the inspector, which initially is set to null. Or referencing nothing. So then you have to drag the gun on the slot in the inspector. Once you have done that, you can just call

    Code (csharp):
    1.  
    2. theGun.Fire();
    3.  
    The name of the game object truly doesn't matter here at all. It only matters if you use something like:
    Alternatively you can also use SendMessage ("Fire").
    In that case you dont need a reference to the GunScript. Eg.

    Code (csharp):
    1.  
    2. var theGun : GameObject;
    3. theGun.SendMessage("Fire");
    4.  
     
  12. littlelingo

    littlelingo

    Joined:
    Jul 18, 2006
    Posts:
    372
    Ah okay. Thanks!

    So when I declare the script then in the inspector I need to drag the gameobject the script lives on. Or at least that is what I seemed to need to do. Is that correct?

    A question about performance regarding SendMessage versus calling the function directly. Is there a difference for speed, overhead, etc.? Or are they interchangeable?

    Thanks,

    -- Clint
     
  13. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    Yes.

    For performance you should prefer the direct function call. SendMessage will always have to do translation of string to function and has to check every script. A direct function call is a lot faster.

    Still there are a lot of cases, where you want to use SendMessage, especially if you don't know the receiver. But if you can use a direct function call, you should.
     
  14. littlelingo

    littlelingo

    Joined:
    Jul 18, 2006
    Posts:
    372
    Excellent! Thanks for the help everyone!

    Regards,

    -- Clint