Scripting tips

The following tips are useful features to know when scripting.

General

We can modify various templates of new Script, Shader, and Compute Shader files. This can be helpful to remove the empty Update stubs which, as we learned, can cause unnecessary runtime overhead. These files can be found in the following locations:

  • Windows: <Unity install>EditorDataResourcesScriptTemplates
  • OSX: /Applications/Unity/Editor/Data/Resources/ScriptTemplates/

The recent release of Unity Version 5.1 introduced the Assert class and allows for assert-based debugging, which some developers are more comfortable with as opposed to exception-based debugging. Check the Unity documentation for more information on Asserts: http://docs.unity3d.com/ScriptReference/Assertions.Assert.html

Calling Debug.Break() is functionally equivalent to pausing the Editor during Play Mode, which can be useful for catching awkward graphical behavior, or as a more convenient alternative to the absurd hotkey required to pause the Scene (Ctrl + Shift + P).

Attributes

Attributes are very useful meta-level tags that can be given to almost any target in C#. They are most commonly used on member data (fields) and classes, allowing us to flag them with special properties so that they can be processed differently. Intermediate and advanced Unity developers will find it worthwhile to read the C# documentation on attributes and use their imagination to come up with their own attributes that help accelerate their workflow. There are quite a few attributes built in to the Unity engine that can be exceptionally useful when used in the right place.

Note

Advanced users will note that attributes can also be given to enums, delegates, methods, parameters, events, modules, and even assemblies.

Variable attributes

Public variables are fairly dangerous things to add to our components, as anything can come along and change the value at runtime, making it hard to trace bugs, as well as requiring special hand holding to prevent the variable from being given an invalid value. However, public variables are usually the first way that Unity developers learn to expose variables in the Inspector View. In some cases, the public variable is absolutely intended to be public, but we don't wish it to be seen in the Inspector. In such a case, the [HideInInspector] attribute can be used to hide the variable from the Inspector, whenever necessary.

However, the preferred approach is to make our variables private or protected and allow Editor-based development by exposing values through the [SerializeField] attribute. This attribute allows private and protected variables to be revealed in the Inspector for designers to manipulate, without risking other components accidentally changing the variable at runtime.

The [Range] attribute can be added to an integer or floating-point field to convert it into a slider in the Inspector View. We can give minimum and maximum values, limiting the range that the value can contain.

Normally, if a variable is renamed, even if we do a refactor through our IDE (whether its MonoDevelop or Visual Studio) then the values are lost as soon as Unity recompiles the MonoBehaviour and makes the appropriate changes to any instances of the component. However, the [FormerlySerializedAs] attribute is incredibly helpful if we wish to rename a variable that has been previously serialized, as it will copy the data from the variable named within the attribute into the given variable during compilation time. No more lost data due to renaming stuff!

Note that it is not safe to remove the [FormerlySerializedAs] attribute after the conversion is completed, unless the variable has been manually changed and resaved since completion. The ".prefab" data file will still contain the old variable name, and so it still needs the [FormerlySerializedField] attribute to figure out where to place the data the next time the file is loaded (for example, when the Editor is closed and reopened). Thus, this is a helpful attribute, but extended use does tend to clutter up our codebase a lot.

Class attributes

The [SelectionBase] attribute will mark any GameObject the component is attached to as the root of selection for the Scene View. This is especially useful if we have meshes that are children of other objects, as we might want the parent object to be selected with the first click, instead of the object with the Mesh Renderer component.

We can use the [RequireComponent] attribute to force designers to attach vital components to the same GameObject if they attempt to attach this component. This ensures any dependencies that our codebase relies on will be satisfied by designers, without having to write out a whole bunch of documentation for them.

The [ExecuteInEditMode] attribute will force the object's Update(), OnGUI(), and OnRenderObject() methods to be called even during Edit Mode. However, there are caveats:

  • The Update() method is only called if something changes in the Scene
  • OnGUI() is only called during Game View events, not for other views such as the Scene View
  • OnRenderObject() is called during any repaint event for the Scene and Game Views

However, this gives such objects a different set of event hooks and entry points compared to typical Editor scripts, so this attribute still has its uses.

Logging

We can add rich text tags to debug strings. Tags such as <size>, <b> (bold), <i> (italics), and <color> all work on debug strings. This can be helpful for differentiating the different kinds of log messages and highlighting specific elements.

Debug.Log ("<color=red>[ERROR]</color>This is a <i>very</i> <size=14><b>specific</b></size> kind of log message");
Logging

The MonoBehaviour class has a print() method for convenience, which does the same thing as Debug.Log().

It can help to create a custom logger class, which automatically appends to the end of every log message. This will push and hide away the unnecessary UnityEngine.Debug:Log(Object) clutter that tends to fill the Console window.

Useful links

Unity technologies provide many useful tutorials on the usage of various scripting features, which are primarily targeted at beginner and intermediate-level developers. The tutorials can be found at https://unity3d.com/learn/tutorials/topics/scripting.

There's a helpful post on Unity Answers, which provides a reference list that covers many of the different scripting and compilation errors we might run across during development, which can be found at http://answers.unity3d.com/questions/723845/what-are-the-c-error-messages.html.

ScriptableObjects are very useful objects and an excellent way of storing game data in a form that does not need to be instantiated at runtime. They work like any other class in that they can contain methods and variables, can be serialized, allow polymorphism, and so on. The only tricky part is they can only be created through scripting, and must be loaded into memory at any time using Resources.Load(). But this allows us to control which ScriptableObjects are present in memory at any given time, giving us more control over runtime memory consumption. Explaining the nuances of ScriptableObjects here would take too much space, but Unity technologies have provided a good introductory examination of ScriptableObjects in the following tutorial video:

https://unity3d.com/learn/tutorials/modules/beginner/live-training-archive/scriptable-objects

Note

Note that, despite the category of the ScriptableObject video, it's generally considered more of an intermediate-level topic. Beginners would be best served by focusing on becoming comfortable with Prefabs, before turning things on their head through ScriptableObjects and the important serialization topics that need to be understood.

Nested Coroutines are another interesting and useful area of scripting that is not well documented. But, the following third-party blog post, which covers a lot of the interesting details, should be considered when working with Nested Coroutines:

http://www.zingweb.com/blog/2013/02/05/unity-coroutine-wrapper

We can figure out when a particular feature was added to the Unity API by checking the API history page at http://docs.unity3d.com/ScriptReference/40_history.html.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.186.153