Fernando…
When you define a variable or an object at the top of a script class and outside any method these variables default to being public variables so that any class outside of the defining class can get access to. This is the case when using C# with Visual Studio and the .NET Framework as well as when working with MonoDevelop and the MonoDevelop Framework, which is an equivalent of the .NET Framework.
When Unity3d itself needs access to such script declarations, the lectures demonstrate this by defining such variables at the top of a script class.
However, there is a drawback to these types of simpler explanations in the lectures since they are being made as easy to understand as possible. This drawback is the lack of understanding of a property of declarations and methods we call “scope”. “Scope” defines the capabilities of how variables and methods can be seen within only a module, a solution, or outside of a solution. This sounds more complex than it is. And to make it simple, let us stay with just variable declarations…
In C# there are 4 primary variable scopes, which are called “access modifiers”, that can be used…
- public
- private
- internal
- protected
Each of these modifiers should precede the variable type in a variable declaration. So for example, if we were to define a public variable of type string with a name of “myString” it would appear as such…
public string mystring = ""; // we initialize the variable to a string that contains no data; this is NOT null
In Unity3d, the C# scripting that you will write will in essence function the same way as the C# used in a .NET web application; In both cases you are writing classes that will always be subordinate to the overriding application. In .NET web applications, the overriding application is that of Internet Information Server or IIS. In Unity3d development, the equivalent application is always the Unity3d engine.
You will write as many C# classes as you require to make your game functional based on your requirements. All of these classes will default to being “public” since the Unity3d engine requires access to them. This is done by default and you can see this every time you define a new class in MonoDevelop for your game development. Simply look at the modifier that precedes the new class definition in the source code. In Visual Studio, the framework simply uses the default with no modifier.
Within every class you create for Unity3d you will define variable and object declarations. Each of these declarations defined outside of any method (functions or procedures; a function returns a value, a procedure does not… ie. “void”) will default to being “public”.
A “public” declaration means that what is being defined can be seen by any method within the class that contains the declaration, any other class in your project solution, as well as the Unity3d engine, both of which are external to this class. By making such declarations “public” you allow the Unity3d engine to interact with these declarations as you have seen in the various lectures.
HOWEVER, it is always a “best practice” to always provide the variable modifier with your variable declaration. Not doing so means that you are allowing for the default to take its place. Though this is correct coding, it makes the coding ambiguous and should be avoided.
There are two other types of variable scoping that will be used in your C# classes for Unity3d; at least in the learning phases of your studies. These scope types are “private” and “local”.
A “private” variable declaration in a class and defined outside of any method can be seen by any method in the class but not outside the class; in this latter case by the other classes in your project solution and the Unity3d engine. By the way, you can NEVER define a class as “private”.
You can define either a “public” or “private” variable anywhere in a C# class and their corresponding scoping will always apply. This means that you can define such variables at the top of a class, in its middle, or at the bottom.
HOWEVER, it is “best practice” to always define such declarations at the top of a class as practically all developers do.
It is also a “best practice” to use as few “public” declarations in a class as possible and only define those that are actually required. This is a standard 'best practice" for both proper coding techniques but just as importantly for security concerns whereby you limit the amount of exposure of each class to the outside world.
The last type of declaration modifier we have is that of “local”. HOWEVER, there is no actual scope modifier that can be applied here as it is always the default in such cases.
“Local” declarations are defined WITHIN a METHOD or a BLOCK of code. For example, a “local” declaration in a method would look like the following…
private void MyMethod() {
int MyInteger = 0;
}
For a block it would like the following…
for (int x = 0; MyInteger < 10, MyInteger++) {
}
In both cases, the variable, “MyInteger” can only be seen within the method or the block of the for-loop. As a result, if you attempt to use “MyInteger” anywhere else in the class but within the “scope” of where it was defined, the compiler will give you an error.
The compiler will also give you warnings if you define “MyInteger” as both a “private” and “local” declaration; the first being outside of any method, the other within a method. What will happen here is that the compiler will warn you of ambiguity with your variable declarations.
The “internal” and “protected” modifiers are used for more advanced coding techniques when declaring variables and objects.
An “internal” modifier allows you to make a declaration that allows you to expose your variables or classes only to other classes within your solution. So if you create 5 C# classes and make one of the classes “internal” instead of “public”, the other 4 classes in your project solution will be able to see the classes but Unity3d will not. Subsequently, for these other 4 classes to work with the internals of your “internal” class, you will have to define your variables, objects, and methods that you wish to expose to these other 4 classes as “internal” as well.
The “protected” modifier is only used when dealing with inheritance hierarchies. However, historically this modifier has caused more trouble than it is worth as it has destroyed many an inheritance hierarchy by making them to rigid, This modifier allows only an inherited class to see the declarations with a modifier of “protected”.
Despite the hoopla made over inheritance hierarchies, which were made very popular in the 1990s and early 2000s, such programming has often been the bane of many a project because the project designers did not know what they were doing. If you do find yourself in need of working with inheritance make sure you keep such hierarchies as small as possible and avoid using the “protected” modifier.
For more definitive information on scope and declaration modifiers, see the following… Modifiers (C# Reference)
Steve