You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Godot 4中Dialogue Manager 3的DialogueEnded事件订阅失败求助

Dialogue Manager 3 (Godot 4) DialogueEnded Event Not Triggering

我正在使用Godot 4的Dialogue Manager 3开发对话系统,编写了checkDialogueFinished函数用于检测对话事件是否结束,但在checkInteract函数中订阅DialogueEnded事件始终未生效。相关代码如下:

using Godot;
using System;
using DialogueManagerRuntime;

public partial class ObjectInteract : Node {
    private Resource dialogue = GD.Load<Resource>("res://Dialogue/Test.dialogue");
    private bool isInDialogue = false;
    
    /*
        函数描述:通过斜率计算物体与玩家之间的距离
        @param ObjectX -> 物体的X坐标
        @param ObjectY -> 物体的Y坐标
        @param PlayerX -> 玩家的X坐标
        @param PlayerY -> 玩家的Y坐标
    */
    public float getDistanceSlope(float ObjectX, float ObjectY, float PlayerX, float PlayerY){
        float dx = ObjectX - PlayerX;
        float dy = ObjectY - PlayerY;
        float distance = dx * dx + dy * dy;
        float trueDistance = (float)Math.Sqrt(distance);

        return distance;
    }
    /*
        函数描述:检查玩家是否足够接近物体以进行交互
        @param slope -> 物体与玩家之间的距离
        @param objectName -> 物体名称
    */
    public void checkInteract(float slope){
        if (slope < 850 && Input.IsActionJustPressed("interact") && !isInDialogue){
            DialogueManager.ShowExampleDialogueBalloon(dialogue);
            isInDialogue = true;

            DialogueManager.DialogueEnded += checkDialogueFinished;
            GD.Print("Event fired!");
        }
    }

    private void checkDialogueFinished(Resource dialogue) {
        GD.Print("Event ended, setting isInDialogue back to false!");
        isInDialogue = false;

        DialogueManager.DialogueEnded -= checkDialogueFinished;
    }
}

可能的问题及解决方案

  • 事件委托签名不匹配
    核对DialogueManager.DialogueEnded的委托定义,确保和checkDialogueFinished的参数完全一致。如果事件包含额外参数(比如对话ID、结束原因等),参数不匹配会直接导致订阅失效。修改checkDialogueFinished的参数列表,完全匹配事件的委托签名即可。

  • 订阅时机错误
    当前代码先调用ShowExampleDialogueBalloon再订阅事件,如果该方法内部在调用时就触发了DialogueEnded(比如对话内容为空),订阅会错过事件。调整顺序,先订阅再启动对话:

    DialogueManager.DialogueEnded += checkDialogueFinished;
    DialogueManager.ShowExampleDialogueBalloon(dialogue);
    isInDialogue = true;
    
  • 静态事件与实例事件混淆
    确认DialogueManager.DialogueEnded是静态事件还是实例事件。如果是实例事件,直接通过静态类访问无法获取到正确的运行实例,自然不会触发事件。改为获取场景中DialogueManager的实例来订阅:

    var dialogueManager = GetNode<DialogueManager>("/root/DialogueManager");
    dialogueManager.DialogueEnded += checkDialogueFinished;
    
  • 示例方法未触发事件
    ShowExampleDialogueBalloon可能是Demo用的简化方法,不会触发完整的DialogueEnded事件流程。查看Dialogue Manager 3的文档,替换为官方推荐的正式对话启动API(比如StartDialogue),确保对话结束时会正确触发事件。

  • 节点生命周期或订阅冲突
    检查ObjectInteract节点是否在对话过程中被销毁,或者是否有其他代码提前取消了DialogueEnded的订阅。另外,确保每次订阅后只取消一次,避免多次订阅/取消导致的异常。

内容的提问来源于stack exchange,提问作者c0sx86

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 14:05:22