- Home /
What is the best way to share data across child classes?
I have recently decided to break my very large character class into multiple smaller classes. An example of these smaller classes can be seen in the picture above. The main class for a character is now c_Manager. This class is initialized by the level loader and is used by all characters including player. It then initializes a series on sub-classes that control all aspects of a character from inventory to model. The problem I am running into is that many of the sub-classes need to communicate with each other (such as c_Controller needs data from c_Status to determine the speed the player should be moving, or c_Model needs data from c_Controller to determine the animation to play) , and I have been unable to find a clean/efficient way to do this.
This is an example of how the c_Manager class is set up:
public class c_Manager : MonoBehaviour {
c_Controller controller;
c_Status status;
c_Model model;
void Start () {
controller = new c_Controller(somedata);
status = new c_Status(somedata);
model = new c_Model(somedata);
}
void Update () {
controller.Update();
status.Update();
model.Update();
}
}
And one of the sub-classes showing where I need the data:
public class c_Controller{
public c_Controller(var somedata) {
// INITIALIZE
}
void Update () {
-> I NEED DATA FROM THE OTHER SUB-CLASSES HERE! <-
}
}
I am sure there is a very simple solution to this, but I come from a C only background and some of the Object Oriented logic can stump me pretty hard.
~Thanks, Malarkey
Answer by paskal007r · Jul 28, 2015 at 12:42 PM
To STORE the data use a dedicated script component then add a DATA_STORAGE variable of the same type to whoever needs access and link it via unity editor. If you don't want to give public access you may force the editor to show the field using [SerializeField] DATACLASSTYPE DATA_STORAGE
Anyway don't focus with OOP, look at Component pattern here, is solid gold: http://gameprogrammingpatterns.com/component.html
currently all the objects/scripts are instantiated at run-time. The only object when the game starts is a GameObject that loads every other object via a single script. I'm not sure how to pass a class by reference in C#, but I'm guessing that's the next solution, so I'll look into it.
Sir, I'm not going to say that I'm an expert with only 2 years of unity experience as a full time dev, but that' approach is at the very least "exotic". Usually you would keep all components of a class already instantiated in a prefab and attached to a single object.
It is actually very helpful. A huge amount of our games content is procedurally generated, and the loader allows us to stream in the linear levels without ever encountering a load screen. It also allows unity to parse and load complex save files. Each level is built as a scene and a script is used to output the level and all of its data to a text file. The loader reads this default level data and the players save data and from these two streams generates the playable level. At the end of each level is a junction positioned so that the old level can be removed from memory and the new level loaded in without the player noticing. I have optimized this procedure to the point that there is almost no hit to performance. As for the weapons and characters they are all procedural and were going to be loaded from a script anyways.
If your curious how the maps are saved it is pretty simple. the file consists of two blocks of data.
-The first block contains all the static geometry/objects and the only data stored for those simple object is an id number and transform.
-the second block contains what we are calling nodes. Each node is basically a struct containing the id number for the type of object to load and all the data required to load the object. if the node is a character spawning node, the stored data would include whether or not to spawn civilians or enemies. if they are enemy what intelligence bracket are they? what weapons can they have? ratio of male to female, etc. The nodes are very special in the way they are parsed in that they can have as little or as much data as you want to include if you want your spawner to only spawn three meter tall, female, green haired rocket launcher toting, super intelligent enemies at a rate of 5 per second then you can fill all that data in and thats going to happen. If the data is not include the loader chooses a default choice or spawn randomly.
Once you write a standard and class to parse all this data for the loader it becomes incredibly easy to expand, and has actually helped avoid a large number of bugs.
Now that I have a more clear vision of your situation I'd recommend using scriptableObjects to keep the data: http://docs.unity3d.com/ScriptReference/ScriptableObject.html
It's a "data-only" asset you can script and use at your necessity, also works with bundleAssets ;)
Oh wow that's a pretty nifty class. In a few week I plan on posting a copy of our loading system to github cleaned up codewise and stripped of all our games content. If you are interested I can definitely update you when that happens.
Your answer
Follow this Question
Related Questions
Can I create custom types of data? 1 Answer
Changing the class of a variable 0 Answers
Can't pass variables between 2 scripts 1 Answer
Calling variables in classes from other scripts 2 Answers
Abstracting class vars, accessing vars by variable 0 Answers