Search Unity

Get reference to gameobject from non-monobehaviour class

Discussion in 'Scripting' started by SpaceCadet, Sep 29, 2017.

  1. SpaceCadet

    SpaceCadet

    Joined:
    Jul 29, 2013
    Posts:
    16
    Hello, I have a class that needs to be constructed, therefore it cannot inherit from Monobehviour:

    Code (CSharp):
    1. public class Speed {
    2.  
    3.     private Controller cont;
    4.  
    5.     public Speed () {
    6.         cont = GameObject.FindGameObjectsWithTag ("Player") [0].GetComponent<Controller> ();
    7.     }
    8.  
    9.  
    10. }
    From the above, the Controller component is a script attached to a game object with the tag of "Player".

    How do I get references to other game objects (like Player) from a non-monobehaviour class?
     
  2. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    I think what you are asking is how to make a class that doesn't inherit MonoBehaviour access GameObject instances.

    There are too many options to count but here are a few.

    1. Change the classes so their public interface allows them to be told about game objects that are important to them.
    2. Create a service locator you can use to make certain important game objects effectively global (be careful with this one).
    3. Create an object that has a field for each important kind of game object and then pass around a reference to that object.
     
  3. SpaceCadet

    SpaceCadet

    Joined:
    Jul 29, 2013
    Posts:
    16
    Please could you elaborate on your first suggestion.

    How could I amend the above so it can be told about the Player game object?
     
  4. R1PFake

    R1PFake

    Joined:
    Aug 7, 2015
    Posts:
    542
    I don't understand your question, GameObject.FindGameObjectsWithTag is a static method, so it can be called from any class.
     
  5. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    You can change the constructor or, better yet, encapsulate the constructor altogether.

    Constructor to accept a player:

    Code (CSharp):
    1. public class Speed {
    2.     private readonly Controller cont;
    3.  
    4.     public Speed(GameObject player) {
    5.         this.cont = player.GetComponent<Controller> ();
    6.     }
    7. }
    Encapsulated constructor:

    Code (CSharp):
    1. public class Speed {
    2.     private readonly Controller cont;
    3.  
    4.     private Speed(GameObject player) {
    5.         this.cont = player.GetComponent<Controller> ();
    6.     }
    7.  
    8.     public static Speed GetInstance(GameObject player) {
    9.         return new Speed(player);
    10.     }
    11. }
     
    SpaceCadet likes this.
  6. makeshiftwings

    makeshiftwings

    Joined:
    May 28, 2011
    Posts:
    3,350
    Maybe I'm misunderstanding your question, but the code you have should work fine. Make sure you actually put the tag "Player" in the Tag field of the Player object if it's not working.
     
    MaxGuernseyIII and SpaceCadet like this.
  7. SpaceCadet

    SpaceCadet

    Joined:
    Jul 29, 2013
    Posts:
    16
    My bad, the initial code I posted worked. I had assumed you needed to inherit from Monobehaviour to have access to the GameObject class.