Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

C# 语言特性

本页概述了C#和Godot的常用特征以及它们如何一起使用.

类型转换和强制转换

C#是一种静态类型语言. 因此, 你无法执行以下操作:

var mySprite = GetNode("MySprite");
mySprite.SetFrame(0);

GetNode() 方法返回一个 Node 实例。需要显式将其转换为所需的派生类型 Sprite2D

为此, 在C#中有多种选择.

强制转换和类型检查

如果返回的节点无法转换为 Sprite2D ,则会抛出 InvalidCastException 异常。如果你确定不会发生异常,则可以直接使用而不必用 as 运算符。

Sprite2D mySprite = (Sprite2D)GetNode("MySprite");
mySprite.SetFrame(0);

使用AS运算符

如果节点无法转换为 Sprite2D ,as 运算符将返回 null ,因此不能作为具体的值类型。

Sprite2D mySprite = GetNode("MySprite") as Sprite2D;
// Only call SetFrame() if mySprite is not null
mySprite?.SetFrame(0);

使用泛型方法

还提供了泛型方法以使该类型转换透明.

GetNode <T>() 在返回之前强制转换节点. 如果节点无法强制转换为所需类型, 它将抛出一个 InvalidCastException.

Sprite2D mySprite = GetNode<Sprite2D>("MySprite");
mySprite.SetFrame(0);

GetNodeOrNull <T>() 使用 as 运算符, 如果节点无法强制转换为所需类型, 则返回 null.

Sprite2D mySprite = GetNodeOrNull<Sprite2D>("MySprite");
// Only call SetFrame() if mySprite is not null
mySprite?.SetFrame(0);

使用IS运算符进行类型检查

可以使用 is 运算符,检查节点是否可以转换为Sprite2D 。如果节点无法转换为 Sprite2D ,is 运算符将返回 false ,否则返回 true。请注意,当 is 运算符针对 null 使用时,结果始终为 false

if (GetNode("MySprite") is Sprite2D)
{
    // Yup, it's a Sprite2D!
}

if (null is Sprite2D)
{
    // This block can never happen.
}

如果 is 运算符返回 true ,你可以声明一个新变量来按条件存储转换的结果。

if (GetNode("MySprite") is Sprite2D mySprite)
{
    // The mySprite variable only exists inside this block, and it's never null.
    mySprite.SetFrame(0);
}

对于更高级的类型检查, 你可以查看 模式匹配.

预处理器符号定义

为了能够根据目标编译环境改变 C# 代码,Godot 提供了一组符号定义。

示例

例如, 你可以根据平台更改代码:

    public override void _Ready()
    {
#if (GODOT_32 || GODOT_MOBILE || GODOT_WEB)
        // Use simple objects when running on less powerful systems.
        SpawnSimpleObjects();
#else
        SpawnComplexObjects();
#endif
    }

或者你可以检测代码所在的引擎, 这对于制作跨引擎库很有用:

    public void MyPlatformPrinter()
    {
#if GODOT
        GD.Print("This is Godot.");
#elif UNITY_5_3_OR_NEWER
        print("This is Unity.");
#else
        throw new NotSupportedException("Only Godot and Unity are supported.");
#endif
    }

或者你可以编写针对多个 Godot 版本的脚本,并使用仅在某些版本上可用的功能:

    public void UseCoolFeature()
    {
#if GODOT4_3_OR_GREATER || GODOT4_2_2_OR_GREATER
        // Use CoolFeature, that was added to Godot in 4.3 and cherry-picked into 4.2.2, here.
#else
        // Use a workaround for the absence of CoolFeature here.
#endif
    }

完整的定义列表

  • 所有 Godot 项目都会定义 GODOT

  • 定义 TOOLS ,可在 Debug 环境(编辑器和通过编辑器运行)构建时使用。

  • GodotFloat64 属性设置为 true 时,将定义 GODOT_REAL_T_IS_DOUBLE

  • 根据架构是 64 位还是 32 位,会定义 GODOT_64GODOT_32

  • One of GODOT_LINUXBSD, GODOT_WINDOWS, GODOT_OSX, GODOT_ANDROID, GODOT_IOS, GODOT_WEB depending on the OS. These names may change in the future. These are created from the get_name() method of the OS singleton, but not every possible OS the method returns is an OS that Godot with .NET runs on.

  • GODOTXGODOTX_YGODOTX_Y_ZGODOTx_OR_GREATERGODOTX_y_OR_GREATERGODOTX_Y_z_OR_GREATER ,其中 XYZ 被当前 Godot 的主版本号、次版本号和补丁版本号替换。xyz 被从 0 到该组件当前版本号的所有值替换。

    备注

    这些定义最早是在 Godot 4.0.4 和 4.1 中添加的。无论当前的 Godot 版本是什么,之前版本的定义都不存在。

    例如: Godot 4.0.5 定义了 GODOT4GODOT4_OR_GREATERGODOT4_0GODOT4_0_OR_GREATERGODOT4_0_5GODOT4_0_4_OR_GREATERGODOT4_0_5_OR_GREATER。 Godot 4.3.2 定义了 GODOT4GODOT4_OR_GREATERGODOT4_3GODOT4_0_OR_GREATERGODOT4_1_OR_GREATERGODOT4_2_OR_GREATERGODOT4_3_OR_GREATERGODOT4_3_2GODOT4_3_0_OR_GREATERGODOT4_3_1_OR_GREATERGODOT4_3_2_OR_GREATER

导出 时, 根据导出功能, 还可能定义以下内容:

  • GODOT_PC , GODOT_MOBILEGODOT_WEB 中的一种, 取决于平台类型.

  • 根据平台的不同,可以使用 GODOT_WINDOWSGODOT_LINUXBSDGODOT_MACOSGODOT_ANDROIDGODOT_IOSGODOT_WEB 之一。

如果想要参考一个示例项目, 可以参考该OS测试demo:https://github.com/godotengine/godot-demo-projects/tree/master/misc/os_test