Modifying a prototype in UnityScript

Previously titled “Adding functions, variables to Runtime Classes”

It is an everyday basic of OO programming that you can stick more functions in an existing class. Just to be clear, here is how you do it in Objective-C for instance, it’s just a category…

http://it.toolbox.com/blogs/macsploitation/extending-classes-in-objectivec-with-categories-27447

I’m afraid I don’t know how to do this with UnityScript / Javascript.

Example. Consider say Color …

file:///Applications/Unity/Unity.app/Contents/Documentation/Documentation/ScriptReference/Color.html

How would you add a new Class variable, or a new Class Function?

Thanks!

You are not going to be able to add anything to an existing class in UnityScript - which is not Javascript, and most obviously not Javascript when considering things like .prototype etc. UnityScript is a .NET language most like JScript.NET.

Just adding properties and methods to object isn’t the .NET way and for a reason, it gets very complicated very quickly. It’s also much harder to do that in a precompiled language rather than a runtime one (Javascript/Ruby both are interpreted and support lots of dynamic playing around - Ruby does this elegantly)

As Fattie mentions above, the .NET way of adding methods to an existing class is to use Extension Methods which are a c# technique - you might be able to call them from Javascript afterwards but they’d have to be put in a Plugins folder to be visible to Javascript which is compiled after c#. Extension methods allow you to write a function that appears to be a member of the class but is in fact implemented elsewhere - it is syntactic sugar only, but it looks good and keeps the code clean. There are no such things as Extension Properties by the way.

Ok, per @fattie in the comments to my first answer I’m posting a second answer that covers a method of having extended properties on any object that you can’t just add them to, probably because they came from somewhere else and you don’t have the code.

This technique will work from Javascript and C#, but the code has to be in C# hence I’ve built it as a plugin unity package you can download from here.

You use it like this (clearly this is an example, I could just modify test!):

//Javascript

//You can have any number of these type of classes
class MyExtendedProperties
{
	//Any number of members
	public var aProperty : String;
}

//This is a test class for this example
//try to believe that it's an object that we've
//got that we can't change the source of
class test
{
	//This is just so that there is something there
	public var test: String = "Hello";
}

function Start () {
	//Create a new instance of test
	var o = new test();
	//Give it an extra property in a new instance of MyExtendedProperties
	Extension.Get.<MyExtendedProperties>(o).aProperty = "World";
	//Read it back
	Debug.Log(Extension.Get.<MyExtendedProperties>(o).aProperty);
	
	//Next time the garbage collector runs our extended properties will be cleaned up
	//as nothing has a reference to o
}

The C# is probably pretty obvious from that Javascript apart from the fact that the .Get method is an extension method callable in C# like this

  anythingAtAll.Get<MyExtendedProperties>().aProperty = "cool huh";

For reference - if we had .NET 4 then there is a built in class to do this.

So the basic idea it to have a dictionary, keyed off the object that contains another class that you can put extra information in. The problem of just doing this straight off is that the fact that the object is the key will keep the object alive forever - read massive memory leaks if this gets used too widely. The answer to that is to use weak references and get a notification when the garbage collector runs to enable you to clean up the extra instances associated with objects that have been killed.

I use Jeff Richter’s method of knowing that the Garbage Collector has run (that man is bloody smart) and then clean up the extra classes that have been created.