<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://www.jerrodputman.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://www.jerrodputman.com/" rel="alternate" type="text/html" /><updated>2024-07-08T22:23:06-07:00</updated><id>https://www.jerrodputman.com/feed.xml</id><title type="html">Jerrod Putman</title><subtitle>A programmer focused on Swift and game development.</subtitle><author><name>Jerrod Putman</name></author><entry><title type="html">Initializing iOS Unity Plugins</title><link href="https://www.jerrodputman.com/2011/09/01/unity-plugins-and-uiapplicationdidfinishlaunchingnotification/" rel="alternate" type="text/html" title="Initializing iOS Unity Plugins" /><published>2011-09-01T00:00:00-07:00</published><updated>2011-09-01T00:00:00-07:00</updated><id>https://www.jerrodputman.com/2011/09/01/unity-plugins-and-uiapplicationdidfinishlaunchingnotification</id><content type="html" xml:base="https://www.jerrodputman.com/2011/09/01/unity-plugins-and-uiapplicationdidfinishlaunchingnotification/"><![CDATA[<p>So you’re writing your Unity plugin to do some cool native functionality, but you really need it to do some work right when the app launches. There are usually two ways to solve this problem: 1) Create an “init” function that you call from Unity script when your first scene is loaded, or worse 2) modify <code class="language-plaintext highlighter-rouge">application:didFinishLaunchingWithOptions:</code> directly. Technically, there’s a third option too, involving creating a category of the <code class="language-plaintext highlighter-rouge">AppController</code> delegate and “overriding” <code class="language-plaintext highlighter-rouge">application:didFinishLaunchingWithOptions:</code>. The OpenFeint Unity plugin uses this method, actually, but as I mentioned in a [previous post][extending-ccnode], this has some serious drawbacks, especially if you want to use the technique more than once (and yes, I realize I’m the one who originally wrote that plugin… I didn’t know!).</p>

<p>I’d like to introduce you to the <code class="language-plaintext highlighter-rouge">UIApplicationDidFinishLaunchingNotification</code> key, something which has become a good friend of mine.</p>

<p>It always bugged me that the <code class="language-plaintext highlighter-rouge">UIApplicationDidFinishLaunchingNotification</code> key existed. I couldn’t possibly think of a use for it. In my mind, the first place that any application code could ever run was in <code class="language-plaintext highlighter-rouge">application:didFinishLaunchingWithOptions:</code> (or its precursor, <code class="language-plaintext highlighter-rouge">applicationDidFinishLaunching:</code>), and so the key was not necessary. I assumed it was just some thing required by the OS that we weren’t really supposed to use.</p>

<p>But one day, I decided to actually investigate the uses of this key instead of basing my assumptions on pure speculation. I found the <code class="language-plaintext highlighter-rouge">NSObject</code> class method <code class="language-plaintext highlighter-rouge">load</code>. Suddenly, the key started to make sense.</p>

<p>The documentation for load says that the method is “invoked whenever a class or category is added to the Objective-C runtime; implement this method to perform class-specific behavior upon loading.” Essentially, what this means is that any code inside your class’s load class method will be executed before <code class="language-plaintext highlighter-rouge">application:didFinishLaunchingWithOptions:</code>. If you want to write any startup code, this seems like it would be the place to do it. But there is a caveat: Other classes may not have loaded themselves yet, so it’s not safe to do too much in this method.</p>

<p>Instead, you should add your class as an observer of the <code class="language-plaintext highlighter-rouge">UIApplicationDidFinishLaunchingNotification</code> key with an action method to do any initialization you want. This will allow all classes to be fully loaded, but still allow for initialization code to be run without having to have either an initialization function in Unity script or by modifying <code class="language-plaintext highlighter-rouge">AppController</code>’s <code class="language-plaintext highlighter-rouge">application:didFinishLaunchingWithOptions:</code>.</p>

<p>Here’s an example:</p>

<div class="language-objc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">@interface</span> <span class="nc">MyCoolPlugin</span> <span class="p">:</span> <span class="nc">NSObject</span>
 
<span class="c1">// Class stuff.</span>
 
<span class="k">@end</span>
</code></pre></div></div>

<div class="language-objc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">static</span> <span class="n">MyCoolPlugin</span> <span class="o">*</span><span class="n">_sharedInstance</span> <span class="o">=</span> <span class="nb">nil</span><span class="p">;</span>
 
