Search Unity

Getting a child object without using .Find()

Discussion in 'Scripting' started by Ultermarto, Jan 7, 2014.

  1. Ultermarto

    Ultermarto

    Joined:
    May 10, 2013
    Posts:
    31
    Hey. Running into a lot of brick walls here. Sorry.

    As ever, my problem is all about the pain-in-the-assery of getting a reference to a game object. This time, I need to retrieve a sub-object of the parent object without searching for it by name, since this object will be copies throughout the scene, and I don't want the script of one to interact with the object of another. Here is my code.

    Code (csharp):
    1. var run : boolean = true;
    2. var player : GameObject;
    3.  
    4.  
    5. function OnTriggerEnter(collider : Collider)
    6. {
    7.     if(run == true)
    8.     {
    9.         run = false;        // Script cannot be triggered again.
    10.        
    11.         var treasureChest : GameObject = transform.parent.gameObject;
    12.         treasureChest.animation.Play();     // Start opening animation.
    13.        
    14.         var treasure : GameObject = treasureChest.Treasure_001;
    15.         yield WaitForSeconds(2);
    16.         Destroy(treasure);      // Treasure piece dissapears.
    17.     }
    18. }
    The parent object is found through
    Code (csharp):
    1. transform.parent.gameObject
    , after which I need to again make a reference for the child object 'Treasure_001'. This method doesn't seem to work, and neither does GetComponent. Please someone help before I eat Unity.
     
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Wait —are you sure? I almost never need to do this, and I wonder if there's a different way to approach whatever you're trying to accomplish that would obviate the need.

    (But then again, I have a really nice message-broadcasting system, which isn't a built-in thing; without that I suppose you would need to do this a lot more.)

    Right, searching for an object by name is almost never the right thing to do. When finding an object by name appears to be the answer, you're probably asking the wrong question. :)

    But OK, enough preaching, let's see if I can be actually helpful... it appears that when something collides with the GameObject to which this script is attached, you want to destroy the treasure (I guess because the player has taken it, right?).

    OK then, the best way to handle situations like this, where a script really needs to do something to some other object, is usually to give it a public property of an appropriate type (e.g. "var treasure : GameObject" up at the top of your script), and then simply assign that in the editor. Your script doesn't need to go looking for it — it's already got it, because it was assigned a value in the editor.

    I'm fairly sure that once you set this up in your prefab, that connection will be maintained when you instantiate that prefab.

    But I would actually recommend splitting this up a little differently... one script on the treasure chest itself, plays the opening animation when its collider is hit. Another script on the treasure itself plays the "you got treasure!" sound, increments the player's cash or whatever, and then destroys itself after a configurable delay (I'd do this with Invoke rather than yield, but whatever). Let each object handle itself, and not futz around with trying to manipulate other objects. And consider the benefits: now you can make an empty treasure chest that opens up but gives you nothing, or treasure lying around on the floor (not in a chest) that you pick up exactly the same as treasure in a chest.

    Finally, if for some reason you really do want to find a child by name, this answer has what you need.

    Cheers,
    - Joe
     
  3. Meltdown

    Meltdown

    Joined:
    Oct 13, 2010
    Posts:
    5,822
  4. Ultermarto

    Ultermarto

    Joined:
    May 10, 2013
    Posts:
    31
    Great. That'll work for now. Thanks.
     
  5. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859