Hello everyone. I would like to know what is the best way to communicate between scripts without referencing them through the inspector. I’ve found some very helpful answers but I’m not sure which is best and why. For example, we have a main script where all our info is saved or loaded and some secondary scripts with info. Most secondary scripts will need to use values from our main script pretty commonly and i know for sure GetComponent<MainScript>
is not the best way to do it, especially if you are going to reference them a lot . I could also create a variable and then drag the game object that holds the main script to it but then i would need to do that for every single secondary script and some scripts may need to be destroyed in runtime or some game objects may change many times which i think is waste of time, which is why I’m interested in being able to make a whole class static and use it’s values or perhaps use namespaces? Any help would be appreciated and sorry for the confusing, I’m really confused as well!
Hello @Ant0ny !
I dont know if you are asking how to find things in the game without using inspector, but this is what i do:
You can find objects via script, and then no need to attach them in the inspector. Imagine you have that MainScript as a component of a GameObject called GameController.
MainScript TheScript;
GameObject TheGameController;
void Start()
{
TheGameController=GameObject.Find("GameController");
TheScript = TheGameController.GetComponent<MainScript>();
}
So now, you can access the MainScript like
TheScript.LevelTime=25;
But the GameObject.Find(string name) is not the best way to do it, it consumes more then the other way, which is searching for tag. For example, we create the tag “controller” for our GameControler, and now we can use:
TheGameController = GameObject.FindGameObjectsWithTag("controller");
Once you have a object, you can easy access to their parents or childs, you can use
GameObject ChildObject;
ChildObject = TheGameController.transform.GetChild(0).gameobject;
it takes the first child (child with index 0) of the gameobject. You can do the same for the parents
ParentObject = TheGameController.transform.parent.gameobject;
or the grandparent
GrandParentObject = TheGameController.transform.parent.parent.gameobject;
Here some of the Unity pages:
I would research these three things:
Class Inheritance: https://unity3d.com/learn/tutorials/topics/scripting/inheritance
Interfaces: https://unity3d.com/learn/tutorials/topics/scripting/interfaces
Events and Delegates: https://unity3d.com/learn/tutorials/topics/scripting/events
If what you are trying to do is limit your use of GetComponent<>() because of its supposed costliness, you can do lazy instantiation.
private Transform _transform;
private Transform Transform
{
get
{
if (_transform == null)
_transform = this.gameObject.GetComponent<Transform>();
return _transform;
}
}
As far as I am aware, GetComponent<>() is really the “best” way to communicate between scripts on the same object. The downside to this method is that it assumes scripts will never be removed from the game object, which is usually fine. In the rare case that scripts are removed, I just bite the bullet and use GetComponent.
As I understood you, you are searching for something you can access from every other script and use functions of in every other script. I don’t know what it’s called but it wasn’t posted yet and I think it’s pretty handy.
public class SaveManager : MonoBehaviour
{
public SaveState state;
public static SaveManager Instance { set; get; }//#this line
private void Awake()
{
//Reset();
DontDestroyOnLoad(gameObject);//#this line
Instance = this;//#and this line
Load();
}
NOTE: You need an empty GO in your scene to attach the script to. When you change the scene the GO will stay in your scene (DontDestroyOnLoad(…))
You can access funtions by making them public (obviously) for example:
//Set index as the last selected LC
public void SetLC(int index)
{
state.last_Selected_LC = index;
Save();
}
and call it somewhere with
//Debug.Log("Select");
SaveManager.Instance.SetLC(lcModelCounter);
buySelect.text = "Selected";