Cheat Sheet: Accessing GameObject/Components

Discussion in 'Scripting' started by phuzzy, Mar 13, 2009.

  1. phuzzy

    phuzzy

    New Member

    Joined:
    Feb 12, 2009
    Messages:
    31
    Below is a cheat sheet we're using on my team to help us access Game Object and Components from code. Hopefully it will come in handy for others!


    Accessing Game Objects and Components in Unity

    Definitions
    *Game Objects* should be thought of generally as items that show up in the Hierarchy view. They are meshes and physical objects (from Maya or made in Unity), lights (not attached to a specific Game Object), cameras, and GUI objects.

    *Components* are those items that are attached to Game Objects, thus appearing in that Game Object's Inspector view. Components are colliders, lights (attached to an object), renderers, shaders, emitters, audio items, and animation clips (if the animation was part of an imported object).


    Keep in Mind
    The object-hierarchy of Game Objects and Components in code is subservient-to and dependent-upon the relative relationships of items to one and another in the Hierarchy view. Scripts are not generally able to see each other at a global level, instead needing to be accessed as any other tangible Component attached to a Game Object within a larger parent-child hierarchy.


    Accessing Game Objects
    *** Accessing the "Self" Game Object ***
    Often a script needs to be able to access the Game Object to which it is attached. Rather than simply declare a public variable of type GameObject and drag the reference from the Hierarchy, use the following code to make the Game Object handle automatically within the script by passing the attached Game Object's name to the Find method.

    Code (csharp):
    1. var o_self : GameObject;
    2. o_self = GameObject.Find(this.name);

    *** Accessing the Parent Game Object ***
    There are times when a script attached to a child Game Object needs access to the Components of it's parent Game Object. By extending the example above with the following line of code, you make a handle to the parent Game Object. Note that to access the parent Game Object, the "transform" property must be invoked and that to do so, we pass that parent's name property into the Find method.

    Code (csharp):
    1. var o_parent : GameObject;
    2. o_parent = GameObject.Find(o_self.transform.parent.name);

    *** Accessing Sibling Game Objects ***
    Because they are at the same level of the hierarchy, sibling Game Objects can be accessed using the example code from "Accessing the "Self" Game Object" above. Remember that the principle here is that Game Objects grouped under a parent Game Object are siblings AND so are Game Objects parallel each other at the top level of the Hierarchy view. Tricksy Unity.


    Accessing Components
    *** Accessing Non-Script Components ***
    Once you have a handle for a Game Object in your code, you can manipulate and access the Components much as we would expect to do in any language. The following example accesses a renderer Component and changes the material's shader property. Note that you still need to create the initial reference to o_foo using one of the techniques above. Refer to the individual Component's references in the Unity Manual to get the exact syntax as it's not always what you expect.

    Code (csharp):
    1. o_foo.renderer.material.shader = Shader.Find("Diffuse");

    *** Accessing Script Components ***
    Accessing scripts attached to a Game Object, thus being able to read their public variables and utilize their public methods, is a little more complicated as a second handle needs to be made to the script itself. The following code assumes that we are accessing a sibling Game Object's (called "sibling_a") script called someScript and that we do not have a handle for that sibling yet.

    Code (csharp):
    1. var o_script : someScript;
    2. o_script = GameObject.Find("sibling_a").GetComponent(someScript);
    3. o_script.someMethod();
    Alternatively, if we already have a handle to the Game Object that has the script we want access to, we could can do the following.

    Code (csharp):
    1. var o_script : someScript;
    2. o_script = o_foo.GetComponent(someScript);
    3. o_script.someMethod();
  2. tolm

    tolm

    New Member

    Joined:
    Feb 4, 2008
    Messages:
    61
    How come you don't just use this.gameObject and this.transform.parent.gameObject?
  3. phuzzy

    phuzzy

    New Member

    Joined:
    Feb 12, 2009
    Messages:
    31
    We tried that technique initially, thinking that the behavior of "this" was similar to what we knew from JavaScript. Unfortunately, the behavior is not analogous and throws an error.
  4. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Messages:
    24,617
    Actually you've added a bunch of unnecessary extra steps. The various "Find" commands are a bit slow; don't use them unless you need to.

    I think it's much easier just to use "gameObject". e.g.,

    Code (csharp):
    1. gameObject.name = "Wibble";
    2. gameObject.active = false;
    Again, I think it's a lot easier just to use transform.parent.

    Code (csharp):
    1. transform.parent = someOtherObject.transform;
    Just use the name of the component:

    Code (csharp):
    1. renderer.material.shader = Shader.Find("Diffuse");
    This is a shortcut for

    Code (csharp):
    1. GetComponent(MeshRenderer).material.shader//etc.
    Rather:

    Code (csharp):
    1. var o_script : someScript = GetComponent(someScript);
    "this" refers to this script. e.g.:

    Code (csharp):
    1. var foo = 33;
    2.  
    3. function Start () {
    4.    var foo = "whee!";
    5.    print (foo + this.foo);
    6. }
    --Eric
  5. tolm

    tolm

    New Member

    Joined:
    Feb 4, 2008
    Messages:
    61
    You must have done something else wrong then, because it should work.

    In Unity "this" refers to the current instance. Since all scripts you write are instances of MonoBehaviour, you can use this.gameObject to access the GameObject that the script is attached to, just like you can use this.name to access the name of that GameObject, because both are properties of MonoBehaviour.

    (And to be really pedantic, you don't even need the "this". You can just write gameObject or name, as long as you haven't defined another variable called "gameObject" or "name".)
  6. phuzzy

    phuzzy

    New Member

    Joined:
    Feb 12, 2009
    Messages:
    31
    ROCK ON!

    The team and I were killing ourselves over this yesterday, and we'd not realized that gameObject and GameObject were two completely different constructs. Thanks for the help!
  7. AngryAnt

    AngryAnt

    Keyboard Operator Moderator

    Joined:
    Oct 25, 2005
    Messages:
    2,940
    Yea - once is a class, the other is a reference to an instance of that class - the instance to which the MonoBehaviour is attached :wink:
  8. dawvee

    dawvee

    New Member

    Joined:
    Nov 12, 2008
    Messages:
    276
    This isn't quite how I understand it. Meshes (or mesh renderers, anyway), cameras, etc. are components. GameObjects are basically just empty containers with a location somewhere in the scene (and potentially inside another container). Components are all the functional stuff you can put into those containers.