Any way to modify Unity's code?


So - I’ve been thinking about this for a while, but I haven’t found any topics on it.
The Unreal engine allows users to adjust the engines internal code to help them make games. I get this from a topic on the unreal website about BioShock Infinite, where the article says:
“(Irrational Games) have replaced or heavily modified vast portions of Unreal Engine 3 for BioShock”

Is there a way to do the same thing with Unity? Modify the engines code to add something/fix something etc? If so - would this be legal?

Any help is appreciated!

Allow me to be brave (or maybe stupid lol), and say yes! But not in a legitimate/straight-forward manner, and just for the managed side of Unity (its managed assemblies)

Recently I found out about the ‘beautiful’ dynamic keyword, I was so happy, you have no idea! Only soon to discover Unity’s rusty Mono version doesn’t support it! It broke my heart! I decided it’s time for payback, Unity broke my heart, it’s time to break ‘it’!

So I read about all assembly/dll modifications/hacks/edits, etc. I came to find out about Mono Cecil - it’s really powerful! - You can modify .NET assemblies with it with ease! For example.

Then I discovered Reflexil!

So I hooked it up to my reflector (.NET Reflector or JustDecompile - It’s a plugin there you can install it for free - Unfortunately it’s not available for ILSpy)

Now, there’s something really stupid in Unity, if you make a PropertyDrawer for a list/array, it will forcefully display the array size field even if your drawer’s OnGUI is freckin empty! That is PLAIN stupid! - I didn’t like that. So I thought I’d find this stupid method and do something about it.

Sure enough, after a very simple reflect, I found it sitting at UnityEditor.EditorGUI.ArraySizeField - But we are not interested in it actually, we’re more interested into the caller, who’s using/calling this? If you’re using ILSpy, you could right click on the method and collapse “Used by”, you’ll see that it’s called by UnityEditor.EditorGUI.SinglePropertyField (Which is the method called when you do a PropertyField) - it has a giant switch statement for the propertyType that’s how it figures out what control to draw for your property.

This is the relevant section for us:

case SerializedPropertyType.ArraySize:
	int intValue2 = EditorGUI.ArraySizeField(position, label, property.intValue, EditorStyles.numberField);
	if (EditorGUI.EndChangeCheck())
		property.intValue = intValue2;

Now, what can we do about it? I tried a couple of things with Reflexil:

  1. I tried deleting the whole switch statement lol. Unity didn’t like that, it didn’t even execute with the patched dll.
  2. I tried nopping the opcodes for the ArraySizeField call, Unity ran, but gave some invalid IL code exceptions.
  3. The successful shot, was not to modify anything, but was just to redirect the call to ArraySizeField to a method of my own! (This won’t change the actual code, but just the call opcode - So as far as Unity’s considered, everything’s legit!)

But this didn’t really solve the property drawer problem, it seemed that if you make a property drawer for an array/list, the drawer will be applied to the individual elements not the whole array. AND, now you can’t even see the size of public arrays/lists (in other words, the array size field is now gone, not just for customly drawn arrays/lists) - But… the point of this is that this method of redirecting calls, WORKED!

A couple of notes:

  1. If you get errors from unity, (unable to load type, type-safety stuff, etc) - Try and verify your patched assembly using peverify.exe
  2. Of course, the patched dll has to go to your Unity’s directory. In Windows, it’s: "C:\Program Files (x86)\Unity\Editor\Data\Managed"
  3. PLEASE don’t do this if you don’t know what you’re doing! There are high chances of you unintentionally breaking things.
  4. Make sure you backup all the DLLs you mess with.
  5. OMG is this illegal??! Who F* cares? let’s light some flares :slight_smile:
  6. Of course, if you try to publish an asset using a patched DLL, the asset store might not accept it. So you’d have to find a way around it, maybe a simple way would be to do this whole thing by code (via Mono Cecil), make a dll for your legit helper classes, include the injection code there and obfuscate the dll or something Idk use your imagination.

I encourage this only as an experiment for educational purposes only - Just careful not to shoot yourself in the foot.

Yes, you buy a source license.

Its costs “upwards of 6 figures” last time I checked.

Unlike UDK however, Unity has a perfectly speedy scripting language in C#/Mono so you can do most anything you need to from the scripting level.