Search code examples
cubuntuunity-game-enginepluginsunityscript

Plugin works in Linux Unity Editor but not in standalone Linux build


I have a very simple plugin from the code from this example (https://docs.unity3d.com/Manual/NativePlugins.html). I'm updating a UI Text Field with the value from the plugin. This works as expected in the Editor but does not work when I build out a standalone application. I'm running Ubuntu 15.10.

How the library is being built:

gcc -shared PluginName.c -o PluginName.so

Here's what I've tried so far:

  • Something with the LD_LIBRARY_PATH?
    • Added the directory that the .so is in to the LD_LIBRARY_PATH
  • Is there a problem with how Unity is building the app?
    • Tried a different version (5.3.6)
  • Is there a problem with the OS running on a VM?
    • Tried from Ubuntu 15.10 running on another PC
  • Maybe the plugin needs 'lib' prefix?
    • Added 'lib' prefix.
  • Is there a problem with the import settings?
    • Checked import settings, checked x86_64 in Platform Settings
  • Does the library need to be in a different directory?
    • Put in Plugins
    • Put in Plugins/x86_64
    • Put in same directory as executable

It seem there is very little information out there about building Unity plugins for Linux as well. An end-to-end example would be useful. Any help with this problem would be greatly appreciated.


Solution

  • As anticipated this ended up being a bit obscure to solve. I found someone who had run into the same problem and they were able to help me out. There is something strange going on with the way that Unity loads libraries on Linux, here is the solution.

    • 'lib' must be the prefix of the library. e.g. libSimplePlugin.so
    • Import options in Unity should be set correctly
      • Under "Select platforms for plugin" check "Editor" and "Standalone"
      • In "Platform settings" in the Unity tab select CPU: x86_64, OS: Linux
      • In "PC, Mac & Linux Standalone settings" tab check x86_64
      • Note: My library is only 64-bit, settings may vary depending on your library build
      • Note: You can get away without some of these but it is better to err on the safe side and have your import settings correct
    • Put your externs in their own static C# class and have a conditional for dealing with Unity library nameing

      using System;
      using System.Runtime.InteropServices;
      
      public static class Native
      {   
          // The name of the external library containing the native functions
          #if UNITY_EDITOR
          private const string LIBRARY_NAME = "libSimplePlugin";
          #else
          private const string LIBRARY_NAME = "SimplePlugin";
          #endif
      
          [DllImport(LIBRARY_NAME)] public static extern float FooPluginFunction ();
      } 
      
    • Call your function

      Native.FooPluginFunction ();
      
    • This was verified to work in Unity 5.3.6