I’m just a small-fry, independent, self-proclaimed game developer who’s been working in earnest on a game for the past half year or so. While working on my project I’ve recently come up with what I think is a real good solution to the glaring inability of not being able to expose C# interface fields in your MonoBehaviour scripts like you would other component references or primitive types. After several layers of polishing and submitting I’ve finally heard from the Asset Store team today that my asset has passed review and has gone live in the store! So I submit to you: IUnified - Interfaces for Unity!
It is designed to be as simple and unobtrusive as possible to easily integrate into Unity’s workflow. Features include:
Easily expose interface fields in your script’s inspector without the need for defining a custom editor every time!
Assign components that implement your interface as you would any other reference - just drag and drop.
Custom selection list allows you to quickly pick your interface implementation from existing scene and prefab object scripts.
Serialized like any other reference so Unity always “remembers” the assignment.
You basically just subclass the included generic type using your interface like so:
[System.Serializable]
public class MyInterfaceContainer : IUnifiedContainer<IMyInterface> { }
And that’s it! Now you can have MyInterfaceContainer type fields in your script and they’ll automatically be drawn using the supplied custom property drawer that exposes the above listed functionality.
using System.Collections.Generic;
using UnityEngine;
public class MyScript : MonoBehaviour
{
public MyInterfaceContainer InterfaceField;
public List<MyInterfaceContainer> InterfaceListField;
}
I hope you all find this as useful as I have so far. I’m asking $5 for the work I’ve put in with the hopes of further funding the development of my game - so when buying my asset you will also help a game to be made as an added bonus! Mathematical!
I should mention that currently there is a limitation with not being able to use the above subclasses inside a collection - Unity will serialize/initialize the collection itself automatically, but items in the collection come through null in the process. I’m working on enabling an unobtrusive workaround for the next release, so stay tuned if you’re interested in such a feature!
Updated in version 1.1.
Sounds very useful, and with a modest price. Do you have competitors in the AssetStore which accomplish something similar? I’ve avoided using Interfaces altogether to avoid the headaches this supposedly solves, so I’m quite interested. Can you please describe what you mean by the following? Explain it like I’m five, I’m rather confused by the whole sentence:
“Custom selection list allows you to quickly pick your interface implementation from existing scene and prefab object scripts”
Hey Sunny!
As far as I know there aren’t any other assets in the store that offer a solution to integrate interfaces into Unity - like you say most people quickly learn to avoid them altogether when developing in Unity. I thought I came up with a reliable and generic enough solution to the problem that I decided to put it out there and potentially generate some funding for my projects.
About the selection list: It’s essentially my version of the built-in object selector (the little ◉ button next to object references in the inspector that lets you pick from a list of objects of the type in question) which lets you pick components that implement your interface. Like so:
Version 1.2 has just been accepted (alot sooner than I thought) - its updated to work with Unity 4.3 to make it unnecessary to have to decorate fields with the [IUnifiedContainer] attribute.
I’ve also introduced an implementation of IList that can be used to abstract the use of a container derived object away so that given a script like this:
using System.Collections.Generic;
using Assets.IUnified;
using UnityEngine;
public class MyScript : MonoBehaviour
{
public IList<IMyInterface> MyInterfaces
{
get
{
return _interfaceList ?? (_interfaceList = new IUnifiedContainers<MyInterfaceContainer, IMyInterface>(() => _interfaces));
}
set
{
_interfaces = value.ToContainerList<MyInterfaceContainer, IMyInterface>();
}
}
private IList<IMyInterface> _interfaceList;
[SerializeField]
private List<MyInterfaceContainer> _interfaces;
}
would allow you to directly access your interface implementation in a collection like this:
using System.Collections.Generic;
using UnityEngine;
public class MyOtherScript : MonoBehaviour
{
public MyScript MyScript;
public void Update()
{
foreach(var myInterface in MyScript.MyInterfaces)
{
myInterface.InterfaceMethod();
}
}
}
Just to let people know: there seems to be a problem produced by Mono when using the null coalescing operator (??) and targeting the Web Player in Unity. Replacing their instances with the conditional operator (?:) where possible or explicit if/else statements avoids the issue.
I’ve submitted a fix related to this issue for version 1.2.1 which is now pending review.
Can classes implementing the interface be of any type (eg. normal classes whose parent is System.Object) or do they need to be MonoBehaviours?
I think a huge barrier to selling your asset is the lack of documentation. Why don’t you put up that readme.pdf online? I , as a buyer, don’t want to buy an asset that claims to do something, but I can’t see how to use it and there aren’t any tutorials, documentation or anything online.
Also, creating a dummy blog just to have a link to submit to the asset store is not really…good…
Why don’t you create a real website, you can have it up and running for free in under 30 minutes, and you’d look much more reliable, accessible and professional? Go get free php hosting if you don’t want to pay for it, install wordpress, get one of the professional looking wordpress themes (there are many), and viola!
Not having a real website might pass for selling models because you don’t really need support for them. But selling scripts is different and most people never buy scripts that don’t have a reliable seller that seems to offer good support. Even if they are really reasonably priced as your own. (The price really is tempting.)
Absolutely, yes - anything that implements the interface can be assigned. Of course, if it isn’t Component derived, like a MonoBehaviour, it won’t be assignable directly in the inspector - you’ll have to do that in code during runtime, but it is supported.
I really appreciate your advice and feedback as a prospective user. My thinking was that I had come up with an acceptable solution to integrating interfaces into Unity for my personal use and was mostly curious to see how other people would react if I polished it up and submitted it to the store at an affordable price. I think you’re very right though - I’ll start looking into putting up a website. I’ve very limited web development experience so initially shied away from it, but you make it sound easy so I’ll start looking into it.
So thank you for the advice! In the meantime I’ll attach the readme so you and others can have more information upfront. 1459957–90369–$readme.pdf (686 KB)
You’re welcome.
Regarding the wordpress website. It might seem intimidating, but it IS really simple. Most hosts have one click installations of wordpress available so you just go to your control panel and choose where to instal it, and they do the rest for you. Once that’s done you just log into your admin panel and start looking at options you have available. It is pretty user friendly so you’ll pick it up pretty fast. I say that because I’ve never watched/read a single wordpress tutorial, I just installed it and started using it. Even if it takes you a while to get the hang of it(which it wont) you’ll be glad in the end because you’ll be creating your presence on the internet.
Very cool stuff, I’ve been pushing for something similar in this thread. I’m unfamiliar with the nitty-gritty details of editor scripting so I couldn’t implement it myself. What you’ve got is pretty close.
Unity’s approach to game object composition is certainly an improvement over deep inheritance entity hierarchies. However, I feel like we are just one step away from game object structures that are much more robust and flexible. That step is better support for interfaces and dependency injection. Your asset is doing just that, so thank you!
Here’s some features/improvements I’d like to see:
In the editor, in addition to being able to inject an existing script instance, it would be nice to be able to inject scripts directly from the assets, thereby creating a new unique instance.
I’d like it if parent scripts could be unfolded to see/edit the injected script’s properties
I’d like to have the option to hide the injected scripts from the gameobject’s flat-list of monobehaviours, and only appear in their parent script (when unfolded)
These improvements could lead to much more neatly organized gameobject structures in my opinion. For systems that are more delicate like Behavior Trees, this would be perfect.
Anyway, good job on this, I hope you keep supporting it
Although my original intention was to simply expose interface fields you could assign implementing MonoBehaviours to, your ideas had occurred to me and I agree would be nice to have. The main obstacle is Unity’s serialization system, which is pretty closed. I’ve had some success implementing something like what you describe, but it involved handling the serialization myself during runtime and was a bit difficult to manage in a generic and robust way.
Hopefully they’ll open the serialization system up in the future and allow for easier and more reliable customization. Until then I’ve had to shelve those ideas and continue working on my project, but I’d like to revisit the concept again some day.
I’ve seen no issue running in Unity 4.3.3f1 - was it working before you updated?
Try deleting the entire IUnified folder and re-importing the asset. Make sure not to move it anywhere else, it should remain in “Assets/IUnified” in order to work properly.
If that doesn’t work then I’d need more details to see what’s going on: What file is the error actually referencing? If it’s one of yours, could you post it in it’s entirety?
All my scripts were in “Assets/standard assets”, and the IUnified was in “Assets”, there’s my mistake.
I moved everything on “Assets” and it’s working.
Hello! - I have been learning from your codes and following some of your approaches when it comes to using Styles and GUIs for editors. However, I think I came up on a bad habit that you’ve been using. Check this out.
Try to open up the select window of IUnified - keep the window open - and then do something that triggers a recompile. You should get an error saying you shouldn’t use GUI stuff outside of OnGUI.
The reason is that one should initialize styles/gui-related stuff in OnGUI/OnInspectorGUI - Like so.
I like your approach! I do seem to remember having issues with GUIStyle initializations, but somehow worked them out without error by handling them the way I did. Now I’m kinda wondering why it worked for me and doesn’t seem to be working for you… I’ll have to look into this.
More specific to IUnified though, were you actually able to reproduce the issue you’ve described? I have the select window explicitly closing itself when it loses focus and so am not able to cause any recompilation/serialization to try and reproduce the issue. If you’ve found a way to do so with IUnified, please let me know, aye?
Yep it’s reproducible - here’s a video - Fortunately it’s easy to solve. Just move all the initialization of your GUIStyles to an InitStyles method, and in OnGUI/OnInspectorGUI do a if (!hasInit) { hasInit = true; InitStyles(); }
Ah, I see - that wouldn’t have occurred to me. Many thanks for the video, that helped alot! An update has been submitted and is now pending review.
Thanks again, vexe!