unity setnativesizenative plugin可以使用mono吗

mono - Loading Resources in a Native Plugin (Unity) - Stack Overflow
Join Stack Overflow to learn, share knowledge, and build your career.
or sign in with
How do I load resources (text files, textures, etc.) from within a native plugin? I'm in the process of attempting to implement a mono invoke of Resources.Load(), but I am unsure as to how to handle the Object that will be returned from this operation (assuming it is successful). Any help would be greatly appreciated :).
The Unity-supported means for your plugin to load resources directly from the native filesystem is to place those resources into a folder named "StreamingAssets" inside your project. When your Unity-based application is installed, the contents of this folder are copied to the native filesystem (except Android, see below). The path to this folder on the native side varies per platform.
In Unity v4.x and later, this path is available as Application.streamingAssetsP
Note that on Android the files you place in StreamingAssets get packaged into a .jar file, though they can be accessed by unzipping the .jar file.
In Unity v3.x, you have to manually construct the path yourself as follows:
All platforms except iOS and Android: Application.dataPath + "/StreamingAssets"
iOS: Application.dataPath + "/Raw"
Android: The path to the .jar is: "jar:file://" + Application.dataPath + "!/assets/"
Here is a snippet I used to handle this:
if (Application.platform == RuntimePlatform.IPhonePlayer) dir = Application.dataPath + "/Raw/";
else if (Application.platform == RuntimePlatform.Android) {
// On Android, we need to unpack the StreamingAssets from the .jar file in which
// they're archived into the native file system.
// Set "filesNeeded" to a list of files you want unpacked.
dir = Application.temporaryCachePath + "/";
foreach (string basename in filesNeeded) {
if (!File.Exists(dir + basename)) {
WWW unpackerWWW = new WWW("jar:file://" + Application.dataPath + "!/assets/" + basename);
while (!unpackerWWW.isDone) { } // This will block in the webplayer.
if (!string.IsNullOrEmpty(unpackerWWW.error)) {
Debug.Log("Error unpacking 'jar:file://" + Application.dataPath + "!/assets/" + basename + "'");
File.WriteAllBytes(dir + basename, unpackerWWW.bytes); // 64MB limit on File.WriteAllBytes.
else dir = Application.dataPath + "/StreamingAssets/";
Note that on Android, Android 2.2 and earlier cannot directly unpack large .jars (typically larger than 1 MB) so you would need to handle that as an edge case.
References: , plus
I want to offer an answer to this question in relation to the native side of things.
It's quite simple really- you can get to the StreamingAssets path on the native side like so:
NSString* bundlePath = [[NSBundle mainBundle] bundlePath];
NSString* streamingAssetsPath = [NSString stringWithFormat:@"%@/Data/Raw/", bundlePath];
I don't like using streaming assets on Android, It's a messy solution copying all the files about IMO. A much cleaner way of doing it is by creating the directory structures defined in the
in your plugin directory.
So for example an image could be located like this in your Unity project:
Assets/Plugins/Android/res/drawable/image.png
Then, on the Android side you can access the resource ID of it like this:
Context context = (Context)UnityPlayer.currentA
String packageName = context.getPackageName();
int imageResourceId = context.getResources().getIdentifier("image", "drawable", packageName);
Up to you how to handle everything else from there! Hope this helps :)
Your Answer
Sign up or
Sign up using Google
Sign up using Facebook
Post as a guest
Post as a guest
By posting your answer, you agree to the
Not the answer you're looking for?
Browse other questions tagged
Stack Overflow works best with JavaScript enabled4389人阅读
unity3D插件(Plugins)(14)
Unity中的插件机制In addition to the basic script interface,
in Unity can receive callbacks when certain events happen. This is mostly used to implement low-level rendering in your plugin and enable it to work with Unity’s multithreaded rendering.
Headers defining interfaces exposed by Unity are provided with the editor.
Interface Registry
A plugin should export UnityPluginLoad and UnityPluginUnload functions to handle main Unity events. See IUnityInterface.h for the correct signatures. IUnityInterfaces is provided to the plugin to access further Unity APIs.
#include &IUnityInterface.h&
#include &IUnityGraphics.h&
// Unity plugin load event
extern &C& void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
UnityPluginLoad(IUnityInterfaces* unityInterfaces)
IUnityGraphics* graphics = unityInterfaces-&Get&IUnityGraphics&();
Access to the Graphics Device
A plugin can access generic graphics device functionality by getting the IUnityGraphics interface. In earlier versions of Unity a UnitySetGraphicsDevice function had to be exported in order to receive notification about events on the graphics device. Starting with Unity 5.2 the new IUnityGraphics interface (found in IUnityGraphics.h) provides a way to register a callback.
#include &IUnityInterface.h&
#include &IUnityGraphics.h&
static IUnityInterfaces* s_UnityInterfaces = NULL;
static IUnityGraphics* s_Graphics = NULL;
static UnityGfxRenderer s_RendererType = kUnityGfxRendererN
// Unity plugin load event
extern &C& void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
UnityPluginLoad(IUnityInterfaces* unityInterfaces)
s_UnityInterfaces = unityI
s_Graphics = unityInterfaces-&Get&IUnityGraphics&();
s_Graphics-&RegisterDeviceEventCallback(OnGraphicsDeviceEvent);
// Run OnGraphicsDeviceEvent(initialize) manually on plugin load
// to not miss the event in case the graphics device is already initialized
OnGraphicsDeviceEvent(kUnityGfxDeviceEventInitialize);
// Unity plugin unload event
extern &C& void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
UnityPluginUnload()
s_Graphics-&UnregisterDeviceEventCallback(OnGraphicsDeviceEvent);
static void UNITY_INTERFACE_API
OnGraphicsDeviceEvent(UnityGfxDeviceEventType eventType)
switch (eventType)
case kUnityGfxDeviceEventInitialize:
s_RendererType = s_Graphics-&GetRenderer();
//TODO: user initialization code
case kUnityGfxDeviceEventShutdown:
s_RendererType = kUnityGfxRendererN
//TODO: user shutdown code
case kUnityGfxDeviceEventBeforeReset:
//TODO: user Direct3D 9 code
case kUnityGfxDeviceEventAfterReset:
//TODO: user Direct3D 9 code
Plugin Callbacks on the Rendering Thread
Rendering in Unity can be multithreaded if the platform and number of available CPUs will allow for it. When multithreaded rendering is used, the rendering API commands happen on a thread which is completely separate from the one that runs MonoBehaviour scripts. Consequently, it is not always possible for your plugin to start doing some rendering immediately, because it might interfere with whatever the render thread is doing at the time.
In order to do any rendering from the plugin, you should call
from your script. This will cause the provided native function to be called from the render thread. For example, if you call GL.IssuePluginEvent from the camera’s OnPostRender function, you get a plugin callback immediately after the camera has finished rendering.
Signature for the UnityRenderingEvent callback is provided in IUnityGraphics.h.
Native plugin code example:
// Plugin function to handle a specific rendering event
static void UNITY_INTERFACE_API OnRenderEvent(int eventID)
//TODO: user rendering code
// Freely defined function to pass a callback to plugin-specific scripts
extern &C& UnityRenderingEvent UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
GetRenderEventFunc()
return OnRenderE
Managed plugin code example:
#if UNITY_IPHONE && !UNITY_EDITOR
[DllImport (&__Internal&)]
[DllImport(&RenderingPlugin&)]
private static extern IntPtr GetRenderEventFunc();
// Queue a specific callback to be called on the render thread
GL.IssuePluginEvent(GetRenderEventFunc(), 1);
Such callbacks can now also be added to CommandBuffers via .
Plugin using the OpenGL graphics API
There are two kind of OpenGL objects: Objects shared across OpenGL contexts ( and programs objects) and per-OpenGL context objects ( and sync objects).
Unity uses multiple OpenGL contexts. When initializing and closing the editor and the player, we rely on a master context but we use dedicated contexts for rendering. Hence, you can’t create per-context objects during kUnityGfxDeviceEventInitialize and kUnityGfxDeviceEventShutdown events.
For example, a native plugin can’t create a vertex array object during a kUnityGfxDeviceEventInitialize event and use it in a UnityRenderingEvent callback, because the active context is not the one used during the vertex array object creation.
An example of a low-level rendering plugin is on bitbucket:
(NativeRenderingPlugin folder). It demonstrates two things:
Renders a rotating triangle from C++ code after all regular rendering is done.
Fills a procedural texture from C++ code, using Texture.GetNativeTexturePtr to access it.
The project works with:
Windows (Visual Studio 2015) with Direct3D 9, Direct3D 11, Direct3D 12 and OpenGL.
Mac OS X (Xcode) with Metal and OpenGL.
Universal Windows Platform with Direct3D 11 and Direct3D 12.
Page amended with no
Did you find this page useful? Please give it a rating:
Building Plugins for Desktop Platforms
Low-level native plugin rendering extensionsUnity has extensive support for native Plugins, which are libraries of native code written in C, C++, Objective-C, etc. Plugins allow your game code (written in Javascript or C#) to call functions from these libraries. This feature allows Unity to integrate with middleware libraries or existing C/C++ game code.
In order to use a native plugin you firstly need to write functions in a C-based language to access whatever features you need and compile them into a library. In Unity, you will also need to create a C# script which calls functions in the native library.
The native plugin should provide a simple C interface which the C# script then exposes to other user scripts. It is also possible for Unity to call functions exported by the native plugin when certain low-level rendering events happen (for example, when a graphics device is created), see the
page for details.
A very simple native library with a single function might have source code that looks like this:
float FooPluginFunction () { return 5.0F; }
To access this code from within Unity, you could use code like the following:
using UnityE
using System.Runtime.InteropS
class SomeScript : MonoBehaviour {
#if UNITY_IPHONE
// On iOS plugins are statically linked into
// the executable, so we have to use __Internal as the
// library name.
[DllImport (&__Internal&)]
// Other platforms load plugins dynamically, so pass the name
// of the plugin's dynamic library.
[DllImport (&PluginName&)]
private static extern float FooPluginFunction ();
void Awake () {
// Calls the FooPluginFunction inside the plugin
// And prints 5 to the console
print (FooPluginFunction ());
Note that when using Javascript you will need to use the following syntax, where DLLName is the name of the plugin you have written, or “__Internal” if you are writing statically linked native code:
@DllImport (DLLName)
static private function FooPluginFunction () : float {};
Creating a Native Plugin
In general, plugins are built with native code compilers on the target platform. Since plugin functions use a C-based call interface, you must avoid name mangling issues when using C++ or Objective-C.
Further Information
(this is needed if you want to do rendering in your plugin)
Did you find this page useful? Please give it a rating:
Managed Plugins
Building Plugins for Desktop Platforms在Unity3D中利用了Mono运行时来实现其脚本模块的基础。先给出一个Mono的定义:Mono是一个由Xamarin公司(先前是Novell,最早为Ximian)所主持的自由开放源代码项目。 该项目的目标是创建一系列匹配ECMA标准(Ecma-334和Ecma-335)的.NET工具,包括C#编译器和通用语言架构。与微软的.NET Framework(共通语言运行平台)不同,Mono项目不仅可以运行于Windows系统上,还可以运行于Linux,FreeBSD,Unix,OS X和Solaris,甚至一些游戏平台,例如:Playstation 3,Wii或XBox 360。那么这里很明显可以看出:Mono具有跨平台的能力。Mono跨平台的能力又是怎么实现的呢?来看看Mono的组件:
1、C#编译器:从Mono2.11版本开始,采用的编译器叫mcs,它的作用是将C#编译为CIL(Common Language Infrastructure,通用中间语言,也叫MSIL微软中间语言,这个语言能运行在所有支持CIL的环境中)
2、Mono运行时:运行时想要的是定义一个与具体语言无关的,跨架构系统的运行环境。其中有:即时编译器(Just-in-time,JIT)、提前编译器(Ahead-of-time compiler,AOT)、类加载器、垃圾回收器和线程系统等。C#代码经mcs编译成CIL后的byte code后就是在Mono运行时中经JIT或AOT转译为原生码(Native Code),这个原生码可以在当前机器运行,这就是Mono跨平台的原因。
3、基础类库:Mono平台提供了很多基础类,这些类库与.NET框架兼容。
4、Mono类库:Mono自带的类库。总之,在我们使用Unity3D开发游戏的过程中,C#代码编译的过程为:
第一步:C#代码到CIL的编译(在mcs上发生)。
第二步:CIL到CIL位元码的编译(在mcs上发生)。
第三步:CIL位元码到本地指令的编译(在Mono运行时上发生,有3种转译方式,3种转译方式如下)
a. 即时编译(Just-in-time,JIT):在程序运行的时候把CIL的位元码转译为目标平台的原生码。
b. 提前编译(Ahead-of-time,AOT):在程序运行前就把CIL的位元码转译为目标平台的原生码并且存储,但是并不是全部的CIL的位元码都会提前转译并存储,仍然会有一小部分的CIL位元码会在程序运行的过程中转译。简单来说就是AOT和JIT都有。
c. 完全静态编译(Full-ahead-of-time,Full-AOT):这种模式是完全的AOT,不允许在程序运行的过程中使用JIT编译。程序在运行之前所有的代码必须都已经被编译成了目标平台的原生码。在ios平台的Unity3D开发必须用到这种模式。0添加评论分享收藏}

我要回帖

更多关于 unity native plugin 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信