Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

Safe Access to Internal Unity Code

A disclaimer by Unity's very own Ted Wikman.

For some of us, good just isn't good enough. The best programmers reuse existing functionality that gets externally maintained. But sometimes, that functionality only exists internally. Even though you should be aware that internal code is often experimental and subject to change, it may be safer to reuse if it is complex code that is better maintained by the authors themselves.

There are many reasons why you would want to access Unity's internals. I needed it to replicate Unity's dragging on my TimeSpanField. In this post I will show you exactly how to access Unity's internals safely and cleanly with complete control over where and how you expose it.


DraggerUtility

Unity's Internal Dragger Behavior

Creating TimeSpanField I tried to replicate Unity's implementation as close as possible: this gives me results that simulate Unity's own behavior. Researching LongField I came across this code:


Replicating Unity's implementation is good because it is likely to remain supported for a long time, however in this case it is locked behind an internal access modifier. Even though we could copy and maintain the code ourselves, that just gives us the problem we are trying to avoid, because at that point it doesn't replicate Unity's behavior anymore.

InternalBridgeDef

Unity's Access Handle

If you create an Assembly Definition with the name Unity.InternalAPIEngineBridge.001 up to .024 that assembly is able to access all of Unity's internal code: problem solved!

It is however very important that you never use this approach. If 2 Assembly Definition share the same name, then Unity will not compile. And since Unity uses these numbers 001 to 024 for their in house packages but we don't know which ones, we have to assume all are taken.

Assembly Definition Reference

Referencing  2D Common Package

This is where we have a trick up our sleeve. Create an Assembly Definition Reference: these can hook into an existing Assembly Definition, and add to it as if it were its own. If you install Unity's 2D Common package (through the package manager), they have a perfectly good assembly sitting under Packages > 2D Common > Runtime / Editor > InternalBridge > InternalBridgeDef for us to use!

The one in green is my own, the one in red is from Unity's 2D Common package. They don't have to share names, but doing so is best practice.

With this technique, you can access Unity's internals anywhere you want to! But should you?

InternalEngineBridge

Safely Accessing Internals

Much like sex, accessing internals is best done behind closed doors. Put your InternalBridgeDef inside a folder called InternalBridge: you can think of this folder as behind closed doors

Add a static class InternalEngineBridge:

Make sure to put the class inside a namespace so that it doesn't clash with other Assembly Definition Reference.

Make the InternalEngineBridge internal so that it can't just be called willy-nilly (the irony is not lost on me). But seriously: as Chesterton's fence dictates, only access internals if you understand what you're doing. For the safety of our code base, it is only responsible to take every precaution and limit its influence.

Add a script AssemblyInfo:


It's a very short script but it makes our InternalEngineBridge visible only to the assemblies we want. You can keep adding assemblies in this script as you need.

The last thing to do is find our assembly and reference the 2D Common's InternalBridgeDef.

Again, the red dot connects to the InternalBridgeDef from the 2D Common package.

TimeSpanField

Using Internals

Now that we have our Assembly Definition set up, every script in that assembly can reference our InternalEngineBridge. So we put our TimeSpanField in there...

And presto!


You can keep adding Assembly Definition Reference as you need, exposing only the things you need to. Our only dependency is on the 2D Commons package installed - granted it's a bit of an odd requirement, but not a hard one to swallow to get safe access to internal Unity code!

Support this post

Did you like this post? Tell us

Leave a comment

Log in with your itch.io account to leave a comment.