<span class="k">@implementation</span> <span class="nc">MyCoolPlugin</span>
 
<span class="k">+</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="n">load</span>
<span class="p">{</span>
    <span class="p">[[</span><span class="n">NSNotificationCenter</span> <span class="nf">defaultCenter</span><span class="p">]</span> <span class="nf">addObserver</span><span class="p">:</span><span class="n">self</span> <span class="nf">selector</span><span class="p">:</span><span class="k">@selector</span><span class="p">(</span><span class="n">createMyCoolPlugin</span><span class="o">:</span><span class="p">)</span> <span class="n">name</span><span class="o">:</span><span class="n">UIApplicationDidFinishLaunchingNotification</span> <span class="n">object</span><span class="o">:</span><span class="nb">nil</span><span class="p">];</span>
<span class="p">}</span>
 
<span class="k">+</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">createMyCoolPlugin</span><span class="p">:(</span><span class="n">NSNotification</span> <span class="o">*</span><span class="p">)</span><span class="nv">notification</span>
<span class="p">{</span>
    <span class="c1">// This code will be called immediately after application:didFinishLaunchingWithOptions:.</span>
    <span class="c1">// You could use this to create an instance of your plugin class, like so:</span>
    <span class="n">_sharedInstance</span> <span class="o">=</span> <span class="p">[[</span><span class="n">MyCoolPlugin</span> <span class="nf">alloc</span><span class="p">]</span> <span class="nf">init</span><span class="p">];</span>
<span class="p">}</span>
 
<span class="c1">// Your plugin methods.</span>
 
<span class="k">@end</span>
 
<span class="c1">// C functions to access your plugin from Unity script.</span>
</code></pre></div></div>

<p>Not only can you use <code class="language-plaintext highlighter-rouge">UIApplicationDidFinishLaunchingNotification</code>, but you can also observe keys like <code class="language-plaintext highlighter-rouge">UIApplicationDidEnterBackgroundNotification</code>. Essentially, you can plug into most of <code class="language-plaintext highlighter-rouge">UIApplicationDelegate</code>‘s methods without having to modify Unity’s <code class="language-plaintext highlighter-rouge">AppController</code>. And naturally, if you’re creating standalone Objective-C libraries, this method is essentially required unless you want your users to modify their app delegate.</p>]]></content><author><name>Jerrod Putman</name></author><category term="Technical" /><category term="Unity" /><category term="plugins" /><category term="C#" /><category term="Objective-C" /><category term="iOS" /><category term="programming" /><summary type="html"><![CDATA[Easily initialize Unity iOS plugins at app startup with UIApplicationDidFinishLaunchingNotification.]]></summary></entry><entry><title type="html">The Unity/Objective-C Divide</title><link href="https://www.jerrodputman.com/2010/01/10/the-unityobjective-c-divide/" rel="alternate" type="text/html" title="The Unity/Objective-C Divide" /><published>2010-01-10T00:00:00-08:00</published><updated>2010-01-10T00:00:00-08:00</updated><id>https://www.jerrodputman.com/2010/01/10/the-unityobjective-c-divide</id><content type="html" xml:base="https://www.jerrodputman.com/2010/01/10/the-unityobjective-c-divide/"><![CDATA[<p>I love <a href="http://www.unity3d.com">Unity</a>! The Unity engine is a fantastic piece of technology, allowing us to quickly develop games without having to worry about a lot of the underlying stuff. However, Unity is essentially an additional layer on top of the iOS SDK, which means that while the iOS SDK may advance with new features, the Unity engine is generally a step behind with adding these features in a manner that can be easily accessed through script.</p>

<p>Enter Objective-C: This is the language that iOS apps are usually written in. Unity provides some support for calling native Objective-C code from Unity script, but generally only in one direction. This can be pretty limiting especially if you’re trying to use a lot of the fancy features in newer iOS versions. Sure, you can pass around information using the <code class="language-plaintext highlighter-rouge">PlayerPrefs</code> trick, but this has the problem of not being instantaneous, and it forces the app to constantly poll for new commands, which isn’t a good idea performance-wise.</p>

<p>What follows is a method for immediately calling Objective-C code from Unity script and also vice versa! That’s right, two-way communication between Objective-C and Unity script that’s instantaneous.</p>

<h2 id="unity-to-objective-c">Unity to Objective-C</h2>

