“And there will be rare but useful cases where they can be properly applied. Just not if you want global vars.”
Maybe it just depends on what kind of project you’re working on, but for an action RPG it seems that it’s not really a rare case that they are useful.
Many of my scripts variables like all the player information for the custom stats based on your armor, your skill tree, where you spend your stat points, etc. they all need to be accessed by multiple scripts and in multiple scenes. There is just one instance of these variables in the entire project and there are many of these variables. There would be no reason not to use public static variables in a case like this, hardly a rare case.
I also have all kinds of other variables that must be easily accessed from any script and that will only ever have 1 value at any time during game play. Things like option menu logic to make sure that the multiple menus and panels never cause any conflicts or interference with each other.
For example:
public static bool gamePausedBool = false;
public static bool mainPauseMenuBool = false;
public static bool optionsMenuBool;
public static bool inventoryBool;
public static bool playerStatsBool;
public static bool skillTreeBool;
public static bool glovesEquippedBool = false;
public static bool bootsEquippedBool = false;
public static bool helmEquippedBool = false;
public static bool chestEquippedBool = false;
public static bool beltEquippedBool = false;
public static bool storeBool = false;
public static bool dropItemSelectedBool;
public static bool itemSlot1AvailableBool;
public static bool itemSlot2AvailableBool;
//etc
All of those are just for my GUIButtonsScript
I agree with Hoeloe that it is very useful to just set up a GlobalDataScript where you keep the majority of your global public static variables organized. You can load up all these variables locally from the PlayerPrefs on Awake() and then set new local private variables for all the other scripts that regularly use them in the other scripts Start() functions.
Here’s an example of some of my GlobalDataScript stuff, just trying to give a good example of how they are useful to me. I heavily rely on them and they work perfectly, so I don’t quite understand what’s the problem with them.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public class GlobalDataScript : MonoBehaviour
{
public static bool videoPlayingBool = false;
public static int globalTotalHealthPotions;
public static int globalTotalManaPotions;
public static int globalTotalCrystals;
public static int globalLevelsUnlocked;
public static int currentLevelInt;
public static int inventoryItemSlotsUsed;
public static int inventoryFirstItemSlot;
public static int inventorySecondItemSlot;
//etc
public static int inventoryFirstItemType;
public static int inventorySecondItemType;
//etc
public static int inventoryFirstItemID;
public static int inventorySecondItemID;
//etc
public static int globalPlayerStrength;
public static int globalPlayerDexterity;
public static int globalPlayerIntelligence;
public static int globalPlayerVitality;
public static int globalPlayerArmor;
public static float playerXPTotal;
public static int playerStatPointsAvailable;
public static int playerSkillPointsAvailable;
public static int playerLevel;
public static int playerAtStoreInt;
public static int tierOneArmorPiecesFound;
public static int tierTwoArmorPiecesFound;
public static int tierThreeArmorPiecesFound;
public static int monsterKillCount = 0;
public static bool loadingScreenImageBool;
public static int arenaLevelsUnlocked;
public static bool globalStoryActiveBool;
public static float playerHealthBeforeArmorChange;
public static float playerEnergyBeforeArmorChange;
public static float globalDebugCounter;
public static int globalBloodSettings;
public static int globalMusicSettings;
public static int playerHasPetInt;
public static int playerPetTypeInt;
//set all variables on Awake()
//allows easy access and storage of large amounts of global variables
//can all be used locally with new private variables on any other scripts via Start()
void Awake()
{
globalTotalHealthPotions = PlayerPrefs.GetInt ("Total Health Potions");
globalTotalManaPotions = PlayerPrefs.GetInt ("Total Mana Potions");
globalTotalCrystals = PlayerPrefs.GetInt ("Total Crystals");
globalLevelsUnlocked = PlayerPrefs.GetInt ("Levels Unlocked");
arenaLevelsUnlocked = PlayerPrefs.GetInt ("Arena Levels Unlocked", 0);
//etc
}
Had to make this into an answer since it wouldn’t fit as a comment. But I guess this is a pretty good example of things you can do where public static variables are extremely useful and easy to use to store variables globally. Even if they aren’t technically global since they belong to the classes, I still feel like they accomplish the same thing as a global variable would when used correctly.
I’ll have to look at some of those other discussion posts a bit later to delve a little deeper into what kind of disadvantages there would be to using public static variables, but it seems to work fine for me.
Here I just wanted to give an example of how I use public static variables. For me they seem like the exact opposite of a rare case, and it’s not hard to apply them properly.
I mean all these variables I listed are just from 2 scripts, I use a lot more public static variables than this and I use quite a lot of public static functions as well which generally just bring up an instance to the local stuff like:
//enemy script and when enemy dies it calls this:
if (XPUpdateBool == false)
{
XPUpdateBool = true;
PlayerXPScript.XPUpdateCall();
}
//on PlayerXPScript
public static PlayerXPScript XPInstance;
void Start()
{
XPInstance = GetComponent<PlayerXPScript>();
}
public static void XPUpdateCall()
{
XPInstance.XPUpdateFunction();
}
void XPUpdateFunction()
{
//tons of local code which only updates the global public static variables and playerprefs when changes occur.
}
You say you can’t give a small example of what you can’t do in C# but here’s a pretty huge example of what you can do. I can’t think of any easier way for me to use all these “global” variables throughout my project even if they aren’t technically global. If I just have to take one extra step to type the name of the script in front of the variable that’s not a big deal to me.