Is this a good use of static variables?
Let's say I have a player script that controls differently depending on which platform my game is running on. The way I would achieve this is to create a script called GameProperties.cs to hold a static int "platformID" variable that can be accessed from any other script. Like so:
public class GameProperties
{
public static int platformID = 0;
}
Then, to give this "platformID" a value, in the first scene of my game, I would have a script called AppStartup.cs that will detect the current platform, like so:
public class AppStartup : Monobehaviour
{
void Start()
{
#if UNITY_EDITOR
GameProperties.platformID = 0;
// ID 0 for Unity's Editor.
#elif UNITY_STANDALONE_WIN
GameProperties.platformID = 1;
// ID 1 for Windows PC.
#elif UNITY_ANDROID
GameProperties.platformID = 2;
// ID 2 for Android devices.
#elif UNITY_IOS
GameProperties.platformID = 3;
// ID 3 for Apple Devices.
#endif
}
}
At this point the static int "platformID" in GameProperties.cs will contain the ID for the platform the game is running on. So, in my Player.cs script:
public class Player : Monobehaviour
{
private int platformID;
void Start()
{
platformID = GameProperties.platformID;
}
void Update()
{
// If the platform is Unity Editor or Windows PC...
if (platformID == 0 || platformID == 1)
{
// PC controls.
}
// If the platform is Android Device or Apple Device...
else if (platformID == 2 || platformID == 3)
{
// Mobile controls.
}
}
}
This method seems to work great for me, and I imagine that it is pretty efficient, considering I only access the GameProperties.cs script once in the Player.cs script.
However, since I am a beginner-intermediate game developer, I would like some insight. Is this a good way to use static variables? Is there a more efficient/simple way to detect the platform a game is running on, and let all other scripts have access to that information? Thank you.
And just to be clear, GameProperties.cs will never be attached to any GameObject.
It might be good. But. I recently read Some tip about coding. It was not really good to use a number. It might confuse you. Some time. So. You can change to Enum. To avoid "$$anonymous$$agic number" on your code.
But since you use for platform ID. Did you try this? > http://docs.unity3d.com/ScriptReference/Application-platform.html
Or something like this?
if (Application.is$$anonymous$$obilePlatform)
{
//$$anonymous$$obile platform : $$anonymous$$obile controller
}
else
{
//Not mobile platform : PC controller
}
Although this is on itself a good way of using static variables. When talking about efficiency, the following is (slightly) better in this situation:
public class Player : $$anonymous$$onobehaviour
{
void Update()
{
#if UNITY_EDITOR ||UNITY_STANDALONE_WIN
// PC controls.
#elif UNITY_ANDROID || UNITY_IOS
// $$anonymous$$obile controls.
#endif
}
}
The reason why this is more efficient is because:
the #if is something you tell to the compiler. When one of these are defined, compile this, else don't compile it.
$$anonymous$$eaning that
if you build for windows/Editor: "// PC controls." will be added to your code
if you build for Android/IOS: "// $$anonymous$$obile controls." will be added to your code.
Note android/IOS one gets grey (in vs at least, not sure about monodevelop). The things in grey aren't compiled, don't throw compiler errors and won't be included in your build (thus reducing your final build size). (If you build for android/IOS they obviously will be included, and the pc one will be left out) Another really $$anonymous$$or advantage is that you have one if check less (as the #if is done at compile time and not in the final build) and one variable less (platformID).
I also think it's a good way to use static variables. I did exactly the same thing in my project using Application.platform. Having a class where you keep static values that are global to your whole project is always useful, and in your example I don't see how it could be a bad practice.
Things turn tricky when you start to dealing with Singleton blocks, but if you understand the difference between what is hapening in your scene and what is happening in your whole project, it's not complicated.
I just recently learned about the "Conditional" Attribute to get things a bit cleaner. Doing the following does allow you to call functions without compiler directives which are more readable but really depend on the use case:
using Unity.Engine;
using System.Diagnostics;
public class SomeClass : $$anonymous$$onoBehaviour{
void Update(){
HandleInputPC();
HandleInput$$anonymous$$obile();
}
[Conditional("UNITY_STANDALONE")]
void HandleInputPC(){
Debug.Log("PC Input");
}
[Conditional("UNITY_IOS"), Conditional("UNITY_ANDROID")]
void HandleInput$$anonymous$$obile(){
Debug.Log("$$anonymous$$obile Input");
}
}
Fun thing here is, that the calls just grey out and wont be called on the wrong platform, but still be recognized by "find references" etc.
Your answer
Follow this Question
Related Questions
Static variable resetting when it shouldn't! 0 Answers
Change value of a static variable multiple times in one script 2 Answers
a static variable resets whenever i enter again the update method 0 Answers
Does reading/changing Static variables constantly affect Performance or get Garbage Collected? 1 Answer
How do I reset a static gameObject? 1 Answer