C# 特征

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

类型转换和强制转换

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

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

GetNode() 返回一个 Node 实例. 在这种情况下, 你必须将其显式转换为所需的派生类型, Sprite. 为此, 在C#中有多种选择. 强制转换和类型检查 InvalidCastException . 如果您非常确定它不会失败, 您可以使用它而不是 as 运算符.

  1. Sprite mySprite = (Sprite)GetNode("MySprite");mySprite.SetFrame(0);

使用AS运算符 Sprite, 则 as 运算符返回 null, 因此它不能与值类型一起使用.

  1. Sprite mySprite = GetNode("MySprite") as Sprite;// Only call SetFrame() if mySprite is not nullmySprite?.SetFrame(0);

使用泛型方法 还提供了泛型方法以使该类型转换透明. GetNode <T>() 在返回之前强制转换节点. 如果节点无法强制转换为所需类型, 它将抛出一个 InvalidCastException.

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

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

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

使用IS运算符进行类型检查 Sprite, 可以使用 is 运算符. 如果节点无法转换为 Sprite, 则 is 运算符返回 false, 否则返回 true.

  1. if (GetNode("MySprite") is Sprite){ // Yup, it's a sprite!}

模式匹配.

C# 信号

Scripting languages 教程中的 处理信号 部分. delegate 上的 [Signal] 特性完成的.

  1. [Signal]delegate void MySignal();[Signal]delegate void MySignalWithArguments(string foo, int bar);

Connect 进行连接. 如果想在编辑器中连接一个信号, 你需要(重新)生成项目组件才能看到这个新的信号. 生成操作可以点击 编辑窗口右上角的 “Build” 按钮手动触发.

  1. public void MyCallback(){ GD.Print("My callback!");}public void MyCallbackWithArguments(string foo, int bar){ GD.Print("My callback with: ", foo, " and ", bar, "!");}public void SomeFunction(){ instance.Connect("MySignal", this, "MyCallback"); instance.Connect(nameof(MySignalWithArguments), this, "MyCallbackWithArguments");}

EmitSignal 方法完成的.

  1. public void SomeFunction(){ EmitSignal(nameof(MySignal)); EmitSignal("MySignalWithArguments", "hello there", 28);}

nameof 关键字引用信号名称(应用于 委托(delegate) 本身). 在建立连接时,可以通过传递一个Godot数组来绑定值。

  1. public int Value { get; private set; } = 0;private void ModifyValue(int modifier){ Value += modifier;}public void SomeFunction(){ var plusButton = (Button)GetNode("PlusButton"); var minusButton = (Button)GetNode("MinusButton"); plusButton.Connect("pressed", this, "ModifyValue", new Godot.Collections.Array { 1 }); minusButton.Connect("pressed", this, "ModifyValue", new Godot.Collections.Array { -1 });}

内置类型 的参数和绑定值, 以及从 Godot.Object 派生的类. 因此, 任何 NodeReference 将自动兼容, 但是自定义数据对象将需要从 Godot.Object 或其子类之中扩展.

  1. public class DataObject : Godot.Object{ public string Field1 { get; set; } public string Field2 { get; set; }}

AddUserSignal 来创建信号, 但要注意它应该在使用所述信号之前执行(使用 ConnectEmitSignal).

  1. public void SomeFunction(){ AddUserSignal("MyOtherSignal"); EmitSignal("MyOtherSignal");}

预处理器符号定义

为了能够根据目标编译环境改变 C# 代码,Godot 提供了一组符号定义。 注解 <DefineConstants> 相对比).

示例

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

  1. public override void _Ready() {#if GODOT_SERVER // Don't try to load meshes or anything, this is a server! LaunchServer();#elif GODOT_32 || GODOT_MOBILE || GODOT_WEB // Use simple objects when running on less powerful systems. SpawnSimpleObjects();#else SpawnComplexObjects();#endif }

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

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

完整的定义列表

  • GODOT
  • GODOT_64GODOT_32
  • GODOT_X11GODOT_WINDOWSGODOT_OSXGODOT_ANDROIDGODOT_IOSGODOT_HTML5GODOT_SERVER 的其中之一,将来可能会更改这些名称。这些名称是根据 OS 单例的 get_name() 方法创建的,但这个函数所能够返回的操作系统并不是都能够运行使用 Mono 的 Godot。 导出 时, 根据导出功能, 还可能定义以下内容:
  • GODOT_PC , GODOT_MOBILEGODOT_WEB 中的一种, 取决于平台类型.
  • GODOT_ARM64_V8AGODOT_ARMEABI_V7A 中的一个,仅在 Android 系统上,取决于架构。
  • GODOT_ARM64GODOT_ARMV7 中的一个, 仅在iOS上, 取决于架构.
  • GODOT_S3TC , GODOT_ETCGODOT_ETC2 中的任一种, 取决于纹理压缩类型.
  • foo -> GODOT_FOO . https://github.com/godotengine/godot-demo-projects/tree/master/misc/os_test