文章目录
- 前言
- 场景搭建
- 新建子场景
- 最简单的按钮事件
- 手动控制场景
- 手动加载场景
- 添加多个场景对象
- 更快速的获取脚本对象
- 删除多个场景对象
- 脚本命名的问题
- 总结
前言
Godot的场景是C#与Godot最后的中间连接。我们解决了场景的加载,我们基本可以保证C#和godot之间的彻底分离。
场景搭建
新建子场景
我们新建一个最简单的子场景,我们按照规范,应该只在Node 2D的节点上面添加子场景。
场景新建原则:
- 根节点必须是Node 2D节点,因为Node 2D节点是最优的通用节点
- 只在根节点上面添加唯一的脚本
在 Godot 中应用面向对象原则
最简单的按钮事件
public partial class TestSence:Godot.Node2D
{private Button button;private int num = 0;public TestSence() {}public override void _Ready(){button = GetNode<Button>("Button");button.ButtonDown += () =>{button.Text = $"按钮 {num}";num++;};base._Ready();}public override void _Process(double delta){base._Process(delta);}}
手动控制场景
Godot Engine 4.2 简体中文文档 最佳实践 场景组织
手动加载场景
Godot Engine 4.2 简体中文文档 最佳实践 何时使用场景与脚本
主场景的脚本事件
namespace Test2.SenceScripts
{public partial class MainSence : Godot.Node2D{public MainSence() { }public override void _Ready(){//加载脚本var packedScene = ResourceLoader.Load<PackedScene>("res://Sences//Test.tscn").Instantiate();//自动添加在子节点上面AddChild(packedScene);}public override void _Process(double delta){base._Process(delta);}}
}
添加多个场景对象
public override void _Ready()
{//加载脚本var packedScene = ResourceLoader.Load<PackedScene>("res://Sences//Test.tscn").Instantiate();//无法添加多个脚本,因为会出现命名冲突for(var i = 0; i < 10; i++){//自动添加在子节点上面AddChild(packedScene);}}
正确示范
public override void _Ready(){//加载脚本var packedScene = ResourceLoader.Load<PackedScene>("res://Sences//Test.tscn");for (var i = 0; i < 10; i++){//每次都要重新创建var newPackedScene = packedScene.Instantiate();//给每个都赋值不同的名字,保证不会出现冲突newPackedScene.Name = "Test" + i;AddChild(newPackedScene);//反向获取脚本对象TestSence testSence = GetNode<TestSence>(newPackedScene.Name.ToString());//通过修改节点的位置防止重叠testSence.Position = new Vector2(i * 100, 0);//if (i < 5)// RemoveChild(packedScene);}GD.Print("我已经实例化了");base._Ready();}
更快速的获取脚本对象
var newPackedScene = packedScene.Instantiate();
//给每个都赋值不同的名字,保证不会出现冲突
newPackedScene.Name = "Test" + i;
AddChild(newPackedScene);
//反向获取脚本对象
TestSence testSence = GetNode<TestSence>(newPackedScene.Name.ToString());
这个添加之后再获取脚本对象太过于麻烦,我们可以通过泛型来获取,这样就少了一个反向获取的操作
var newPackedScene = packedScene.Instantiate<TestSence>();
//给每个都赋值不同的名字,保证不会出现冲突
newPackedScene.Name = "Test" + i;
AddChild(newPackedScene);
删除多个场景对象
for (var i = 0; i < 10; i++){//每次都要重新创建var newPackedScene = packedScene.Instantiate();//给每个都赋值不同的名字,保证不会出现冲突newPackedScene.Name = "Test" + i;AddChild(newPackedScene);//反向获取脚本对象TestSence testSence = GetNode<TestSence>(newPackedScene.Name.ToString());//通过修改节点的位置防止重叠testSence.Position = new Vector2(i * 100, 0);//将前五个移出if (i < 5)RemoveChild(newPackedScene);}GD.Print("我已经实例化了");base._Ready();}
脚本命名的问题
总结
官方文档写的特别好,建议大家按照官方文档的最佳实践编写Godot代码。