Search Unity

Scripting woos...need a hand

Discussion in 'Scripting' started by tim76, Jun 28, 2017.

  1. tim76

    tim76

    Joined:
    Nov 11, 2014
    Posts:
    20
    So have script to find in child that is a Textmesh and it works just fine...

    var mytextname = this.gameObject.transform.Find("SourceVoltage").gameObject;
    var mytext = mytextname.GetComponent(TextMesh);


    Then I almost the same code for get an InputField and it crashes....

    var myInputField = this.gameObject.transform.Find("inplname").gameObject; //this line crashes
    var MyInputfieldtxt = myInputField.GetComponent(InputField);


    Error
    NullReferenceException: Object reference not set to an instance of an object
    Lgt_closeme.Update () (at Assets/Jscript/Lgt_closeme.js:17)

    Yes, inplname is there and that is the name of it, why a null Reference?

    upload_2017-6-27_19-14-8.png

    Why Unity, Why ?

    any help would be nice. Thanks.
     
  2. cstooch

    cstooch

    Joined:
    Apr 16, 2014
    Posts:
    354
    I've never used Find, but your answer to your question is right in the documentation:

    https://docs.unity3d.com/ScriptReference/Transform.Find.html



    Maybe you can use the full path (ex. Panel/layout/inplname <- not sure if that's right, but from the docs it looks like something like this should work)
    Why use find though?? Why not just set it in the inspector yourself?
     
    Last edited: Jun 28, 2017
    Kiwasi likes this.
  3. tim76

    tim76

    Joined:
    Nov 11, 2014
    Posts:
    20
    Ohhhhh
    Well, 'Find' is kinda useless then
     
  4. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    As noted, better to set it in the inspector if possible. :)
     
  5. cstooch

    cstooch

    Joined:
    Apr 16, 2014
    Posts:
    354
    Really, like i said though, not sure why you'd use that rather than just dragging it in the inspector. That works nicely.

    Also since your just looking for the game object, by the looks of things.. if you really must "find" it there are functions like GameObject.FindWithTag . Just be sure to do these on awake or start or something, not every frame in an update.. they are "expensive" (that's one reason doing it from inspector is preferred ).
     
  6. tim76

    tim76

    Joined:
    Nov 11, 2014
    Posts:
    20
    Well this not for a game, and I am trying to make this very generic because it's prefab. I'm Making an app to do Voltage drop calculations in lighting circuits. So I will have tons of these on screen, all with there own menu to set variables about that light, and run real-time calculations as changes are made. The scripts that changes these variables will change depending on the next light they are connected to. So i thought code would be better than the inspector window, as the controlling scrips may change. This chunk of code is on an update function, but the menus or 'canvas' which this is on will be set to SetActive(false); until they are called up by another function. I am assuming, if it's not active the update function will not be updating.

    Wish I could find a program out there already to do these calculations...I would much rather playing around with a 2D shooter!
     
  7. cstooch

    cstooch

    Joined:
    Apr 16, 2014
    Posts:
    354
    I don't know if Unity is the tool for you to really use for this, but I did mention a couple other options that you can use to find the child game object programatically too though (including how to possibly do it with find). Without knowing much about what you're working on, it's hard for me to say for sure, but I'd think there's some other find functions that would work, but make sure if you use that you only call the find once (ex. in start or awake) unless the reference has to keep changing for some reason (i.e. you need it to point elsewhere).
     
  8. tim76

    tim76

    Joined:
    Nov 11, 2014
    Posts:
    20
    Unity is about the only tool I could find to use. The gaming engine makes ideal to the dynamic programming. Believe me, a few I.T. people looked at programming this in a spreadsheet and Visia, VB, and it's not easy.

    Oh btw, I fix the code.

    var myInputField = this.gameObject.transform.GetChild(0).GetChild(0).Find("inplname").gameObject.GetComponent(InputField);
     
  9. cstooch

    cstooch

    Joined:
    Apr 16, 2014
    Posts:
    354
    Pretty certain you can do something like you want in many other tools/languages (I'm a programmer / systems analyst by trade), but hey if Unity is how you want to do it (or it suits your comfort level best) and it works, go for it. Definitely not trying to convince you otherwise. Whatever works!
     
  10. larku

    larku

    Joined:
    Mar 14, 2013
    Posts:
    1,422
    That'll work and is 100% valid, but is VERY fragile. Move something around, rename something, add a new child, etc in the hierarchy and BANG..

    If you know its location in the hierarchy (as the code suggests) then you are certainly better to link them together in the inspector as suggested above. It's far less fragile, better performing, and more "the way unity intended".
     
    Last edited: Jun 28, 2017
  11. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    That may just be the most brittle line of code I have ever seen. Move just one GameObject in the hierarchy and the whole thing breaks.

    Go with an inspector link, if you know where it is, or just search the whole hierarchy to find the GameObject of interest. GetComponentsInChildren is useful for this.
     
  12. karmington

    karmington

    Joined:
    Aug 14, 2017
    Posts:
    1
  13. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    Searching names by string is admitting defeat in the face of adversity IMO. I'm not fond of any solution that uses string comparisons for scene objects or assets in the project- it's simply too fragile to be a good design choice. Dragging and dropping references is just a way to do initialization with dependency injection, which is a great default approach, and in situations where that's not an option, there are a hundred other approaches I'd suggest before doing either GameObject.Find or Transform.Find. I honestly think that teaching new developers to use Unity would be far simpler if those functions were Editor-specific.

    Mostly I think, just pay attention to the sequence of events involved- if there's some reparenting or instantiation that means the component needing to be referenced doesn't exist during the parent's initialization, then whatever process you use to move or instantiate the new object should be able to handle triggering a GetComponent/GetComponentInChildren call starting at the root of the new object hierarchy. In other words, assigning that reference should just be a matter of course when the new object is moved into position, and since it's being done at that time, there shouldn't be any confusion over which GameObject that call should originate in. When moving a GameObject back into a pool of other identical GameObjects, for instance, you should still have that specific GameObject's reference handy to do the GetComponent call on.

    *shrugs*