Scripting in Unity for experienced programmers
For programmers new to Unity
In Unity you can use scripts to develop pretty much every part of a game or other real-time interactive content. Unity supports scripting in C# and there are two main ways to architect your C# scripts in Unity: object-oriented design, which is the traditional and most widely used approach, and data-oriented design, which is now possible in Unity, for specific use cases, via our new high-performance multithreaded Data-Oriented Technology Stack (DOTS).
Unity supports C#, an industry-standard language with some similarities to Java or C++
In comparison to C++, C# is easier to learn. Additionally, it’s a “managed language”, meaning that it automatically does the memory management for you: allocating-deallocating memory, covering memory leaks, and so on.
Generally, C# is preferable to C++ if you want to make a game first, and then deal with more advanced aspects of programming later.
All gameplay and interactivity developed in Unity is constructed on three fundamental building blocks: GameObjects, Components, and Variables.
Any object in a game is a GameObject: characters, lights, special effects, props–everything.
Components
GameObjects can’t do anything on their own. To actually become something, you need to give a GameObject properties, which you do by adding Components.
Components define and control the behavior of GameObjects they are attached to. A simple example would be the creation of a light, which involves attaching a Light Component to a GameObject (see below). Or, adding a Rigid body Component to an object to make it fall.
Components have any number of editable properties, or variables, that can be tweaked via the Inspector window in the Unity editor and/or via script. In the above example, some properties of the light are range, color, and intensity.
Unity’s built-in Components are very versatile, but you will soon find you need to go beyond what they can provide to implement your own logic. To do this, you use scripts to implement your own game logic and behaviour and then add those scripts as Components to GameObjects. Each script makes its connection with the internal workings of Unity by implementing a class which derives from the built-in class called MonoBehaviour.
Your script Components will allow you to do many things: trigger game events, check for collisions, apply physics, respond to user input, and much, much more. See the Unity Scripting API for more information.
The traditional GameObject-Component concept continues to work well because it’s easy to understand for programmers and non-programmers alike, and easy to build intuitive UIs for. You add a Rigidbody Component to a GameObject and it will start falling, or a Light Component to a GameObject and it will emit light. And so on.
However, the Component system was written in an object-oriented framework and it creates challenges for developers when it comes to managing cache and memory in ever-evolving hardware.
Components and GameObjects are “heavy C++” objects. All GameObjects have a name. Their Components are C# wrappers on top of C++ components. This makes them easy to work with, however, it can come at a cost to performance because they potentially end up stored in an unstructured way. That C# object could be anywhere in memory. The C++ object can also be anywhere in memory. Things are not grouped together in contiguous memory. Every time anything is loaded in CPU for processing, everything has to be fetched from multiple locations. It can get slow and inefficient and therefore, require a lot of optimization workarounds.
To address these performance problems, we’re rebuilding the core foundation of Unity with the high-performance, multithreaded Data-Oriented Technology Stack or DOTS (currently in Preview).
DOTS makes it possible for your game to fully utilize the latest multicore processors efficiently. It’s comprised of:
- The C# Job System for running multithreaded code efficiently.
- The Entity Component System (ECS) for writing high-performance code by default.
- The Burst Compiler for producing highly optimized native code.
In DOTS, the ECS is the new Component system; what you do with a GameObject in the traditional object-oriented way, you do with an Entity in this new system. Components are still called just that. The critical difference is in the data layout. You can read more about this in the blog post “On DOTS: Entity Component System”.
In addition to being a better way of approaching game programming for design reasons, using ECS puts you in an ideal position to leverage Unity's C# Job System and Burst Compiler, letting you take full advantage of today's modern hardware.
DOTS’ multithreaded systems enable you to create games that run on a variety of hardware and build richer game worlds with more elements and more complex simulations. Performant code in turn contributes to optimal thermal control and battery lifetime on players’ mobile devices. By moving from object-oriented to data-oriented design, it can be easier for you to reuse your code and for others to understand and work on it.
As some of the technology of DOTS is in Preview, it is advised that developers use it to solve a specific performance challenge in their projects, as opposed to building entire projects on it. Check out the “More Resources” section at the bottom of this page for links to key DOTS resources.
Tweaking and debugging is efficient in Unity because all the gameplay variables are shown right as developers play, so things can be altered on the fly, without writing a single line of code. The game can be paused at anytime or you can step-through code one statement at a time.
Here are some great resources to learn more about optimizing in Unity:
Understanding optimization in Unity
Optimizing graphics performance
General best practices (including extensive tips on optimizing Unity’s UI system)
.NET: Unity has used an implementation of the standard Mono runtime for scripting that natively supports C#. Unity currently ships with Visual Studio for Mac instead of MonoDevelop-Unity on macOS. On Windows, Unity ships with Visual Studio.
The .NET 4.6 scripting runtime in Unity supports many of the new exciting C# features and debugging available in C# 6.0 and beyond. This also provides a great C# IDE experience to accompany the new C# features.
IL2CPP: This is a Unity-developed scripting backend which you can use as an alternative to Mono when building projects for some platforms. When you choose to build a project using IL2CPP, Unity converts IL code from scripts and assemblies into C++ code, before creating a native binary file (.exe, apk, .xap, for example) for your chosen platform.
Note that IL2CPP is the only scripting backend available when building for iOS and WebGL.
As a programmer you have a great deal of flexibility in Unity because you can extend the editor with your own custom windows that behave just like the Inspector, Scene or any other built-in windows in the standard editor. Adding your own tools to Unity supports you and your team’s unique workflows and needs, ultimately boosting efficiency.