Correct use of static variable in my class?

I have a GoldCoin class, which is attached to every gold coin gameObject in my scene. I need to know how many gold coins are in my scene when the level loads. I though using a static variable for that purpose would be good, but I have to manually reset it from another class in order for the count to be the same when I reload the scene:

// GoldCoin.cs
using UnityEngine;
using System.Collections;

public class GoldCoin : MonoBehaviour
{
	#region Variables
	public static int sNumOfGoldCoins;
	public static int sTotalGoldCoinsValue;
	
	public int coinValue = 1;
	#endregion
	
	
	#region Unity Functions
	// ================================== AWAKE FUNCTION ================================== //
	void Awake( )
	{
		// Set number and total value of all gold coins in scene
		sNumOfGoldCoins++;
		sTotalGoldCoinsValue += coinValue;
	}
	
	// ================================ ON TRIGGER ENTER FUNCTION ================================ //
	private void OnTriggerEnter( Collider collider )
	{
		// Check if it was the Bike's collider...
		if( collider.tag == "Bike" )
		{
			Messenger<int>.Broadcast( "GoldCoinCollect", coinValue, MessengerMode.REQUIRE_LISTENER );
			Destroy (gameObject);
		}
	}
	#endregion
}

The problem with the above is when I reload the scene, the static vars get bigger and bigger since they are not being reset. So I take care if it in my other class which only gets disabled once when exiting/reloading level:

// CollectiblesManager.cs
using UnityEngine;
using System.Collections;

public class CollectiblesManager : MonoBehaviour
{
// =================================== ONDISABLE FUNCTION =================================== //
	void OnDisable( )
	{
		//...
		
		GoldCoin.sNumOfGoldCoins = 0;
		GoldCoin.sTotalGoldCoinsValue = 0;
	}
}

This works fine, but it made me question whether or not using static variables for this purpose was the correct choice?! If you guys have any suggestions on how to implement this better, I am all ears…

Thanks!
Stephane

I would suggest moving the awake() code to the start(). And moving the Ondisable() code to awake(). :)

1 Answer

1

How about this:

Instead of using a static variable and the collectibles manager to reset the static variable, simply use the collectible manager to store the count. That way it will be automatically reset when the scene is loaded (because the collectible manager will be destroyed and re-created along with the rest of the scene objects):

public class CollectiblesManager : MonoBehaviour
{
	public static CollectiblesManager instance = null;

	public int numOfGoldCoins = 0;
	public int totalGoldCoinsValue = 0;
	
	void Awake() {
		instance = this;
	}
}

public class GoldCoin : MonoBehaviour
{
	#region Variables
	public int coinValue = 1;
	#endregion
 
 
	#region Unity Functions
	void Start( )
	{
	   CollectiblesManager.instance.numOfGoldCoins++;
	   CollectiblesManager.instance.totalGoldCoinsValue += coinValue;
	}
 
	private void OnTriggerEnter( Collider collider )
	{
	   // Check if it was the Bike's collider...
	   if( collider.tag == "Bike" )
	   {
		 Messenger<int>.Broadcast( "GoldCoinCollect", coinValue, MessengerMode.REQUIRE_LISTENER );
		 Destroy (gameObject);
	   }
	}
	#endregion
}

Thanks for the quick answer tbkn! That's exactly what I used to do before I switched to using a static var in the GoldCoin class itself! I am still trying to figure out when and where static variables should be used and this was a poor attempt on my part :) Now, what about making the variables static in CollectiblesManager: CollectiblesManager.numOfGoldCoins++; ? and reset them to 0 in OnDisable? Would that make sense or not in this scenario? Thanks again!

Just dropping in to say that I would use the Singleton pattern as suggested by @tbkn pretty much always unless there is a very specific reason not to (usually that you want to flag something before and don't know if it will exist yet). The singleton pattern can be tricky around creation time because of the order of instantiation and the execution of code in Awake and Start methods, but it's by far the most flexible system.

@whydoidoit - yeah the Singleton pattern can get tricky at creation time, and it's why I wanted to try static vars for this class because I do need to initialize some values in ClassA before ClassB uses them. I could easily change the Start() function in ClassB to a custom function that I would call from ClassA when init is done...might try that! @tbkn - makes sense, thanks for the tip! I think sometimes I get lazy and start using static vars as an easy way out... Thank you both for the help! You were very helpful :)

@tbkn - thanks for the heads up!