跳到主要内容

快速开始

更新日期:2025-04-11

前置知识

请确保你已经掌握了以下技能:

  • 虚幻引擎基础
  • C++ 和 U++ 基础
  • .NET 和 C# 基础

开发环境

请确保你已经安装了以下软件:

  • 虚幻引擎 5.5+
  • .NET SDK 9+

此外,你还需要安装一款支持 .NET 9 的 IDE,推荐 Jetbrains Rider 2024.3+ 或 Visual Studio 2022+。

注意

在 Z# 发布正式版之前,大概率不会考虑前向兼容问题,因此这个环境要求可能发生变化。

安装插件

将本仓库克隆到 /<你的工程>/Plugins/.../ZSharp 目录下,暂不支持安装到引擎中。

自动配置

可以跟随引导自动生成 Z# 项目,安装插件后第一次打开编辑器时会询问是否生成示例内容,点击确认即可。

生成内容后会提示编译生成的解决方案并重启编辑器。

脚本的解决方案与 C++ 解决方案不是一个文件,是同目录下名为 <你的工程名>Script.sln 的文件。在解决方案的 Game 目录下,你可以看到生成的示例代码。

信息

MagicCube 是一个由脚本定义的 Actor 子类,它与你在 C++ 中定义的类具有完全相同的行为,因此你可以在场景中实例化一个该类型的对象来开始你的探索。

手动配置

如果你不希望从示例内容开始,也可以手动配置项目。同时,你也可以在这一节了解到自动配置具体做了什么。

创建项目

/<你的工程>/Source 下新建一个 Managed 目录,再在其中新建一个 Game 目录。 在 Game 目录下新建一个 Game.zsproj 文件并将以下内容拷贝到文件中:

{
"ProjectReferences":
[
"ZeroGames.ZSharp.Core",
"ZeroGames.ZSharp.Core.UnrealEngine",
"ZeroGames.ZSharp.Core.Async",
"ZeroGames.ZSharp.UnrealEngine",
"ZeroGames.ZSharp.Emit"
]
}

上述代码文件定义了一个 Z# 项目,Z# 构建工具会根据这个 .zsproj 文件的内容生成对应的 .NET 类库项目(目前只支持 C#)。 .zsprojjson 格式的,上述代码声明该项目引用的其他项目。

加入代码

Game 目录下新建一个 Source 目录,再在其中新建一个 DllEntry.cs 文件并将以下内容拷贝到文件中:

[assembly: DllEntry(typeof(Game.DllEntry))]

namespace Game;

internal class DllEntry
{
[DllMain]
private static void DllMain(string[] args)
{
UE_LOG(LogTemp, $"============= Game Assembly Loaded! {string.Join("", args)} ===========");
}
}

上述代码为 Game 项目定义了入口点。Z# 项目最终会编译成一个托管程序集,当 Z# 加载这个程序集时,会自动查找入口点并调用。 因此,当我们的程序集被加载的时候,你应该可以看到一条日志输出到控制台。

Source 目录下新建一个 MagicCube.cs 文件并将以下内容拷贝到文件中:

namespace Game;

[UClass, Blueprintable]
public partial class MagicCube : Actor
{
protected override void ReceiveBeginPlay_Implementation() => UE_LOG(LogTemp, $"{GetName()} Begin Play!");
protected override void ReceiveEndPlay_Implementation(EEndPlayReason endPlayReason) => UE_LOG(LogTemp, $"{GetName()} End Play!");
}

上述代码在 Game 程序集中定义了一个 Actor 类,它会在 BeginPlayEndPlay 时分别输出一条日志。 你可以直接在场景中创建这个 Actor,也可以创建它的蓝图子类。

信息

需要注意的是,MagicCube 的命名空间必须符合一定规则才能被正确扫描到。如果你想了解更多,请查看 Emit

创建配置

/<你的工程>/Config 目录下新建一个 DefaultZSharp.ini 文件并将以下内容拷贝到文件中:

[/Script/ZSharpRuntime.ZSharpRuntimeSettings]
+EmitVirtualModules=(ModuleName="Game")
+ModuleEmitMetadataSources=(ModuleName="Game")

[MasterALC]
+StartupAssemblies=Game("Hello Z#", "!")

上述代码做了三件事:

  1. 定义了一个名为 Game虚拟模块
  2. 虚拟模块 Game 中存在动态反射信息,Z# 会在模块加载时扫描与其同名的程序集,发现其中定义的虚幻反射类型,并动态注册到虚幻类型系统中。
  3. Game 程序集将在 Z# 启动时自动加载,并且入口方法的参数为 [ "Hello Z#", "!" ]

生成代码

打开编辑器,按顺序执行以下两条控制台命令:

  1. z#.gens:这会在你的工程根目录生成脚本解决方案,并在 /<你的工程>/Intermediate/ZSharp/ProjectFiles 目录下生成项目文件。
  2. z#.geng:这会在 /<你的工程>/Intermediate/ZSharp/Glue 目录下生成用于与虚幻引擎互操作的胶水代码。

编译整个解决方案,重启编辑器,脚本代码就可以运行了。