关于 godot-csharp
godot-csharp 是使用 C# 和 .NET 8 编写 Godot 4.7 游戏代码的技能,介绍节点脚本、生命周期、导出属性、信号、场景实例化及与 GDScript 的交互。
主要功能
- 01C# 节点脚本与生命周期方法
- 02通过 [Export] 暴露检查器字段
- 03将信号用作 C# 事件
- 04使用 PackedScene 实例化场景
- 05调用和访问 GDScript 节点
适用场景
- 01用 C# 编写 Godot 游戏逻辑
- 02在检查器中公开可调参数
- 03将 C# 代码连接到信号
- 04与 GDScript 脚本互操作
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ gamedev-skills/ awesome-gamedev-agent-skills --skill godot-csharp安装后在 Claude Code 中输入/godot-csharp确认已加载。
附带文件references/csharp-setup-and-interop.md
详细介绍
Godot C# / .NET(4.x)
使用 C# 编写 Godot 游戏代码:节点子类、引擎生命周期、导出、作为事件的信号,以及 GDScript 互操作。目标版本为 Godot 4.7(.NET / C#) 和 .NET 8。
适用场景
- 使用 C#(
.cs+.csproj)编写 Godot 游戏脚本、将 GDScript 习惯写法转换为 C#、公开[Export]字段,或连接[Signal]委托并使用 GetNode 时使用。
不适用场景: GDScript 专属语法 → godot-gdscript;与语言无关的引擎概念(场景、物理、动画)→ 相应的 godot-* 技能。你需要安装 Godot .NET 构建版本和 .NET SDK;标准构建版本无法运行 C#。
核心工作流
- 使用 Godot .NET 编辑器构建版本并安装匹配的 .NET 8 SDK。创建第一个 C# 脚本时会生成
.csproj/.sln。使用编辑器或dotnet build进行构建。 - 每个节点脚本都是扩展 Godot 类型的
partial类(源生成器依赖partial)。文件名应与节点脚本类名一致。 - 使用 PascalCase 重写生命周期方法,并将 delta 参数设为
double:_Ready()、_Process(double delta)、_PhysicsProcess(double delta)。 - 使用
[Export]公开可调参数;它们会像 GDScript 的@export一样显示在检查器中。 - 将信号声明为
[Signal]委托,并命名为XxxEventHandler;使用EmitSignal(SignalName.Xxx, ...)发出信号,并通过生成的 C#event订阅。 - 使用
GetNode<T>("Path")(或%Unique)获取节点,并在需要时使用Call/Get/Set调用 GDScript。
模式
1. 节点脚本:生命周期、[Export]、GetNode
using Godot;
public partial class Player : CharacterBody2D
{
[Export] public float Speed = 200.0f; // editable in the Inspector
[Export] public float JumpVelocity = -400.0f;
private const float Gravity = 1200.0f;
private AnimatedSprite2D _sprite;
public override void _Ready()
{
_sprite = GetNode<AnimatedSprite2D>("AnimatedSprite2D");
}
public override void _PhysicsProcess(double delta)
{
Vector2 v = Velocity; // Velocity is a property here
if (!IsOnFloor())
v.Y += Gravity * (float)delta; // delta is double; cast for float math
if (Input.IsActionJustPressed("jump") && IsOnFloor())
v.Y = JumpVelocity;
float dir = Input.GetAxis("move_left", "move_right");
v.X = dir != 0 ? dir * Speed : Mathf.MoveToward(v.X, 0, Speed);
Velocity = v;
MoveAndSlide(); // no args, like GDScript 4.x
}
}
2. 将信号用作 C# 事件
using Godot;
public partial class Health : Node
{
// Delegate name MUST end with "EventHandler"; generator creates the event + SignalName.
[Signal] public delegate void HealthChangedEventHandler(int current, int max);
private int _hp = 100;
public void TakeDamage(int amount)
{
_hp = Mathf.Max(_hp - amount, 0);
EmitSignal(SignalName.HealthChanged, _hp, 100); // type-safe signal name
}
public override void _Ready()
{
HealthChanged += OnHealthChanged; // subscribe like a normal C# event
}
private void OnHealthChanged(int current, int max) => GD.Print($"HP {current}/{max}");
}
3. 在 C# 中实例化场景
public partial class Spawner : Node2D
{
// Load once; PackedScene is the C# equivalent of preload's result.
private readonly PackedScene _bullet = GD.Load<PackedScene>("res://bullet.tscn");
public void Shoot(Vector2 at)
{
var b = _bullet.Instantiate<Node2D>(); // typed instantiate
b.GlobalPosition = at;
AddChild(b);
}
}
4. 与 GDScript 节点互操作
public override void _Ready()
{
Node gd = GetNode("GDScriptNode");
// Call a GDScript method and read/write its properties dynamically.
gd.Call("take_damage", 10);
int score = (int)gd.Get("score");
gd.Set("score", score + 5);
// Connect to a GDScript signal by name:
gd.Connect("died", Callable.From(OnDied));
}
private void OnDied() => GD.Print("entity died");
易踩坑
- 忘记
partial。 没有partial,Godot 源生成器就无法扩展该类,[Export]/[Signal]会出错,且构建错误信息难以理解。 - 方法大小写或签名错误。 C# 重写方法必须是
_Ready、_Process(double)、_PhysicsProcess(double),采用 PascalCase,delta 类型为double(GDScript 使用 snake_case 和float)。名称不匹配时,方法不会被调用。 [Signal]委托命名。 名称必须以EventHandler结尾;引擎会使用去掉该后缀后的名称公开信号,并生成SignalName.X和一个 C#event。GD.Print与Console.WriteLine。 使用GD.Print/GD.PrintErr将输出写入 Godot 输出面板;Console输出可能不会显示。- 值类型结构体。
Vector2、Color、Transform2D都是结构体——应修改局部副本(var v = Velocity; v.X = ...; Velocity = v;);直接编辑Velocity.X无法编译或持久生效。 - 需要 .NET 构建版本和 SDK。 非 .NET 编辑器无法运行 C#;.NET SDK 缺失或版本不匹配会导致构建失败。Godot 4.7 的目标为 .NET 8;请查看当前平台的导出说明,因为 Android 和其他 AOT 目标可能需要更新的 SDK 工具。
QueueFree()与Free()——规则与 GDScript 相同;优先使用QueueFree()。释放对象后继续使用会抛出ObjectDisposedException。- .NET 在某些平台上的导出方式有所不同(例如 Web/移动平台可能需要额外步骤);请查看目标平台的 .NET 导出说明。
参考资料
- 关于导出属性的不同形式(
[ExportGroup]、范围、类型化数组)、使用await ToSignal(...)的异步操作、Godot.Collections与 System 集合、C# 中的自定义资源,以及项目/构建设置,请阅读references/csharp-setup-and-interop.md。
相关技能
godot-gdscript— 这些模式对应的 GDScript 写法。godot-signals-groups— 信号/事件架构(与语言无关)。godot-resources— 数据资源;C# 的[Export]+Resource模式。unity-csharp-scripting— Unity 中的 C#,适用于从 Unity 转来的开发者。
评论
支持 Markdown