原生插件一个在 Unity 外部创建的特定于平台的原生代码库,用于在 Unity 中使用。允许您访问诸如操作系统调用和第三方代码库之类的功能,否则这些功能将无法在 Unity 中使用。 更多信息
参见 词汇表 在 Unity 中可以接收特定事件发生时的回调。您可以使用此功能在您的 插件在 Unity 外部创建的一组代码,用于在 Unity 中创建功能。您可以在 Unity 中使用两种类型的插件:托管插件(使用 Visual Studio 等工具创建的托管 .NET 程序集)和原生插件(特定于平台的原生代码库)。 更多信息
参见 词汇表 中实现低级渲染,以便它可以与 Unity 的多线程渲染配合使用。
为了处理主要的 Unity 事件,插件必须导出 UnityPluginLoad
和 UnityPluginUnload
函数。IUnityInterfaces 使插件能够访问这些函数,您可以在插件 API 中的 IUnityInterface.h
中找到它们。
#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>();
}
使用 IUnityGraphics
接口(可以在 IUnityGraphics.h
中找到)来为插件提供对通用图形设备功能的访问。此脚本演示了如何使用 IUnityGraphics
接口注册回调。
#include "IUnityInterface.h"
#include "IUnityGraphics.h"
static IUnityInterfaces* s_UnityInterfaces = NULL;
static IUnityGraphics* s_Graphics = NULL;
static UnityGfxRenderer s_RendererType = kUnityGfxRendererNull;
// Unity plugin load event
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
UnityPluginLoad(IUnityInterfaces* unityInterfaces)
{
s_UnityInterfaces = unityInterfaces;
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 on graphics device initialization.
For example, D3D11 resource creation.
break;
}
case kUnityGfxDeviceEventShutdown:
{
s_RendererType = kUnityGfxRendererNull;
//TODO: user graphics API code to call on graphics device shutdown.
break;
}
case kUnityGfxDeviceEventBeforeReset:
{
//TODO: user graphics API code to call before graphics device reset.
break;
}
case kUnityGfxDeviceEventAfterReset:
{
//TODO: user graphics API code to call after graphics device reset.
break;
}
};
}
如果平台和可用 CPU 的数量允许,您可以使用多线程在 Unity 中进行渲染。
注意:当您使用多线程渲染时,渲染 API 命令发生在与运行 MonoBehaviour 脚本一段代码,允许您创建自己的组件,触发游戏事件,随时间推移修改组件属性并以您喜欢的任何方式响应用户输入。 更多信息
参见 词汇表 的线程完全分离的线程上。主线程和渲染线程之间的通信意味着您的插件可能不会立即开始渲染,具体取决于主线程向渲染线程推送了多少工作量。
要从插件进行渲染,请从您的 托管插件一个托管 .NET 程序集,使用 Visual Studio 等工具创建,用于在 Unity 中使用。 更多信息
参见 词汇表 脚本调用 GL.IssuePluginEvent。这会导致 Unity 的渲染管道从渲染线程调用原生函数,如下面的代码示例中所示。例如,如果您从 相机一个创建场景中特定视点的图像的组件。输出要么绘制到屏幕上,要么作为纹理捕获。 更多信息
参见 词汇表 的 OnPostRender 函数调用 GL.IssuePluginEvent,该函数将在相机完成渲染后立即调用插件回调。
原生插件代码
// Plugin function to handle a specific rendering event
static void UNITY_INTERFACE_API OnRenderEvent(int eventID)
{
// 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 OnRenderEvent;
}
托管插件代码
#if UNITY_IPHONE && !UNITY_EDITOR
[DllImport ("__Internal")]
#else
[DllImport("RenderingPlugin")]
#endif
private static extern IntPtr GetRenderEventFunc();
// Queue a specific callback to be called on the render thread
GL.IssuePluginEvent(GetRenderEventFunc(), 1);
UnityRenderingEvent
回调的签名在 原生渲染插件示例中的 IUnityGraphics.h 中提供。
有两种类型的 OpenGL 对象
Unity 使用多个 OpenGL 上下文。在初始化和关闭编辑器和播放器时,Unity 依赖于一个主上下文,但在渲染时它使用专用上下文。也就是说,您不能在 kUnityGfxDeviceEventInitialize
和 kUnityGfxDeviceEventShutdown
事件期间创建每个上下文的对象。