How do I access the instance of a script held by a GameObject?
I am putting myself through learning Unity atm and I got an issue. I have a class GameVariablesController. That is only a C# Script. This is supposed to hold all game variables that need to be saved. Now I want to access them. However, I am not sure how to do this. In Game Maker Studio, I would make an Object, add it to the scene and access this one via the game object list. So I tried to do the same in Unity.
For finding the GameObject, I need to search for it and GameObject.Find(); returns me the object. However, it does not contain the definitions for the functions the script is holding. So my question is, how do I access the instance of that script? I am not quite sure how this works in Unity.
Answer by UnityCoach · Jul 10, 2017 at 11:13 PM
If there's only one instance of that script in the scene, you can simply use
GameVariablesController gvc = FindObjectOfType<GameVariablesController>();
It saves you from finding the bearer. The component has to be on a game object in the scene though.
To clarify, finding the bearer refers to using GameObject.Find to first find the object and then you would need to use object.GetCompnent();
ANother way to find the bearer is what I like to do:
public GameVaribaleController gvc;
Declare this at the top of the script that needs the reference. Then a field will be created in the inspector on any object with this script attached. You can drag the GameVariableControllerObject into the field to finalize your reference.
That's right, there are many ways to do the same thing.
This depends on if the object that needs to get access to the component is in the scene at the beginning, or if it's a Prefab that will be instantiated later for example. In which case, you can't reference a scene object from a Prefab.
You can also imagine that the required object is a Prefab, that could be automatically instantiated when needed (lazy initialisation), and that you could implement as a Singleton (unique instance) that instantiates itself when it's accessed.
Unity is so flexible..
Hey, I didn't even think about using a Singleton. I think that is the most elegant solution. Saves me the few nanoseconds looking for the object and is overall more stable towards user error, such as forgetting to add the script to something :D. Thanks.
Answer by GothSeiDank · Jul 11, 2017 at 11:00 AM
To add to the answer @UnityCoach has given, I am using this singleton to solve the issueusing
System.Collections;
using System.Collections.Generic;
using UnityEngine;
//---------------------------------------------
public class GameVariablesController
//---------------------------------------------
{
//---------------------------------------------
// Private Members
//---------------------------------------------
private static GameVariablesController instance = null;
private static readonly object padlock = new Object();
//---------------------------------------------
// Public Members
//---------------------------------------------
public float playerShipMaxSpeed {get;set;}
public float playerBulletMaxSpeed {get; set;}
//---------------------------------------------
GameVariablesController()
//---------------------------------------------
{
playerShipMaxSpeed = 40;
playerBulletMaxSpeed = 900;
}
//---------------------------------------------
public static GameVariablesController Instance
//---------------------------------------------
{
get
{
lock(padlock)
{
if ( instance == null )
{
instance = new GameVariablesController();
}
return instance;
}
}
}
}