Writing native MacOSX plugins using Objective C for Unity

Im writing this caus in the attempt of creating a native plugin using objective c i had some fallbacks, minor ones but still. I hadn’t found a clear statement about my problem.

My Problem was that i got the EntryPointNotFoundException when trying to call my native function from within unity or mono for that matter and i could not tell why.

What I was missing was that i needed to write a c wrapper for my objective c code inside the plugin. And then calling the c wrapper function using a c# wrapper inside unity ( last part is same with c/c++ plugins)

So in the following i will describe THE WAY or at least my approach to do this.

I’m using a mac with El Capitan (10.11.5) and Xcode version 7.3.1 as well as Unity 5.3.5p4 (i think any Unity Xcode or OS X version will work but now you know my setup if you run into problems)

The Xcode Part:

At first you have to create a new XCode project to create the bundle.

In there you have to create 3 files:

  • Wrapper.m
  • Plugin.h
  • Plugin.m

The Wrapper.m contains the wrap code for your Objective c plugin:

</pre>
#import <Foundation/Foundation.h>

#import "Plugin.h"

#define GetStringParam( _x_ ) ( _x_ != NULL ) ? [NSString stringWithUTF8String:_x_] : [NSString stringWithUTF8String:""]

extern void Message(char* msg)

{

Plugin* helper = [[Plugin alloc]init];

[helper log:GetStringParam(msg)];

&nbsp;

}

 

Plugin.h

</pre>
#ifndef Plugin_h

#define Plugin_h

#import <Foundation/Foundation.h>

@interface Plugin: NSObject

{

}

- (void) log: (NSString *) message;

@end

#endif

Plugin.m

</pre>
#import <Foundation/Foundation.h>

#import "Plugin.h"

#import <Cocoa/Cocoa.h>

@implementation Plugin : NSObject

NSOpenPanel *panel;

- (void) log: (NSString *) message

{

NSLog(@"Passed message = %@", message);

}

@end
<pre>

With that code set up you can compile your code in Xcode to generate the .bundle in my case Plugin.bundle

Now the Unity Part:
In Unity you have to put your bundle into the Plugins folder if you dont have one create it. (See unity docu about special folder names if you want to know more).

Screen Shot 2016-08-12 at 14.46.22

When the bundle is imported you can set some Properties in the inspector upon clicking on it. You should mark the appropriate Platformsettings (in this case MacOSX x86 and MacOSX x_86_64

Screen Shot 2016-08-12 at 14.46.34

With thats done you need to write the c# wrapper for your native plugin.

Create a c# file, i name it PluginTest.cs

PluginTest.cs

using UnityEngine;
using System.Collections;
using System;
using System.Runtime.InteropServices;

public class TestPlugin : MonoBehaviour
{
    
    [DllImport(Plugin)]
    extern static private void Message(string message);

    public void Msg ()
    {
        Message (Hello World);
    }
        
    void OnGUI()
    {
        if (GUILayout.Button(Write Message))
        {
            Msg ();
        }
    }
}

We need to use the System.Runtime.InteropServices; in order to include the Plugin. Also we need to DllImport it using the [DllImport(“PLUGINNAME”)] statement (in my case the bundle is called Plugin so i write [DllImport(“Plugin”)] and then what Method from the Dll is marked as extern below.
With that done we can call this Method like a normal c# method.

In this case i added an OnGUI Button to test it.

Attach the Script to a Gameobject in your scene.


You’ll notice there is nothing coming up in the Console Log, this is okay! To achieve this we would need a response from the plugin and Debug.Log it ourselves. In this case we can check it by looking at the Editor Log.
Screen Shot 2016-08-12 at 15.02.07
Here’s our native log:
Screen Shot 2016-08-12 at 15.03.00.png
Passed message = Hello World is what our plugin is putting out.

So i hope i could help and now it’s up to you to write whatever awesome native plugin you can imagine.

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s