[C#] Accessing variables from a class that is not attached to a Game Object

Hi everyone. I am using C# in this project.

I have 3 class files:

  • World.cs
  • Player.cs
  • StateMachine.cs

The World class is attached to the Camera and it creates the world, sets up variables, and instantiates a Player class as ‘player’.

I would like to access variables in the instance ‘player’ from inside the StateMachine class, without making ‘player’ a static variable.

Cheers

You can declare

public Player _Player;

in your StateMachine class and assign a public reference of the Player gameobject in the inspector of StateMachine gameobject.

as DeathQuake said, just create a public property or variable to assign your script. But I would change it to
public GameObject Cam;
and attach your cam instead, because the Camera already created an instance of player, so you just need to get that script
var playerScript = Cam.GetComponent();
and you can then simply use all public stuff from it
playerScript.LevelUp();
or whatever :slight_smile:

Thanks very much for the answers.
Sorry, I should have specified a little more, or I might not understand entirely - my apologies if this is a simple concept I don’t understand yet.

The ‘player’ class instance is not attached to any physical gameObject, it’s instantiated through the World class.

Is there any way to reference the variables in the instance without attaching it to a gameObject first?

Well you might have two other options, the first one, you already mentioned, is to make it static, but instead of making the class static, how about using a singleton pattern for a GameManager Script and instantiate the player there, that way you can use the instance of the GameManager to access the player class, without making it static. So just the GameManager is basically Static that holds the classes and stuff you need.

Another Option would be to search for the Camera, so GameObject.Find(“NameOfObject”).GetComponent(); that way you can get the script without attaching it first to a GameObject, but it comes with a cost in performance (depends on how often and intense you gonna use it) as many suggest to avoid the Find method.

Maybe you can also use some kinda event that pushes the player class information to another script that listens for it, but that would also be an overkill for a simple class reference. So the best way would be using a GameObject property and assigning it within the Unity Inspector. Is there a specific reason why you don’t like to use it that way?

Singleton is the way to go…
Create a single instance for your world class

    private static World  mInstance = null;
    public static World   pInstance
    {
        get { return mInstance; }
    }

    void Awake()
    {
        mInstance = this;
    }

While instantiating your player in world class, assign that to a public GameObject.

public tempGO = Instantiate(_playerprefab) as GameObject;

now with singleton world class, you can now reference this tempGO anywhere in the scene like,

World.pinstance.tempGO

Consider passing in the reference when you create the object. You have full control of the constructor, if a certain reference is needed, make it manadatory.

1 Like

Can you explain a bit… I am not getting what you just said.

public class MyClass {
    // Reference that must exist
    SomeClass reference;

    public MyClass (SomeClass reference){
        this.reference = reference;
    }
}
2 Likes