Search Unity

Newb-like question on find/getcomponent

Discussion in 'Scripting' started by psychicparrot, Mar 5, 2008.

  1. psychicparrot

    psychicparrot

    Joined:
    Dec 10, 2007
    Posts:
    884
    Hellooo!

    I want to be able to find a gameobject which has a script attached to it, then call a function within the script, from another gameobject.

    The script I'm calling from is Javascript and the script I want to call on is C#.

    I assumed it would be like this:

    Code (csharp):
    1.  
    2.    
    3.    oneObject=GameObject.Find("Networking");
    4.    var script = oneObject.GetComponent("Controller");
    5.            
    6.     if(script)
    7.         {
    8.             connected = script.isConnected();
    9.                 Debug.Log("CONNECTION STATUS IS "+connected.ToString());   
    10.         }
    11.  
    12.  
    Where Networking is the GameObject with a script named 'Controller' attached to it.

    It never finds the object, so I tried:


    Code (csharp):
    1.  
    2.         oneObject =GameObject.Find("Controller");
    3.            
    4.             if(oneObject)
    5.             {
    6.                 connected = oneObject.isConnected();
    7.                 Debug.Log("CONNECTION STATUS IS "+connected.ToString());
    8.    
    9.             }
    Which gives an error in the IDE saying that '.isConnected is not a member of Unity.GameObject'

    So, how do I do this? Ideally, I'd like a reference to the object that I can keep throughout the whole game and fire calls into it when I need to... I'm just having trouble understanding how to find these objects and refer to them, so any help on how Find, GetComponent etc. can be used to call functions would be really appreciated!

    Thanks!
    Jeff.
     
  2. CoherentInk

    CoherentInk

    Joined:
    Jul 16, 2006
    Posts:
    216
    Your first piece of code looks mostly correct, but you probably need to cast your Controller as a Controller when you assign it to script:
    Code (csharp):
    1. var networkingObj : GameObject = GameObject.Find("Networking");
    2. var controller : Controller = (Controller)networkingObj.GetComponent("Controller");
    3. if (controller) {
    4.     var connected = controller.IsConnected();
    5.     Debug.Log("Connection status is " + connected.ToString());
    6. }
    Although I haven't tested this code, this will likely work. The compiler may complain on the var controller line since I'm not sure how to explicitly cast the type in JavaScript; I'm just guessing here as that is how you would do it in C#.

    Let me know if this fails miserably.
     
  3. psychicparrot

    psychicparrot

    Joined:
    Dec 10, 2007
    Posts:
    884
    Thanks for the help so far, Mr. CoherentInk - I appreciate it :)

    The controller line, sadly, just throws an error ...

    Assets/Main_Scripts/Player_Scripts/Player_NetworkSync.js(17) error UCE0001: ';' expected. Insert a semicolon at the end.

    I've tried a bunch of different syntax on it, but it keeps telling me I need a semicolon ... when there already is one. I literally copy and pasted the line of code from here and no matter how many times I look at it, the semicolon is there ;)

    Am I missing something here? I mean, I doubt I'm the first one to run into this but the docs are lacking on this whole subject and it seems like such a straightforward thing to want to do?
     
  4. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Should be

    Code (csharp):
    1. var networkingObj : GameObject = GameObject.Find("Networking");
    2. var controller : Controller = networkingObj.GetComponent("Controller");
    Although you can shorten that to

    Code (csharp):
    1. var controller = GameObject.Find("Networking").GetComponent("Controller");
    Basically, I believe you were right the first time. There's something about the compile order of scripts when mixing JS and C# though. Which is why I never do that; too much bother IMO.

    --Eric
     
  5. psychicparrot

    psychicparrot

    Joined:
    Dec 10, 2007
    Posts:
    884
    Thanks for your help, Eric :)

    I'm surprised that it's been so difficult to achieve, but just before you posted I found another way of doing it ...


    Code (csharp):
    1.  
    2.  
    3. var objects : GameObject[] = GameObject.FindGameObjectsWithTag("Networking");
    4. for(var oneObject : GameObject in objects)
    5. {
    6.    var script = oneObject.GetComponent("Controller");
    7.    if(script)
    8.    {
    9.       var connected = script.isConnected();
    10.       Debug.Log("Connection status is " + connected.ToString());
    11.    }
    12. }
    13.  
    14.  
    Hardly ideal, but hey if it works then I'm moving on to the next challenge!

    If anyone has a cleaner / tidier way of doing this, I'd love to know about it. If not, the solution I tried above was the only one that I've found to work reliably.

    THANKYOU for your help, guys. Very much appreciated.
     
  6. psychicparrot

    psychicparrot

    Joined:
    Dec 10, 2007
    Posts:
    884
    Just to close this off ... although I had managed to get the scripts to compile, if I moved any of this code into other scripts it was all getting odd and failing.

    As Eric mentioned, there are issues with compilation order. Once I'd moved my scripts around a bit everything was ok.

    Anyone having problems with this kind of stuff should read http://unity3d.com/support/documentation/ScriptReference/index.Script_compilation_28Advanced29.html, particularly the bottom few paragraphs where it talks about C# and Javascript orders!!

    Again, thanks for the help, guys :)