• Godot信号教程(使用C#语言)| 创建自定义信号 | 发出自定义信号 | 使用代码监听信号


    信号是什么

    Godot游戏引擎中,信号是一种用于对象之间通信的重要机制。它允许一个对象发出信号,而其他对象可以连接到这个信号并执行相应的操作。这样可以轻松实现解耦和灵活的对象通信。

    连接信号

    使用编辑器连接信号

    在Godot编辑器中,可以通过节点面板来连接信号,具体步骤如下。
    在编辑器中选择发送信号的节点。在节点属性面板中,找到发送信号的信号名称,点击右下角的“连接…”按钮。
    在这里插入图片描述
    在连接对话框中选择要接收信号的节点和设定接收方法的方法名。编辑器会自动生成回调方法的命名,一般为"_on_节点名_信号名"。如果使用C#,编辑器不会自动生成该方法,需要手动编写回调方法。完成后点击“连接”按钮完成信号连接,如下图所示。
    这种方法是在编辑器中完成信号连接,并且可以通过可视化界面直观地完成。
    在这里插入图片描述
    注意,你在程序中的接收方法,方法名要与编辑器中设置的方法名完全一致,即上图中画红色方框的区域。

    使用代码连接信号

    在对象脚本中,我们可以使用代码连接到一个信号并实现相应的操作。

    public override void _Ready()
    {
    	// 连接到信号
        var timer= GetNode<Timer>("Timer");
        timer.Timeout += OnTimerTimeout;
    }
    private void OnTimerTimeout()
    {
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    当Timer对象发出Timeout信号时,该脚本挂载的对象会接收到信号并调用OnTimerTimeout()方法来执行相关操作。
    这种方法通过代码进行信号连接,可以更加灵活地处理信号并进行相应的逻辑操作。

    Lambda

    连接信号时,我们还可以使用Lambda表达式来处理信号,使代码更加简洁和易读。下面我们就用一个具体的例子来学习一下。
    首先创建一个Timer节点。并将其Autostart启动。
    在这里插入图片描述

    然后我们编写如下脚本:

    using Godot;
    
    public partial class LearnCSDN : Node2D
    {
    	private Timer timer;
    	// Called when the node enters the scene tree for the first time.
    	public override void _Ready()
    	{
    		timer = GetNode<Timer>("Timer");
            timer.Timeout+=() =>
            {
    			GD.Print("Timeout");
                // 当计时器发出 "timeout" 信号时,会执行这个Lambda表达式
                // 在这里编写处理代码
            };
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在上面的代码中,我们在_Ready方法获取了场景中名为"Timer"的子节点,并将其赋值给timer成员变量。

    然后,我们使用+=操作符与Lambda表达式将计时器的Timeout事件与一个匿名方法绑定在一起。在这个匿名方法中,我们使用GD.Print打印了"Timeout"信息,表示计时器超时时会执行这段代码。
    现在运行场景,会发现每过一秒我们的输出窗口都会有Timeout的消息传出,如下图所示。
    在这里插入图片描述

    自定义信号

    声明信号

    我们可以自定义信号,而不是使用Godot内置的信号,使用自定义的信号要在脚本的类中编写,可以在类的成员变量区域使用signal特性来声明信号。在声明信号时,需要注意信号命名的要求,结尾需要以EventHandler为后缀。代码如下所示。

    using Godot;
    
    public partial class LearnCSDN : Node2D
    {
    	// 声明信号
    	[Signal]
    	public delegate void HealthDepletedEventHandler();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    通过上述代码,我们声明了一个名为"HealthDepleted"的信号。

    注意,信号名的末尾必须以"EventHandler"结尾。这是一种命名约定,有助于标识信号与其他方法的区别。

    在声明完信号后,我们需要在Godot编辑器中对脚本进行编译(Build),以便编辑器的节点选项卡中能够显示该信号。编译之后,我们可以像连接其他信号一样,将该信号连接到其他节点或方法。
    在这里插入图片描述
    如图所示,在Build之后,节点中出现了我们刚刚声明的信号。
    在这里插入图片描述
    自定义信号还可以包含参数,以在发出信号时传递相关信息。

    发射信号

    在某个需要触发信号的地方,通过调用EmitSignal方法来发出信号,并指定要发出的信号名称和相关参数。

    public void BeHit()
    {
        // 发出信号
        EmitSignal(nameof(Hit));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    带参数的信号

    除了简单的无参数信号,信号还可以携带参数来传递更多信息。在信号的声明中,可以定义参数的类型和名称。

    using Godot;
    using System;
    
    public partial class SignalTest : Node2D
    {
    	// 声明一个带有参数的信号
        [Signal]
        public delegate void MySignalEventHandler(int value, string message);
    
        public void SayHello()
        {
            // 发出带有参数的信号
            EmitSignal(nameof(MySignal), 42, "Hello, World!");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    当发送信号时,可以传递相应的参数。连接到信号的其他对象可以接收到这些参数。

    其他文章

    Godot配置C#语言编写脚本(使用VSCode作为外部编辑器)
    C#的属性讲解

  • 相关阅读:
    不得不说,还是这款开源工作流表单设计器较合心意!
    【译】Based:简单线性注意力语言模型平衡召回-吞吐量权衡
    数论-整除分块
    python笔记--字符串
    circt firtool man page
    学好IB课程需要具备什么能力?
    Vue3.2中,CSS与数据的双向绑定
    系统架构设计专业技能 · 软件工程之UML建模设计
    同城预约上门服务APP小程序开发 打造快捷便利生活
    计算机毕业设计ssm+vue基本微信小程序的校园二手商城系统
  • 原文地址:https://blog.csdn.net/weixin_44499065/article/details/133023475