<p>First, since the release of Unity 4, all Unity iOS licenses have access to a quick and easy way of calling Objective-C code from Unity script. In C#, just do the following:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="n">System</span><span class="p">.</span><span class="n">Runtime</span><span class="p">.</span><span class="n">InteropServices</span><span class="p">.</span><span class="nf">DllImport</span><span class="p">(</span><span class="s">"__Internal"</span><span class="p">)]</span>
<span class="k">extern</span> <span class="k">static</span> <span class="k">public</span> <span class="kt">int</span> <span class="nf">AwesomeFunction</span><span class="p">(</span><span class="kt">int</span> <span class="n">awesomeParameter</span><span class="p">);</span>
</code></pre></div></div>

<p>Then, in a C/C++/Objective-C file somewhere in your Unity-built Xcode project, do the following:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="nf">AwesomeFunction</span><span class="p">(</span><span class="kt">int</span> <span class="n">awesomeParameter</span><span class="p">)</span>
<span class="p">{</span>
   <span class="c1">// My awesome code goes here.</span>
 
  <span class="k">return</span> <span class="n">somethingAwesome</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>You may have to wrap your function prototypes in</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">extern</span> <span class="s">"C"</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
</code></pre></div></div>

<p>if you’re using C++/Objective-C++ (or your code is in a <code class="language-plaintext highlighter-rouge">.mm</code> or <code class="language-plaintext highlighter-rouge">.cpp</code> file) due to name mangling.</p>

<h2 id="unity-to-objective-c-the-playerprefs-trick">Unity to Objective-C (The PlayerPrefs Trick)</h2>

<p>Previously, the above method was only available for Unity iOS Pro licensees. Since Unity 4, that is no longer the case, but I am leaving this section in the post for reference.</p>

<p>The <code class="language-plaintext highlighter-rouge">PlayerPrefs</code> trick you may already be familiar with involves sending a command to Objective-C from Unity script like this:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">PlayerPrefs</span><span class="p">.</span><span class="nf">SetString</span><span class="p">(</span><span class="s">"Commands"</span><span class="p">,</span> <span class="n">String</span><span class="p">.</span><span class="nf">Format</span><span class="p">(</span><span class="s">"AwesomeCommand|{0}|{1}"</span><span class="p">,</span> <span class="n">awesome1</span><span class="p">,</span> <span class="n">awesome2</span><span class="p">));</span>
</code></pre></div></div>

<p>Or something similar. You’ll still be sending commands this way. However, in Objective-C, you probably have an <code class="language-plaintext highlighter-rouge">NSTimer</code> that is constantly polling to see if the “Commands” key in <code class="language-plaintext highlighter-rouge">NSUserDefaults</code> has a string in it. You might even have some fancy queueing system set up so that you can call multiple commands in a row without them overwriting each other. The issue, though, is that if you need a result back from one of these commands, you can’t get it instantaneously. You have to set up some kind of polling system in Unity script to wait for a return result to show up in some other <code class="language-plaintext highlighter-rouge">PlayerPrefs</code> key. Messy.</p>

<p>But there’s a better way. Let me introduce you to <em>Key-Value Observing</em>. The iOS SDK provides a method for setting up “observers” for certain things currently going on in the system. It just so happens that one of the things that you can “observe” is <code class="language-plaintext highlighter-rouge">NSUserDefaults</code>. That’s our ticket!</p>

<p>Somewhere in your Objective-C code (where you might normally set up the <code class="language-plaintext highlighter-rouge">NSTimer</code> for polling the <code class="language-plaintext highlighter-rouge">NSUserDefaults</code>), place the following code:</p>

<div class="language-objc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[[</span><span class="n">NSUserDefaults</span> <span class="nf">standardUserDefaults</span><span class="p">]</span> <span class="nf">addObserver</span><span class="p">:</span><span class="n">self</span> <span class="nf">forKeyPath</span><span class="p">:</span><span class="s">@"Command"</span> <span class="n">options</span><span class="o">:</span><span class="mi">0</span> <span class="n">context</span><span class="o">:</span><span class="nb">nil</span><span class="p">];</span>
</code></pre></div></div>

<p>Then, create a method like the following:</p>

<div class="language-objc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">observeValueForKeyPath</span><span class="p">:(</span><span class="n">NSString</span> <span class="o">*</span><span class="p">)</span><span class="nv">keyPath</span> <span class="nf">ofObject</span><span class="p">:(</span><span class="n">id</span><span class="p">)</span><span class="nv">object</span> <span class="nf">change</span><span class="p">:(</span><span class="n">NSDictionary</span> <span class="o">*</span><span class="p">)</span><span class="nv">change</span> <span class="nf">context</span><span class="p">:(</span><span class="kt">void</span> <span class="o">*</span><span class="p">)</span><span class="nv">context</span>
<span class="p">{</span>
   <span class="c1">// Command parsing code goes here.</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The <code class="language-plaintext highlighter-rouge">observeValueForKeyPath:ofObject:change:context:</code> method is essentially the function you had before that parsed the commands from <code class="language-plaintext highlighter-rouge">PlayerPrefs</code>/<code class="language-plaintext highlighter-rouge">NSUserDefaults</code>. What the <code class="language-plaintext highlighter-rouge">addObserver:forKeyPath:options:context:</code> method does is set self to be an observer of <code class="language-plaintext highlighter-rouge">NSUserDefaults</code>, meaning that every time you set the <code class="language-plaintext highlighter-rouge">PlayerPrefs</code> in Unity script, the <code class="language-plaintext highlighter-rouge">observeValueForKeyPath:</code> method gets called immediately!</p>

<p>What this now allows you to do is to set a result key in Objective-C and immediately access it in Unity script. Here’s an example:</p>

<div class="language-objc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Objective-C code</span>
<span class="k">if</span><span class="p">([[[</span><span class="n">NSUserDefaults</span> <span class="nf">standardUserDefaults</span><span class="p">]</span> <span class="nf">getObjectForKey</span><span class="p">:</span><span class="s">@"Command"</span><span class="p">]</span> <span class="nf">isEqualToString</span><span class="p">:</span><span class="s">@"DoSomething"</span><span class="p">)</span>
<span class="p">{</span>
   <span class="c1">// Return a result by setting the key here.</span>
   <span class="p">[[</span><span class="n">NSUserDefaults</span> <span class="nf">standardUserDefaults</span><span class="p">]</span> <span class="nf">setInteger</span><span class="p">:</span><span class="mi">1</span> <span class="nf">forKey</span><span class="p">:</span><span class="s">@"Result"</span><span class="p">];</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Unity C# code</span>
<span class="kt">int</span> <span class="nf">CallDoSomething</span><span class="p">()</span>
<span class="p">{</span>
   <span class="n">PlayerPrefs</span><span class="p">.</span><span class="nf">SetString</span><span class="p">(</span><span class="s">"Command"</span><span class="p">,</span> <span class="s">"DoSomething"</span><span class="p">);</span>
   <span class="c1">// Before, doing something like this would be very bad!</span>
   <span class="k">return</span> <span class="n">PlayerPrefs</span><span class="p">.</span><span class="nf">GetInt</span><span class="p">(</span><span class="s">"Result"</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>As you can see, you can get immediate results from the Objective-C code! Hooray!</p>

<h2 id="objective-c-to-unity-the-mono-runtime-trick">Objective-C to Unity (The Mono Runtime Trick)</h2>

<p><em>NOTE: Unity provides a C function called UnitySendMessage that you can use to send messages back to your scripts. However, it’s not nearly as robust as this method since it waits until the next frame to execute and you can’t call static methods since you have to supply the function with a GameObject name. However, if you don’t need the extra functionality, I recommend you use that instead.</em></p>

<p>There are many instances where you need to capture an event in Objective-C and then pass this off immediately to your Unity scripts so that you can update your game. While using <code class="language-plaintext highlighter-rouge">NSUserDefaults</code> to send information back to <code class="language-plaintext highlighter-rouge">PlayerPrefs</code> is certainly doable, a polling system would need to be set up in Unity script and it would never be instantaneous.</p>

<p>To get this working, you need to know a little bit about the underlying Unity frameworks. Unity uses a framework called <a href="http://www.mono-project.com">Mono</a>, which is an open-source cross-platform implementation of .NET. When you use something in the <code class="language-plaintext highlighter-rouge">System</code> namespace or <code class="language-plaintext highlighter-rouge">String.Format</code>, you’re actually using .NET libraries (or rather, Mono implementations of .NET libraries), and not something Unity-specific. While the actual invocation of the Mono runtime isn’t visible from inside the Xcode project, that doesn’t mean we can’t still have access to the Mono functions.</p>

<p>You can do amazing things with C. You can also do terrible things with C. That’s why it’s preferred by so many programmers, as data and memory in C is completely malleable. You can do almost anything with it. Even though we don’t have access to the Mono header files in the Unity Xcode project, by doing some handy Internet searches, we can get the function prototypes of all of the Mono functions we’ll need to get what we want.</p>

<p>In addition, many Mono functions require or return special MonoTypes. This would be a problem in C#, but in C a void pointer cures all! For our purposes, here are all of the MonoTypes that we need:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">typedef</span> <span class="kt">void</span><span class="o">*</span> <span class="n">MonoDomain</span><span class="p">;</span>
<span class="k">typedef</span> <span class="kt">void</span><span class="o">*</span> <span class="n">MonoAssembly</span><span class="p">;</span>
<span class="k">typedef</span> <span class="kt">void</span><span class="o">*</span> <span class="n">MonoImage</span><span class="p">;</span>
<span class="k">typedef</span> <span class="kt">void</span><span class="o">*</span> <span class="n">MonoClass</span><span class="p">;</span>
<span class="k">typedef</span> <span class="kt">void</span><span class="o">*</span> <span class="n">MonoObject</span><span class="p">;</span>
<span class="k">typedef</span> <span class="kt">void</span><span class="o">*</span> <span class="n">MonoMethodDesc</span><span class="p">;</span>
<span class="k">typedef</span> <span class="kt">void</span><span class="o">*</span> <span class="n">MonoMethod</span><span class="p">;</span>
<span class="k">typedef</span> <span class="kt">void</span><span class="o">*</span> <span class="n">gpointer</span><span class="p">;</span>
<span class="k">typedef</span> <span class="kt">int</span> <span class="n">gboolean</span><span class="p">;</span>
</code></pre></div></div>

<p>To be honest, you don’t even really have to set up the <code class="language-plaintext highlighter-rouge">typedef</code>s, but it makes the function prototypes look cleaner and more readable. Remember, since pointers simply point to memory, they don’t really need a type.</p>

<p>Now for the function prototypes that we’ll need. The following is the bare minimum of functions needed to accomplish calling Unity script code from Objective-C. (Remember: You may need to wrap these in <code class="language-plaintext highlighter-rouge">extern “C” { … }</code> if you’re using C++/Objective-C++ due to name mangling.)</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">MonoDomain</span> <span class="o">*</span><span class="nf">mono_domain_get</span><span class="p">();</span>
<span class="n">MonoAssembly</span> <span class="o">*</span><span class="nf">mono_domain_assembly_open</span><span class="p">(</span><span class="n">MonoDomain</span> <span class="o">*</span><span class="n">domain</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">assemblyName</span><span class="p">);</span>
<span class="n">MonoImage</span> <span class="o">*</span><span class="nf">mono_assembly_get_image</span><span class="p">(</span><span class="n">MonoAssembly</span> <span class="o">*</span><span class="n">assembly</span><span class="p">);</span>
<span class="n">MonoMethodDesc</span> <span class="o">*</span><span class="nf">mono_method_desc_new</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">methodString</span><span class="p">,</span> <span class="n">gboolean</span> <span class="n">useNamespace</span><span class="p">);</span>
<span class="n">MonoMethodDesc</span> <span class="o">*</span><span class="nf">mono_method_desc_free</span><span class="p">(</span><span class="n">MonoMethodDesc</span> <span class="o">*</span><span class="n">desc</span><span class="p">);</span>
<span class="n">MonoMethod</span> <span class="o">*</span><span class="nf">mono_method_desc_search_in_image</span><span class="p">(</span><span class="n">MonoMethodDesc</span> <span class="o">*</span><span class="n">methodDesc</span><span class="p">,</span> <span class="n">MonoImage</span> <span class="o">*</span><span class="n">image</span><span class="p">);</span>
<span class="n">MonoObject</span> <span class="o">*</span><span class="nf">mono_runtime_invoke</span><span class="p">(</span><span class="n">MonoMethod</span> <span class="o">*</span><span class="n">method</span><span class="p">,</span> <span class="kt">void</span> <span class="o">*</span><span class="n">obj</span><span class="p">,</span> <span class="kt">void</span> <span class="o">**</span><span class="n">params</span><span class="p">,</span> <span class="n">MonoObject</span> <span class="o">**</span><span class="n">exc</span><span class="p">);</span>
<span class="n">gpointer</span> <span class="nf">mono_object_unbox</span><span class="p">(</span><span class="n">MonoObject</span> <span class="o">*</span><span class="n">obj</span><span class="p">);</span>
</code></pre></div></div>

<p>Here’s where we need to explain things: We call Unity script functions by using the <code class="language-plaintext highlighter-rouge">mono_runtime_invoke function</code>. However, before we can call this, we need to get the <code class="language-plaintext highlighter-rouge">MonoMethod</code> (essentially, the pointer to the Unity script function we want to call) from the assembly file that was compiled by Unity when you hit “Build &amp; Run”. So how do we get that?</p>

<p>First things first, we need to get the domain where all of the Unity scripts are running. In the vaguest of terms, a domain is kind of a box where scripts are run. So we need to grab the Mono domain first:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">MonoDomain</span> <span class="o">*</span><span class="n">domain</span> <span class="o">=</span> <span class="n">mono_domain_get</span><span class="p">();</span>
</code></pre></div></div>

<p>Simple enough. We now have the location where all of the Unity scripts are being run. Now to get the <code class="language-plaintext highlighter-rouge">MonoMethod</code>, we first need to get a reference to the assembly that contains the function. In your Xcode project, if you look in the Libraries group, you’ll see a bunch of <em>dll.s</em> files. These files get compiled by Xcode into DLL files that get placed into your app’s <em>Data</em> folder. If you don’t believe me, take your built Unity app, <em>Show Package Contents</em> on it, and then browse around.</p>

<p>Knowing the folder structure of the built application is actually important to this process, as we’re going to be directly referencing these DLLs for the next step. We need to get the assembly itself so we can read through it and find our functions. Here’s how to do that:</p>

<div class="language-objc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">NSString</span> <span class="o">*</span><span class="n">assemblyPath</span> <span class="o">=</span> <span class="p">[[[</span><span class="n">NSBundle</span> <span class="nf">mainBundle</span><span class="p">]</span> <span class="nf">bundlePath</span><span class="p">]</span>
   <span class="nl">stringByAppendingPathComponent:</span><span class="s">@"Data/Assembly - CSharp.dll"</span><span class="p">]</span>
<span class="n">MonoAssembly</span> <span class="o">*</span><span class="n">assembly</span> <span class="o">=</span> <span class="n">mono_domain_assembly_open</span><span class="p">(</span><span class="n">domain</span><span class="p">,</span> <span class="n">path</span><span class="p">.</span><span class="n">UTF8String</span><span class="p">);</span>
<span class="n">MonoImage</span> <span class="o">*</span><span class="n">image</span> <span class="o">=</span> <span class="n">mono_assembly_get_image</span><span class="p">(</span><span class="n">assembly</span><span class="p">);</span>
</code></pre></div></div>

<p>You’ll notice we put in the path of the built DLL file from the application’s main bundle. Note that the assembly you’re looking for might be different for the class method you’re trying to access. To find out the correct assembly, highlight the script in Unity and go into <em>Debug</em> mode in the <em>Inspector</em>. The <em>Assembly Identifier</em> should tell you the name of the assembly. We then get the assembly from our domain. The <code class="language-plaintext highlighter-rouge">MonoImage</code> is something we’ll need for the next step.</p>

<p>We have our assembly now, and we can start accessing the functions inside it. To do this, we need to tell Mono what functions we’re looking for. (For ease of use, I’m only going to be looking for static methods in classes without a namespace. If you want to access specific objects or call non-static methods, I suggest you read up on the official documentation on <a href="http://www.mono-project.com/Embedding_Mono">Embedding Mono</a>.)</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">MonoMethodDesc</span> <span class="o">*</span><span class="n">desc</span> <span class="o">=</span> <span class="n">mono_method_desc_new</span><span class="p">(</span><span class="s">"AwesomeClass:AwesomeFunction()"</span><span class="p">,</span> <span class="n">FALSE</span><span class="p">);</span>
<span class="n">MonoMethod</span> <span class="o">*</span><span class="n">method</span> <span class="o">=</span> <span class="n">mono_method_desc_search_in_image</span><span class="p">(</span><span class="n">desc</span><span class="p">,</span> <span class="n">image</span><span class="p">);</span>
<span class="n">mono_method_desc_free</span><span class="p">(</span><span class="n">desc</span><span class="p">);</span>
</code></pre></div></div>

<p>Notice that the <code class="language-plaintext highlighter-rouge">MonoMethodDesc</code> (literally, <em>MonoMethod Description</em>) is created by giving <code class="language-plaintext highlighter-rouge">mono_method_desc_new</code> a string that contains the method that we want to call. Remember to put the class name before the function and follow it with a colon, not a period. If you want to access a method with parameters, do something like this:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="s">"AwesomeClass:AwesomerFunction(int,int,int)"</span>
</code></pre></div></div>

<p>Formatting is very important. There shouldn’t be any spaces between the method parameters. After getting the description, we then search the assembly image for the method. Doing all of this searching could impact performance in your app, so it’s recommended that you do all of this in an initialization function and store the pointers to the various <code class="language-plaintext highlighter-rouge">MonoMethod</code>s you want to use. After we have the method pointer, we free the <code class="language-plaintext highlighter-rouge">MonoMethodDesc</code> that was created.</p>

<p>Now you have your <code class="language-plaintext highlighter-rouge">MonoMethod</code>! And you say you want to call it! We can do that very easily now:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">mono_runtime_invoke</span><span class="p">(</span><span class="n">method</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</code></pre></div></div>

<p>See? Very simple. If your method had some parameters in it, you need to pass the arguments as a void pointer array to the third parameter of <code class="language-plaintext highlighter-rouge">mono_runtime_invoke</code>, like so:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="n">param1</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">param2</span> <span class="o">=</span> <span class="mi">27</span><span class="p">;</span>
<span class="kt">void</span> <span class="o">*</span><span class="n">args</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span> <span class="o">&amp;</span><span class="n">param1</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">param2</span> <span class="p">};</span>
 
<span class="n">mono_runtime_invoke</span><span class="p">(</span><span class="n">method</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</code></pre></div></div>

<p>We are essentially passing the arguments by their address via way of an array.</p>

<p>If your Unity method returns a value (such as an integer), you can retrieve that value by doing something like this:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">MonoObject</span> <span class="o">*</span><span class="n">result</span> <span class="o">=</span> <span class="n">mono_runtime_invoke</span><span class="p">(</span><span class="n">method</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
<span class="kt">int</span> <span class="n">int_result</span> <span class="o">=</span> <span class="o">*</span><span class="p">(</span><span class="kt">int</span> <span class="o">*</span><span class="p">)</span><span class="n">mono_object_unbox</span><span class="p">(</span><span class="n">result</span><span class="p">);</span>
</code></pre></div></div>

<p>And that’s it! There are a few caveats to using this method of invoking Unity script methods: Firstly, it’s slow. It would not be recommended to call these many times per frame or even once every frame. It’s primarily good for callbacks that occur every now and then (like for <em>GameKit</em> connection results, etc). Secondly, you’re putting a lot of trust in the Mono and Unity developers to not change things around too drastically. If you upgrade Unity and your code suddenly stops working, you’ll need to downgrade to the previous version of Unity or muck around until you can find out what was changed.</p>

<h2 id="conclusion">Conclusion</h2>

<p>Finding all of this out was a long weekend project for me, and it has definitely been worth it. Functionality that I simply didn’t think was possible without official Unity support is now immediately available, and I am now able to bounce back and forth between Unity script and Objective-C to get access to whatever I need. There are performance issues to consider, but on the whole the flexibility outweighs the potential performance pitfalls. It just requires you to properly plan your app with these things in mind.</p>

<p>It should be added, using the Objective-C to Unity callback functionality is not for the faint of heart, and certainly not for those who aren’t well-versed in the art of programming. Just be sure to design your games around what you <strong>can</strong> do, not around what you <strong>wish</strong> you could do.</p>

<p>I hope you’ve found this both educational and useful and that you’ll consider contributing your own findings to the Unity community.</p>]]></content><author><name>Jerrod Putman</name></author><category term="Technical" /><category term="Unity" /><category term="Objective-C" /><category term="interop" /><category term="C#" /><category term="programming" /><category term="iOS" /><category term="technical" /><summary type="html"><![CDATA[Achieving greater control for communicating between Unity script and Objective-C using the Mono runtime.]]></summary></entry></feed>