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 提供了一组符号定义。
备注
如果是Godot 3.2之前创建的项目, 你需要修改或重新生成你的 csproj 文件来使用这个功能(可与一个3.2+新项目中的 <DefineConstants>
相对比).
示例
例如, 你可以根据平台更改代码:
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
}
或者你可以检测代码所在的引擎, 这对于制作跨引擎库很有用:
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
}
Or you can write scripts that target multiple Godot versions and take advantage of features that are only available on some of those versions:
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_64
或GODOT_32
。根据操作系统,会定义
GODOT_LINUXBSD
、GODOT_WINDOWS
、GODOT_OSX
、GODOT_ANDROID
、GODOT_IOS
、GODOT_HTML5
或GODOT_SERVER
其中之一。将来可能会更改这些名称。这些名称是根据 OS 单例的get_name()
方法创建的,但该方法返回的操作系统并非都能够使用 .NET 运行 Godot 。GODOTX
,GODOTX_Y
,GODOTX_Y_Z
,GODOTx_OR_GREATER
,GODOTX_y_OR_GREATER
, andGODOTX_Y_z_OR_GREATER
, whereX
,Y
, andZ
are replaced by the current major, minor and patch version of Godot.x
,y
, andz
are replaced by all values from 0 to the current version number for that component.备注
这些定义最早是在 Godot 4.0.4 和 4.1 中添加的。无论当前的 Godot 版本是什么,之前版本的定义都不存在。
例如: Godot 4.0.5 定义了
GODOT4
、GODOT4_OR_GREATER
、GODOT4_0
、GODOT4_0_OR_GREATER
、GODOT4_0_5
、GODOT4_0_4_OR_GREATER
和GODOT4_0_5_OR_GREATER
。 Godot 4.3.2 定义了GODOT4
、GODOT4_OR_GREATER
、GODOT4_3
、GODOT4_0_OR_GREATER
、GODOT4_1_OR_GREATER
、GODOT4_2_OR_GREATER
、GODOT4_3_OR_GREATER
、GODOT4_3_2
、GODOT4_3_0_OR_GREATER
、GODOT4_3_1_OR_GREATER
和GODOT4_3_2_OR_GREATER
。
在 导出 时, 根据导出功能, 还可能定义以下内容:
GODOT_PC
,GODOT_MOBILE
或GODOT_WEB
中的一种, 取决于平台类型.One of
GODOT_WINDOWS
,GODOT_LINUXBSD
,GODOT_MACOS
,GODOT_ANDROID
,GODOT_IOS
, orGODOT_WEB
depending on the platform.
如果想要参考一个示例项目, 可以参考该OS测试demo:https://github.com/godotengine/godot-demo-projects/tree/master/misc/os_test