Fork me on GitHub

Getting Started with iOS Development Part8: Plugins

Plugins - Pro/Mobile-Only Feature

Unity has extensive support for C, C++ or Objective-C based Plugins. Plugins allow your game code (written in Javascript, C# or Boo) to call into native code libraries. This allows Unity to integrate with other middleware libraries or legacy game code.

Note: Plugins are a Pro-only feature. For desktop builds, plugins will work in standalones only. They are disabled when building a Web Player for security reasons.

In order to use a plugin you need to do two things:

 
  • Write a plugin in a C based language and compile it.
  • Create a C# script which calls functions in the plugin to do something.

So the plugin provides a simple C interface. The script then invokes the functions exposed by the plugin.

Here is a very simple example:

 

The C File of a Minimal Plugin:

float FooPluginFunction () { return 5.0F; }

 

A C# Script that Uses the Plugin:

using UnityEngine;
using System.Runtime.InteropServices;

class SomeScript : MonoBehaviour {
   // This tells unity to look up the function FooPluginFunction
   // inside the static binary
   [DllImport ("__Internal")]
   private static extern float FooPluginFunction ();

   void Awake () {
      // Calls the native FooPluginFunction
      // And prints 5 to the console
      print (FooPluginFunction ());
   }
} 

Building an Application with Native Plugin for iOS

  1. Define your extern method like: 
    [DllImport ("__Internal")]
    private static extern float FooPluginFunction ();
    
  2. Switch the editor to iOS platform
  3. Add your native implementation to the generated XCode project's "Classes" folder (this folder is not overwritten when project is updated, but don't forget to backup your native code).

If you are using C++ (.cpp) or Objective-C (.mm) to implement the plugin you have to make sure the functions are declared with C linkage to avoid name mangling issues.

 
extern "C" {
  float FooPluginFunction ();
} 
 

Using Your Plugin from C#

iOS native plugins can be called only when deployed on the actual device, so it is recommended to wrap all native code methods with an additional C# code layer. This code could check Application.platform and call native methods only when running on the actual device and return mockup values when running in the Editor. Check the Bonjour browser sample application.

 

Calling C# / JavaScript back from native code

Unity iOS supports limited native->managed callback functionality via UnitySendMessage:

UnitySendMessage("GameObjectName1", "MethodName1", "Message to send");

This function has three parameters : game object name, game object script method to call, message to pass to the called method. Limitations to know:

  1. only script methods that correspond to the following signature can be called from native code: function MethoName(message:string)
  2. calls to UnitySendMessage are asynchronous and have a one frame delay.
 

Automated plugin integration

Unity iOS supports limited automated plugin integration.

  1. All the .a,.m,.mm,.c,.cpp located in Assets/Plugins/iOS will be automatically merged into produced Xcode project.
  2. Merging is done by symlinking files from Assets/Plugins/iOS to the final destination and this might affect some workflows.
  3. .h files are not included into Xcode project tree, but they appear on final destination file system, thus allowing compilation of .m/.mm/.c/.cpp.

Note: subfolders are not supported.

 

iOS Tips

  1. Managed -> unmanaged calls are quite expensive on iOS. Try to avoid calling multiple native methods per frame.
  2. As mentioned above wrap your native methods with an additional C# layer that would call actual code on the device and return mockup values in the Editor.
  3. String values returned from a native method should be UTF-8 encoded and allocated on the heap. Mono marshaling calls are free for them.
  4. As mentioned above the XCode project's "Classes" folder is a good place to store your native code, because it is not overwritten when the project is updated.
  5. Another good place for storing native code is the Assets folder or one of its subfolders. Just add references from the XCode project to the native code files: right click on the "Classes" subfolder and choose "Add->Existing files...".

Bonjour Browser Sample

A simple example of the use of native code plugin can be found here

This sample demonstrates how objective-C code can be invoked from a Unity iOS application. This application implements a very simple Bonjour client. The application consists of a Unity iOS project (Plugins/Bonjour.cs: C# interface to the native code, BonjourTest.js: JS script that implements application logic) and native code (Assets/Code) that should be added to built XCode project.

More Information

Mono Interop with native libraries.

P-invoke documentation on MSDN.

posted on 2012-02-07 08:33  pengyingh  阅读(2201)  评论(0编辑  收藏  举报

导航