
16 apr Techorama talk: the making of (part 3)
Implementing a Unity3D Client
by Johnny Hooyberghs
My decision to create a 3D environment to visualize the arena and fighting robots made me look into the Unity Game Engine. As a professional .NET backend developer I should never need a game engine, so this is an opportunity to learn something new and challenging. Today, Unity is a very popular tool to create both small and large games. Unity uses the Mono project to offer a choice, next to JavaScript, to use C# as a programming language for its scripting. Because I am a C# developer since the start of .NET, this made my leap into Unity a lot more familiar.
PLATFORM
Unity allows me to compile my project to a multitude of platforms like Desktop, Mobile, Web, and Console. For this project, I decided to compile to native Windows for Desktop and optionally to the web using WebGL. The desktop version will be a Windows executable with some supporting files that can be shared in a ZIP archive or an installer. The WebGL version can be integrated into a webpage to make it available through the web browser.
ASSETS
Unity provides a user interface to manage a number of assets. Games generally use a large number of assets that make up the entire visual world but also support the dynamics of this world through scripts. CSharpWars uses a number of different assets like scenes, models, animations, textures, materials, prefabs, scripts and many others.
Assets can be created with a range of supporting tools, like 3d modeling software. Since I am not a graphical wizard, I downloaded a number of free assets from different locations in order to prototype a working game front-end. Unity provides a built-in Unity Asset Store to download both free and paid assets and use them directly in your games. Some other assets, like textures, can be downloaded from a wide range of websites.
A scene contains your environment and UI. Think of a scene as a unique level. A scene will generally contain a camera to provide a viewport for the player looking at the scene and any number of lights to create a realistic view of the game world. CSharpWars only needs a single environment, containing a platform or arena hosting a number of fighting robots. It also doesn’t contain any UI or menu system and will immediately show the arena and active fight when started. It will contain a single light floating in the air as if it were the sun and it will contain a camera, slowly rotating around the arena, to create a dynamic view of the battlefield.
Models are graphical 3d representations of objects. They exist of polygon meshes and can be placed inside of your 3d environment. CSharpWars uses a simple cube model and transforms it into an arena floor by extending its width, depth, and height. Width and depth are based on the arena dimensions. Height is a small value to make the arena into a thin, but visible, floating floor surface. Other models for robots and effects are downloaded from the Unity Asset Store for free.
Animations are bound to models and are able to animate the position and rotation of individual meshes to create moving models. CSharpWars only uses animations to animate robots from their previous game state to their current game state. The animations for this were included within the robot assets package downloaded from the Unity Asset Store.
Textures are images that makeup mesh surfaces. They are responsible for making a model look realistic. A texture is a simple image that can be wrapped around a mesh surface. All textures in CSharpWars were included with the assets downloaded from the Unity Asset Store or were downloaded from other websites containing free surface texture images.
Materials are assets that take a texture and are linked to a mesh surface. It will use parameters to decide the look and feel of the texture based on known materials like wood, metal or whatever you’d like. An important feature of a material is how it will react to light. Light can be reflected, refracted or absorbed, creating a distinct look and feel.
Prefabs are used as blueprints of physical objects that are used inside your environment. They can contain a collection of assets that together make up a more complex object. This object can easily be instantiated and cloned to make object management a lot easier to handle. CSharpWars uses prefabs for its robots because each robot is built using the same structure. Whenever a new robot is deployed to the arena, an instance of this prefab is created and placed on the correct location in the arena. The instance will contain all properties, parameters, and scripts that are needed for the object to live independently of the others.
Scripts are pieces of C# code that can be linked to different kinds of assets or game objects built from assets. From the script, you are able to change the properties of the attached game object to make your game dynamic and react to certain triggers. CSharpWars does not use a single script with a game-loop but uses a number of prefabs and game objects with linked scripts.
CONTROLLERS
I have called a number of my C# scripts, controllers. These scripts are linked to a game object that represents an important aspect of the environment and evaluates that game object every frame tick of the running game.
The arena itself, a surface defined by a width and height, is managed by an ArenaController. This controller uses another helper script to call the HTTP API endpoint to get the details for the arena. Based on the result, the ArenaController will transform the arena floor to match these dimensions.
On top of the arena, a BotsController is managing the collection of fighting robots. Again by using a helper script, a call to the HTTP API endpoint is executed every two seconds to get the latest list of active robots. If a managed robot is gone from the list, the robot is removed from the arena and all references are cleaned. If a new robot is discovered, the script will instantiate a new robot instance from the prefab and will start managing it. If an existing robot is still in the list, its state is updated.
Next to the BotsController, each robot instance is managed by a BotController. This controller will be notified if the state for the robot has changed and will trigger actions or animations based on this. The BotController will perform frame-by-frame evaluations to correctly animate a robot performing a move like walking, turning, fighting or even dying.
A number of smaller controllers will manage things like flying particles due to ranged attacks, explosions due to self destructs, tags for displaying robot names, health and stamina bars.
Source code: https://github.com/Djohnnie/CSharpWars