-
-
Notifications
You must be signed in to change notification settings - Fork 0
Plugin Development Tutorial zh
3cxc edited this page Sep 13, 2026
·
1 revision
本教程将指导您使用 NativePluginKit 为Unknown: Site-0 创建一个最小化插件
dotnet new classlib -n HelloWorldPlugin -f net8.0
cd HelloWorldPlugin编辑 HelloWorldPlugin.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<PublishAot>true</PublishAot>
<NativeLib>Shared</NativeLib>
<IlcExportUnmanagedEntrypoints>true</IlcExportUnmanagedEntrypoints>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\NativePluginKit\NativePluginKit.csproj" />
<ProjectReference Include="..\NativePluginKit.SourceGenerators\NativePluginKit.SourceGenerators.csproj"
OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
<UnmanagedEntryPointsAssembly Include="NativePluginKit" />
</ItemGroup>
</Project>创建 HelloWorldPlugin.cs:
using NativePluginKit.Features.Logger;
using NativePluginKit.Loader.Plugins;
namespace HelloWorldPlugin;
public partial class HelloWorldPlugin : Plugin
{
public override string Name => "HelloWorldPlugin";
public override string Description => "一个示例插件";
public override string Author => "你的名字";
public override Version RequiredApiVersion => new(1, 0, 0);
protected override void OnStart()
{
Log.PrintLog("你好,世界!");
}
public override void OnStop() { }
}注意 — 类必须声明为
partial。源生成器会产出OnInit,OnStop和[ModuleInitializer]引导
Log.PrintLog("普通信息");
Log.PrintWarning("警告信息");
Log.PrintError("错误信息");
Log.Debug("调试信息");NativePluginKit.Features.FMOD.Transition.TransitionToScene(
"res://scenes/menu.tscn", fadeOut: true);using NativePluginKit.Features.Cards;
for (int i = 0; i < Card.GetCardCount(); i++)
{
string name = Card.GetCardNameAt(i);
Log.PrintLog($"{name}({Card.GetCardTypeEnum(name)})消耗 {Card.GetCost(name)}");
}using NativePluginKit.Features.Entities;
using NativePluginKit.Features.Wrappers;
foreach (EntityId id in Entity.GetAllEntityIds())
{
if (!Entity.Contains(id)) continue;
Log.PrintLog($"{Entity.GetDisplayName(id)}:{Entity.GetCurrentHP(id)}/{Entity.GetMaxHP(id)}");
}using NativePluginKit.Events;
using NativePluginKit.Features.Events;
EventBus.On<EntityDamagedEvent>(EventType.EntityDamaged, OnEntityDamaged);
private void OnEntityDamaged(EntityDamagedEvent e)
{
var id = new EntityId(e.EntityId.Low, e.EntityId.High);
Log.PrintLog($"{Entity.GetDisplayName(id)} 受到 {e.HpDamage} 点伤害");
}HostApiTable api = Api;dotnet publish -c Release -r win-x64将 bin/Release/net8.0/win-x64/publish/HelloWorldPlugin.dll 复制到主机的 <GameRoot>/plugins/ 目录:
<GameRoot>/
├── ExampleClient.exe
└── plugins/
└── HelloWorldPlugin.dll
启动客户端,你将看到:
Loading plugin: HelloWorldPlugin v1.0.0.0 by 你的名字
你好,世界!
| 阶段 | 方法 | 说明 |
|---|---|---|
| 加载 | __GeneratedModuleInit |
[ModuleInitializer],在 OnInit 之前注册元数据 |
| 加载 | __GeneratedOnInit |
导出为 OnInit,创建实例并注入 Api
|
| 启动 | OnStart() |
业务初始化 |
| 停止 | OnStop() |
释放资源,宿主随后释放实例 |
-
不要从
OnStart/OnStop抛出异常 —— 异常无法安全穿越 ABI 边界 -
插件保持自包含 —— 只依赖
NativePluginKit和 BCL -
匹配 API 版本 —— 通过
RequiredApiVersion声明 -
使用
Log.PrintLog——Console.WriteLine输出到进程 stdout,客户端控制台可能看不到 -
在
OnStop中释放所有非托管资源 —— 包括通过EventBus.Off<T>取消事件订阅