Mix of static and non-static variables in a class

Hello,

I realize the title is quite vague, but I would like some guidance on a design problem I have encountered.

Assume we have a class called Soldier. Soldier can be upgraded into Officer and Commander (names do not matter). There is also a SoldierManager who manages the soldiers (issues orders - where to move, when to move, upgrade, and create soldier).

If a soldier is upgraded, the Soldier class should naturally know the information of the upgrade. This information includes new stats (health, attack power, etc.), along with the new 3D Mesh. However, this information, although they live within an instanceable class (Soldier), should be static, because every time we create a new soldier type, the info needs to be passed on again and again for each prefab.

As we know, static members cannot be exposed to the inspector. As such, I cannot drag and drop the corresponding prefabs or Mesh objects. This automatically gives us two workarounds: a singleton or an assetloader, e.g. Resources.Load. A singleton makes no sense in a class that is supposed to be instanceable. This also rings a huge alarm on a bad coding practice, potentially violating the SOLID principle. The next idea I had was to create a ScriptableObject (let’s call it “MyData”), where this information lives and use a hard type reference in the soldier class (e.g., public MyData soldierData) and access the info. This, however, generates a type-coupling issue, even if it makes sense.

On the other hand, we have the SoldierManager, who creates the soldiers. As such, the manager should know what a soldier is, thereby having access to this information (Soldier’s stats and mesh). If we go by the ScriptableObject option, it means that the Manager must also have a reference to “MyData”, which defeats the purpose of having the upgrade information residing in the Soldier script.

How would you keep this logic clean, without introducing tight-coupling between these types?

Intuitively, I would go by a static member, as previously mentioned, but this is not handled as expected by Unity. If I do not sacrifice my instinctive workflow due to Unity’s obscurity of static members, how else would I pass this information?

Thanks!

I don’t understand why you’re worried about “tight coupling” between some ScriptableObject and your Manager class. You can use the same type of ScriptableObject and make new ones for Solider, Officer, Commander etc. At a certain point the manager needs to know how to create the things you want it to create. Separating that configuration out into its own instance that can be entirely set up via the Inspector and then just drag-dropped onto the manager seems the most ideal in my mind.

1 Like

Hi KelsoMRK,

Thanks for your input! I understand what you are saying, I just dislike having data that regard one specific class outside of the class. Basically, I am trying to minimize the use of custom type references in my scripts (other than UnityEngine and MSDN API) as much as possible. Maybe it’s because I have a very conservative view of what tight coupling entails.

I will go with the ScriptableObject option then.

Cheers!

Keeping your “configuration” separate is a good thing :slight_smile:

Why?

Have you heared of the factory pattern? This is what you want and basically do with the manager object and ScriptableObjects. I would only suggest to seperate things like meshes from game data. You don’t need a reference to prefabs in your Soldier model as it is managed by the factory. But it also wouldn’t make a big difference.
Then there is no issue to assign the ScriptableObject to your Soldier.