Godot 4中Dialogue Manager 3的DialogueEnded事件订阅失败求助
我正在使用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

