Script execution VS Variable declaration

Hey everyone!

Does anyone know if this can be a problem?:

(EDIT: See post #3 for updated version)

public enum ItemTypes { // ...
}

// I would prefer this:
public class Statics {
    int mainTexId = Shader.PropertyToId("_MainTex");
    int itemTypesLength = ItemType.GetNames(typeOf(ItemType)).Length;
}

// , but is this better?:
public class Statics : MonoBehaviour {
    int mainTexId;
    int itemTypesLength;
    void Awake () {
        mainTexId = Shader.PropertyToId("_MainTex");
        itemTypesLength = ItemType.GetNames(typeOf(ItemType)).Length;
    }
}

Best wishes,
Shu

Enums are just like constants.

Statics are class-instantiated time, i.e, when you new up the class.

You cannot “new” a monobehavior, you have to make it on a GameObject with .AddComponent<>();

And with monobehaviors it is NOT the main thread that news them up, so you must use the Awake() construct for most calls.

One thing you are not considering above is a static class, which can only contain statics and constants

public static class MyItems
{
  public static int Item1 = 1;
  public static int Item2 = 2;
  public const int MaxItems = 100;
}

It can also contain static methods.

1 Like

@Kurt-Dekker

Thanks for your reply!

I did forget to put static and readonly. This is what the code in my original post would look like, with some additional examples (if those are different):

public readonly int[] ints = new int[2]{0,1};
public enum ItemTypes { // ...
}
public class Item {
    public int id;
    public Item (int id_) {id = id_;}
}
public readonly Item item = new Item(0);
public readonly Item items = new Item[2]{new Item(0),new Item(1)};

// I would prefer this:
public static class Statics {
    static readonly int ints0 = ints[0];
    static readonly int mainTexId = Shader.PropertyToId("_MainTex");
    static readonly int itemTypesLength = ItemType.GetNames(typeOf(ItemType)).Length;
    static readonly int itemId = item.id;
    static readonly int items0Id = items[0].id;
}

// , but is this better?:
public static class Statics : MonoBehaviour {
    static int ints0, mainTexId, itemTypesLength, itemId, items0Id;
    void Awake () {
        ints0 = ints[0];
        mainTexId = Shader.PropertyToId("_MainTex");
        itemTypesLength = ItemType.GetNames(typeOf(ItemType)).Length;
        itemId = item.id;
        items0Id = items[0].id;
    }
}

I know I could use properties to limit write access, but I would like to avoid those.

If there are no execution order issues with the first solution, I would prefer that solution, because I can put readonly easily, it requires less code and I don’t need to access Awake by putting the script on a GameObject (I don’t want to clutter the main manager object with scripts if it’s not required).

The thing I am concerned about is that when initializing the variables, I’m unsure whether or not “Shader.” or “ItemType.” is reliably available, because they might not have been read at that point? Or is this not an issue?

For example:

void DoSomething () {
    int i = 0;
    i += j; // j cannot be reached, before it is declared
    int j = 1;
}

I’m not sure how useful being concerned is when you’re doing software engineering.

What actual real world problem are you trying to solve?

Do you just need to spend some time reviewing C# syntax and Unity’s object lifecycle?

Generally, in Monobehaviors put initializers in Awake() if they are for the current object, or in Start() if they are for other objects. When you get into more advanced situations, attach the debugger and find out what is actually happening.

It’s FAR too mind-bogglingly bland and unmemorable to even attempt to keep all this in your brain ahead of time. Plus, Unity is subject to change over time.

Just write code, pay attention to what you’re doing, attach the debugger or put in good logging statements, and eventually you’ll develop an intuition for what’s going on in whatever environment you’re working with.

1 Like

Thanks for your reply!

Two of the most common examples that I am currently using quite a lot is Shader.PropertyToID to generate shader property hashes that I want to be able to access from everywhere. The same with a few dozen enum lengths. The cases both aren’t about having access to that data by the same object or another, but by the entire project, which makes things a lot easier when having to access the same things very frequently.
For now, I am probably just going to use the initializers and hope to get a compiler error if anything may be an issue.