Godot C# 脚本开发
FreeGuideOnline
最新
2026-07-13
csharp using Godot; using System;
public partial class MyNode : Node2D { public override void _Ready() { GD.Print("Hello from C#!"); } }
点击运行当前场景,控制台将输出 `Hello from C#!`,表明脚本工作正常。
### 基本代码结构解析
- `using Godot;` 引入 Godot 核心命名空间,所有 Godot 类型都在此。
- `partial` 关键字表明该类会与 Godot 引擎自动生成的代理类合并,不要删除。
- `_Ready()` 是 Godot 生命周期方法,在节点进入场景树并准备就绪时调用。
- `GD.Print()` 对应 GDScript 的 `print()`,输出调试信息到控制台。
## C# 脚本的核心概念
### 节点路径与访问
在 C# 中操作节点,需要获取节点引用。最常见的方式是在场景里通过 `GetNode<T>()` 方法按路径查找。
```csharp
// 获取子节点 "Sprite2D"
var sprite = GetNode<Sprite2D>("Sprite2D");
// 获取唯一命名的节点(使用 % 前缀,类似场景唯一名称)
var player = GetNode<CharacterBody2D>("%Player");
注意:使用 % 前缀必须在 Godot 编辑器中右键节点 -> 设为场景唯一名称。
信号(Signal)的连接
Godot 信号机制在 C# 中通过 [Signal] 特性和委托事件实现。可以从编辑器连接,也可以用代码手动连接。
编辑器连接:在节点面板的“信号”选项卡,双击信号并选择目标节点与方法,Godot 会自动生成方法桩。
代码连接:
public override void _Ready()
{
Button button = GetNode<Button>("Button");
button.Pressed += OnButtonPressed;
}
private void OnButtonPressed()
{
GD.Print("按钮被按下");
}
发射自定义信号:
[Signal]
public delegate void HealthDepletedEventHandler();
public void TakeDamage(int amount)
{
// ... 处理伤害逻辑
if (health <= 0)
EmitSignal(SignalName.HealthDepleted);
}
SignalName.HealthDepleted 是由 [Signal] 特性自动生成的常量,避免字符串硬编码。
引用类型与资源
Godot 的资源在 C# 中使用相同类名。例如加载一个 PackedScene 并实例化:
PackedScene bulletScene = GD.Load<PackedScene>("res://bullet.tscn");
Node2D bullet = bulletScene.Instantiate<Node2D>();
AddChild(bullet);
推荐在类顶部用 Resource 特性(或直接导出属性)方便在编辑器中拖拽赋值:
[Export]
public PackedScene BulletScene { get; set; }
输入处理
在 _Process 或 _PhysicsProcess 中检测输入。C# 使用 Input 单例,方法名称与 GDScript 略有不同,遵循 PascalCase 命名。
public override void _PhysicsProcess(double delta)
{
Vector2 velocity = Vector2.Zero;
if (Input.IsActionPressed("ui_right"))
velocity.X += 1;
if (Input.IsActionPressed("ui_left"))
velocity.X -= 1;
if (Input.IsActionPressed("ui_down"))
velocity.Y += 1;
if (Input.IsActionPressed("ui_up"))
velocity.Y -= 1;
// 归一化后移动
velocity = velocity.Normalized() * speed;
// 假设我们有一个 CharacterBody2D 节点
// 通常使用 _PhysicsProcess 来调用 MoveAndSlide()
}
注意:_Process 接收 double delta,用于逐帧更新;_PhysicsProcess 接收固定的物理步骤 double delta。
常用 API 快速参考
数学与坐标
Vector2,Vector3代表二维和三维向量,运算与 GDScript 一致。- 坐标转换:
Position,GlobalPosition,Transform等属性直接访问。 - 实用函数:
Mathf.DegToRad(45),Mathf.Sin(angle)等来自Godot.Mathf。
延时与定时器
// 创建一次性计时器(使用场景树定时器最安全)
Timer timer = new Timer();
timer.WaitTime = 2.0;
timer.OneShot = true;
timer.Timeout += () => GD.Print("2秒到");
AddChild(timer);
timer.Start();
// 简单等待几帧
await ToSignal(GetTree().CreateTimer(1.0), SceneTreeTimer.SignalName.Timeout);
GD.Print("等待1秒后执行");
ToSignal 返回 SignalAwaiter,必须在异步方法(async)中使用,并且不能在 _Ready 中直接 await 而不声明 async。
场景切换
PackedScene nextScene = GD.Load<PackedScene>("res://Level2.tscn");
GetTree().ChangeSceneToPacked(nextScene);
获取当前场景树根节点
Node root = GetTree().Root;
Node currentScene = GetTree().CurrentScene;