top of page
Mirror Ripple.jpg

Unity Networking Package which includes Interactables, Portals / Multi World Mirrors and Mesh Texture Drawing all working across the network using mirror. Like my Scarlett game engine this project came out of an AIE assessment which I took to the next level, which I tend to do by a lot. You know what can I say, I love to code and I love to code cool things!

​

Anyways this started out as part of a networking project which showed the basics on how to use the Unity Networking Library - Mirror. However soon after finishing the requirements for the assessment I developed some ideas that I wished to test inside Unity, with the potential of using these in a Unity Package or in future projects. These included:

​

  • Drawing on objects in the environment and having the same drawing replicated on all other clients

  • Multi world portals/magic mirrors which players and objects could pass through

  • Interactables in the environment with changes replicated across all clients

Mesh Drawing

​

First up - Mesh drawing! This was the first idea that I wanted to implement - Drawing textures onto objects and have the same texture draw out on all connected clients. List of features includes:

​

  • Mesh drawing using circle brush or texture brush with multiple blend and tint options

  • High performant Bresenham Algorithm to smoothly connect points while drawing regardless of frame rate

  • Sends drawing data to all clients which includes object to draw on and the pixel coordinates to draw out the same drawing. Uses specialized Vector2Short class that holds 16 bit values to save on the amount of data that gets sent across the network.

  • Optimizations - Minimal heap allocation with alpha threshold clipping for transparent textures

​

Drawable objects would be labelled with the tag 'Drawable'. On game startup all objects that have the 'Drawable' tag has a custom material added to their renderer along with a blank transparent texture with specified dimensions that is used to overlay the drawings on the object. This is used by the mesh drawing to affect the textures on the drawable material.

Mesh Drawing - Inspector

Performance & Optimizations

​

Once the mesh drawing script was completed and the drawings where successfully replicating across the network I then had to tackle the *rather* small issue of performance, with a total of around 10 fps whilst drawing in-game. After analyzing for performance bottlenecks I went through and changed the scripts dependence on heap allocation, opting instead for a pre-allocation of bresenham coordinates with initialized vector2Shorts, and an index to keep track of how many valid coordinates where in the array. This meant that no heap allocation was occurring per frame whilst drawing.

 

Another optimization was to inline as much as possible inside the texture drawing sections of the code as they would be the most taxing segments of the script with large quantities of recursion. At first the bresenham algorithm would return well over 600 points to draw in, and this would result in 600 separate calls to the draw function. So to circumvent this I created a singular function that would loop over all the draw calls within the drawBresenham function. Alongside many other small changes throughout the script the performance was dramatically improved and now provides no noticeable slowdown in game no matter how fast the player draws.

 

What was at first a 90% slowdown thanks to the texture drawing turned into a roughly 5% performance hit after the optimizations. A pretty nice improvement! And well within the performance range to use within a commercial product.

external-content.duckduckgo.com.png

Multi World - Portals / Magic Mirrors

​

This addition to the project was something that I'd wished to try after reading up on the theory of portals and methods of implementing them into games. This eventually developed into the the idea of a multiverse that is interconnected through the portals. With the base principle of having a static level environment but have the ability to place objects in different worlds, separate from each other.

​

My final implementation tweaked the portal code to instead show the reverse from the same portal, creating a mirror like effect where you look back at the things behind you. Once the player or object passes through the mirror the object would change which world it was based in to the world that the mirror is connected to. Using layers to designate worlds I could disable rendering of objects not on the same world as the camera, as well as disable physics between objects in different worlds so invisible collisions don't take place. This allows for using the same static environment without needing to duplicate things, but have different objects placed throughout the levels depending on the world you're in.

To provide some extra flare to the mirror I added some ripple effects to the portal shader that triggers once an object moves through. This was accomplished by taking the object's position and raycasting towards the mirror. This would return a UV coordinate that I could communicate to the shader to ripple out from that UV position, with a start and end point that grows and fades away as the ripple expands. Using sine functions as well as multiplications for the waves amplitude and frequency I was able to manipulate the normals on the mirrors surface to distort outwards like a wave.

​

Ripple Sub-Shader

Ripple Shader Graph.png

Unity Network Interactables

Mesh Drawing Updated.png
bottom of page