Unity 4.6 and Modules

Since version 4.5, Unity has a module manager menu option, but it seemed it was not yet implemented. In 4.6 however, that module manager is used for the new GUI system. The source of the new UI is also available now and the install instructions talk about a specific folder in the unity install to copy the files to. I experimented a bit with that folder to see if Unity is also able to load my own files/modules. The answer to that is YES.

Quick rundown:

The modules are stored in a specific folder setup. The root folder is “Unity/Editor/Data/UnityExtensions” on Windows and “Unity.app/Contents/UnityExtensions” on Mac. The folder structure for the modules inside it follow the following pattern: “Organization/Name/Version”. So for the new GUI it is “Unity/GUISystem/4.6.0”. In a modules folder there are the DLLs and an ivy.xml. The ivy.xml describes the actual module and is used by unity to see which modules are available and if the module version is suited for the unity version. The ivy.xml contains the names of the dlls that need to be loaded.

In depth:

Unity modules are loaded from the following paths:

Windows: <Unity Install dir>/Editor/Data/UnityExtensions
Mac: Unity.app/Contents/UnityExtension

In that folder there is the following structure for modules:

<Organization>/<Name>/<Version>

The version there is the module version. Not the unity version.

A module consists out of 1 or more DLLs and an ivy.xml that describes it. For example, the GUI system module contains the following:

Unity/GUISystem/4.6.0/Editor/UnityEditor.UI.dll
Unity/GUISystem/4.6.0/Standalone/UnityEngine.UI.dll
Unity/GUISystem/4.6.0/UnityEngine.UI.dll
Unity/GUISystem/4.6.0/ivy.xml

It seems there is support for build specific dlls because of the Standalone folder.

The ivy.xml contains version number of the module as well as the unityversion it is made for. For example, here is the unity GUISystem ivy.xml

<?xml version="1.0" encoding="utf-8"?>
<ivy-module version="2.0" e:basepath="C:\BuildAgent\work\d63dfc6385190b60\Extensions\guisystem" xmlns:e="http://ant.apache.org/ivy/extra">
  <info version="4.6.0" organisation="Unity" module="GUISystem" e:packageType="UnityExtension" e:unityVersion="4.6.0p1" />
  <publications>
    <artifact name="UnityEngine.UI" type="dll" ext="dll" e:guid="f5f67c52d1564df4a8936ccd202a3bd8" />
    <artifact name="Editor/UnityEditor.UI" type="dll" ext="dll" e:guid="80a3616ca19596e4da0f10f14d241e9f" />
  </publications>
</ivy-module>

The important parts are the “e:unityVersion” attribute and the “artifact” tags. e:unityVersion determines the unity version that should be able to run this module. It can be a specific version, but it looks like it also allows more global versions. As an example, in this ivy.xml the e:unityVersion is set to “4.6.0p1” and unity will refuse to load it if unity is a different version, but you could set the e:unityVersion to “4.6” and then unity will load it as long as unity is a version of 4.6.(e.g. 4.6.1)

Artifacts determine which assemblies need to be loaded. The unity GUISystem has 2 dlls that need to be loaded and those are written here. The name must match the dll file and the type needs to be “dll”. ext could be left out, but if present should also be “dll”. e:guid is the guid of the dll. When making a dll you can define a guid in the assemblyinfo. That guid should match the one written here.

It looks like unity will only load the xml/folder structure on start, so if you add a new module unity will need to be restarted. But if you only change the dlls, then unity will automatically reload them and recompile the project when switching back to unity.

Making my own module:

To make your own module, first read this page. That page describes how to make a managed dll for use in unity. To make a module from that dll, you only need to add an ivy.xml and copy it into the correct folder.

For example, You want to make a module called MyFirstUnityModule. You  already have the MyFirstUnityModule.dll ready to use. First, you need to make the correct folder structure under the UnityExtensions folder. For the organization you can use your own name or a company name. In this case, lets name the organization MyFirstCompany. It is our first version, so the version is 1.0.0. You need to make the following folder structure

UnityExtensions/MyFirstCompany/MyFirstUnityModule/1.0.0

You then copy the created MyFirstUnityModule.dll to that folder. After that you copy the GUISystem ivy.xml to this folder and open it in your favorite text editor. You need to change the file it so it matches your module information. In this case, the version, organization, module, e:unityVersion attributes and the artifact tag. You also need to copy the dll guid into the e:guid attribute.

<?xml version="1.0" encoding="utf-8"?>
<ivy-module version="2.0" e:basepath="C:\BuildAgent\work\d63dfc6385190b60\Extensions\guisystem" xmlns:e="http://ant.apache.org/ivy/extra">
  <info version="1.0.0" organisation="MyFirstCompany" module="MyFirstUnityModule" e:packageType="UnityExtension" e:unityVersion="4.6" />
  <publications>
    <artifact name="MyFirstUnityModule" type="dll" ext="dll" e:guid="f5f67c52d1564df4a8936ccd202a3bd8" />
  </publications>
</ivy-module>

After you have done that, you can open unity(or restart it if it was already open). If you then check the module manager(under edit-modules…) you can see that unity loaded your newly created module!

Notes:

For more info about the ivy.xml, see the ivy project page.
For an explanation in Japanese, see here.
For other questions, join the #Unity3D irc channel on freenode.net.

Edit:

Shana explained a bit more about how it worked internally on irc:

<Zerot> shana: re comment: interesting. didn't know that. that will make it easier to keep the modules when updating unity
<shana> Zerot: also, when setting versions, something like 1.0.0.1a2 is valid
<Zerot> shana: For the module version you mean?
<shana> Zerot: yes, in any version in the ivy file
<shana> Zerot: also you shouldn't have to restart Unity, only the domain needs to be restarted (and that happens every time you go into play mode)
<shana> Zerot: it "should", but I can't quite remember what the code is doing
<Zerot> shana: with my experiments I didn't hit the play button. But that might work, yeah
<Zerot> it does reload automatically when the dlls are changed though. similar as if you put them in assets
<shana> Zerot: check what unity is loading in the editor log, I made it log everything there
<Zerot> oh nice
<shana> modules show up there, with paths and versions, so you can check what it's doing
<Zerot> ill do
<Zerot> will*
<shana> a module will have preference in the installation directory unless another module supersedes it with a higher version btw

One thought on “Unity 4.6 and Modules

  1. Nice detective work 🙂

    You don’t have to put your modules into the unity installation directory directory. Unity will helpfully look for user modules in

    Windows: ProgramData/Unity/[UnityVersion]/UnityExtensions
    OSX: ~/.local/share/Unity/[UnityVersion]/UnityExtensions

Leave a Reply

Your email address will not be published. Required fields are marked *