Organizing code without creating instances/objects in C#

Is it possible to organize code so that data is accessible like this:

for variables: BaseStats.HealthData.current
for methods: BaseStats.HealthData.DamageHealth(45.0f, false);

This would be much like a class or struct, but without using classes or structs or anything that requires the instantiation of objects. Are there any other similar data structures in C# that would simply allow me to organize my variables and methods in such a tree-like format without using objects or instances?

You need namespaces.

You can do this using static. Static lets you access methods/variables without requiring instantiation of objects, but still do require that you put them in classes and structs. (The variables/methods are at ‘class level’ instead of ‘instance level’, and shared between all instances).

Thanks. I knew about namespaces, but did not think to use them for this purpose. Ideally, my data should go directly into the parent class/script (inheriting from a Monobehaviour), but not make use of additional nested classes. Namespaces cannot go into a class, right?

Thank you. Perhaps my thinking about this is wrong. Maybe I am just searching for what is fundamentally a static class. But it just seems like creating an object for simple encapsulation is too heavy.

If you want static data in your MonoBehaviour-derived class, that’s fine as well. It doesn’t have to be in its own static class.

Thanks. I don’t think I’m looking for static (just tested it to make sure). Each game object with this script needs its own version of the data, and static replaces that data.

I’m just looking for a way to encapsulate non-static data without resorting to classes or structs which need an instance. The Monobehaviour-derived classes that Unity generates with every script are enough, and this encapsulated data should go within these classes.

It sounds like you read some random post somewhere about how “instances” are bad or cause garbage collection or something and are interpreting it incorrectly. “Encapsulated data” IS a class or struct, that’s the entire point of classes and structs. There’s no reason not to put a bunch of data that needs to be encapsulated into a class or struct. If you’ve got an int for health, it’s going to require the instantiation of that int and a place in memory for that int regardless of whether or not it’s in a class or struct. In C#, everything has to be in a class or struct anyway. You can’t not use classes and structs; even statics are still fundamentally a part of classes and structs.

That’s quite a contradiction you’ve got there. You want to encapsulate data (which means having a class or struct) and don’t want to use static fields because each gameobject requires its own version of the data (which means having a class or struct). @makeshiftwings is right; even static classes derive from System.Object. You need a class or struct.

You mention that you don’t want to instantiate classes or structs. Well you don’t need to:

namespace BaseStats {
//Non-static struct
struct HealthData {
public static object current; //Static field
public static void DamageHealth (float num, bool booll) => ; //Static function
}
}

Thanks. Actually, I was initially having an issue with referring to an instance of a class that was declared in a parent class. This is resolved now with a reference to the parent class via:

private BaseStats parent;
public HealthData(BaseStats parent)
{
    this.parent = parent;
}

Using ‘parent’ now allows me to access instances declared in the parent class.

I think that I just wanted to deal with the Monobehaviour-derived class that Unity generates and not any other objects for this particular data. Maybe my conception of how I should be approaching this was wrong. I now see that it probably was.

Thanks. In my code, I have HealthData, DefenseData, and other classes’ methods referencing one another, so I think that I do need to instantiate them, since I will be referring to their data within each class.

I know that I needed classes - the Monobehaviour-derived script is one, and each object that gets this script will have its own instance of it. I thought that within these classes/scripts, there may have been another way of organizing data (perhaps “encapsulation” is the wrong word) that did not create additional nested classes or structs. I now see that no such method exists.

If you’re just trying to keep all the code inside the one MonoBehaviour, you can use nested classes:

public class PersonWithStats : MonoBehaviour
{
  public AllTheStats myStats;

  [Serializable]
  public class AllTheStats
  {
    public BaseStats baseStats;
    public HealthStats healthStats;
    public DefenseStats defenseStats;

    public class BaseStats
    {
        public int level;
        public string name;
     }
    
     public class HealthStats
     {
          public int maxHealth;
          public int currentHealth;
      }

       public class DefenseStats
       {
            public float dodgeChance;
            public int armorValue;
       }
    }
}