Async Message · 蓝图收发与解绑

通过消息 Id、监听、载荷封装与解包的核心连线,掌握蓝图收发和任务解绑。

本页内容3 节

监听消息

蓝图收发只需围绕 Message Id 和 Payload 接线。下面使用项目已有的 Starry.Damage.Message,载荷类型为 FStarryVerbMessage;图中只展示消息节点之间的关系,标签与业务载荷按下方步骤填写。

监听:保存任务、接收消息与载荷解包文档节点
查看节点文本
Begin Object Class=/Script/BlueprintGraph.K2Node_MakeStruct Name="MakeMessageId"
   StructType="/Script/CoreUObject.ScriptStruct'/Script/AsyncMessageSystem.AsyncMessageId'"
   ShowPinForProperties(0)=(PropertyName="InternalMessageTag",PropertyFriendlyName="InternalMessageTag",bShowPin=True,bCanToggleVisibility=True)
   bMadeAfterOverridePinRemoval=True
   NodePosX=-80
   NodePosY=29
   NodeGuid=985352B2DC8F4A0095D44216175B3AD1
   CustomProperties Pin (PinId=DF86702FC03E4DF6BBD7BFF3046D8C3F,PinName="InternalMessageTag",PinFriendlyName=INVTEXT("Internal Message Tag"),PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.ScriptStruct'/Script/GameplayTags.GameplayTag'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
   CustomProperties Pin (PinId=6FF212F31C3A4D3E87A61A6F3728C04B,PinName="AsyncMessageId",PinFriendlyName=INVTEXT("Async Message Id"),Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.ScriptStruct'/Script/AsyncMessageSystem.AsyncMessageId'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,LinkedTo=(ListenForDamage E930D04231754D74AE03E28F68EE7EB4,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
End Object
Begin Object Class=/Script/BlueprintGraph.K2Node_AsyncAction Name="ListenForDamage"
   ProxyFactoryFunctionName="StartListeningForAsyncMessage"
   ProxyFactoryClass="/Script/CoreUObject.Class'/Script/AsyncMessageSystem.AsyncAction_ListenForAsyncMessage'"
   ProxyClass="/Script/CoreUObject.Class'/Script/AsyncMessageSystem.AsyncAction_ListenForAsyncMessage'"
   NodePosX=290
   NodePosY=0
   NodeGuid=D36A1AF0A0BC4F97906DE3F1CF83ED45
   CustomProperties Pin (PinId=D801EFB425314D9390E5C61489B9DFEF,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
   CustomProperties Pin (PinId=FDCC3810174D4070A74041417AD1FB2C,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,LinkedTo=(SaveDamageTask E1C138265FF544BDA40124C48FFA8650,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
   CustomProperties Pin (PinId=E930D04231754D74AE03E28F68EE7EB4,PinName="MessageId",PinFriendlyName=INVTEXT("Message Id"),PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.ScriptStruct'/Script/AsyncMessageSystem.AsyncMessageId'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,LinkedTo=(MakeMessageId 6FF212F31C3A4D3E87A61A6F3728C04B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
   CustomProperties Pin (PinId=1EA1E1B67CD0461ABFC898A1117D2AEC,PinName="DesiredEndpoint",PinFriendlyName=INVTEXT("Desired Endpoint"),PinType.PinCategory="interface",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.Class'/Script/AsyncMessageSystem.AsyncMessageBindingEndpointInterface'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
   CustomProperties Pin (PinId=F3E62B47CD714F4EA69FE4CD3FAA5981,PinName="AsyncTaskProxy",PinFriendlyName=INVTEXT("Async Message Task"),Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.Class'/Script/AsyncMessageSystem.AsyncAction_ListenForAsyncMessage'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,LinkedTo=(SaveDamageTask 792F688E6E69467F80C6A97D9781B538,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
   CustomProperties Pin (PinId=BEBC6ABECC904872A32DEA8B927699AD,PinName="OnMessageReceived",PinFriendlyName=INVTEXT("On Message Received"),Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,LinkedTo=(ReadDamagePayload CBF77DEA607048E793ED940EB934D562,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
   CustomProperties Pin (PinId=AC98F51220034FFC936E90881B852B1D,PinName="Message",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.ScriptStruct'/Script/AsyncMessageSystem.AsyncMessage'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=True,PinType.bIsConst=True,LinkedTo=(BreakMessage 988A07AD0CFB42FCAFCC087A17D13BC2,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
End Object
Begin Object Class=/Script/BlueprintGraph.K2Node_BreakStruct Name="BreakMessage"
   StructType="/Script/CoreUObject.ScriptStruct'/Script/AsyncMessageSystem.AsyncMessage'"
   ShowPinForProperties(0)=(PropertyName="MessageId",PropertyFriendlyName="MessageId",bShowPin=True,bCanToggleVisibility=True)
   ShowPinForProperties(1)=(PropertyName="MessageSourceId",PropertyFriendlyName="MessageSourceId",bShowPin=True,bCanToggleVisibility=True)
   ShowPinForProperties(2)=(PropertyName="QueueTime",PropertyFriendlyName="QueueTime",bShowPin=True,bCanToggleVisibility=True)
   ShowPinForProperties(3)=(PropertyName="PayloadCopy",PropertyFriendlyName="PayloadCopy",bShowPin=True,bCanToggleVisibility=True)
   bMadeAfterOverridePinRemoval=True
   NodePosX=650
   NodePosY=102
   NodeGuid=62FDA70ACA27485B90600FB4645A10CE
   CustomProperties Pin (PinId=988A07AD0CFB42FCAFCC087A17D13BC2,PinName="AsyncMessage",PinFriendlyName=INVTEXT("Async Message"),PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.ScriptStruct'/Script/AsyncMessageSystem.AsyncMessage'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=True,PinType.bIsConst=True,LinkedTo=(ListenForDamage AC98F51220034FFC936E90881B852B1D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
   CustomProperties Pin (PinId=50B6CC820AAB46A4BFED7FA44B1894B1,PinName="MessageId",PinFriendlyName=INVTEXT("Message Id"),Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.ScriptStruct'/Script/AsyncMessageSystem.AsyncMessageId'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
   CustomProperties Pin (PinId=A2869FE1E34A4059980FB28A2FC9489E,PinName="MessageSourceId",PinFriendlyName=INVTEXT("Message Source Id"),Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.ScriptStruct'/Script/AsyncMessageSystem.AsyncMessageId'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
   CustomProperties Pin (PinId=85C401AC93304699BF91BC39F3C5586D,PinName="QueueTime",PinFriendlyName=INVTEXT("Queue Time"),Direction="EGPD_Output",PinType.PinCategory="real",PinType.PinSubCategory="double",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
   CustomProperties Pin (PinId=205A4015315C40A2B51CBC8C5716312E,PinName="PayloadCopy",PinFriendlyName=INVTEXT("Payload"),Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.ScriptStruct'/Script/CoreUObject.InstancedStruct'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,LinkedTo=(ReadDamagePayload 0B014C24F3E749CEB3FBD98AA8A41898,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
End Object
Begin Object Class=/Script/BlueprintGraph.K2Node_InstancedStruct Name="ReadDamagePayload"
   FunctionReference=(MemberParent="/Script/CoreUObject.Class'/Script/Engine.BlueprintInstancedStructLibrary'",MemberName="GetInstancedStructValue")
   NodePosX=990
   NodePosY=57
   NodeGuid=2F84B53BA8FB410BAC7A7F69626D7C00
   CustomProperties Pin (PinId=CBF77DEA607048E793ED940EB934D562,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,LinkedTo=(ListenForDamage BEBC6ABECC904872A32DEA8B927699AD,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
   CustomProperties Pin (PinId=0B014C24F3E749CEB3FBD98AA8A41898,PinName="InstancedStruct",PinFriendlyName=INVTEXT("Instanced Struct"),PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.ScriptStruct'/Script/CoreUObject.InstancedStruct'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=True,PinType.bIsConst=True,LinkedTo=(BreakMessage 205A4015315C40A2B51CBC8C5716312E,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
   CustomProperties Pin (PinId=CC3213FEABB247668DB5B484B00EF15D,PinName="Valid",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
   CustomProperties Pin (PinId=3123C311586B4E23BEFE2A45F6B0FB21,PinName="NotValid",PinFriendlyName=INVTEXT("Not Valid"),Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
   CustomProperties Pin (PinId=E6561FA7AACF4DFE9277B65C7E26DC72,PinName="Value",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.ScriptStruct'/Script/StarryGame.StarryVerbMessage'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
End Object
Begin Object Class=/Script/BlueprintGraph.K2Node_VariableSet Name="SaveDamageTask"
   VariableReference=(MemberName="DamageMessageTask",bSelfContext=True)
   NodePosX=640
   NodePosY=24
   NodeGuid=A4C8C6ADA06D4D19BCE2F57BDDF5EEBC
   CustomProperties Pin (PinId=E1C138265FF544BDA40124C48FFA8650,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,LinkedTo=(ListenForDamage FDCC3810174D4070A74041417AD1FB2C,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
   CustomProperties Pin (PinId=81E94C22759A41288FEBABCF562B821F,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
   CustomProperties Pin (PinId=792F688E6E69467F80C6A97D9781B538,PinName="DamageMessageTask",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.Class'/Script/AsyncMessageSystem.AsyncAction_ListenForAsyncMessage'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,LinkedTo=(ListenForDamage F3E62B47CD714F4EA69FE4CD3FAA5981,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
End Object
  1. Make Async Message Id 的 Internal Message Tag 选择 Starry.Damage.Message,输出连接 Start Listening for Async Message.Message Id。
  2. 从自己的打开、激活或 BeginPlay 执行线启动监听,Desired Endpoint 保持为空。高级引脚 Tick Group 默认 Post Update Work。
  3. On Message Received 接到 Get Instanced Struct Value 的执行输入;Message 接 Break Async Message。
  4. Break Async Message.Payload 接到 Get Instanced Struct Value.Instanced Struct,将 Value 的类型确定为 Starry Verb Message,例如连接已有的该类型变量或业务处理引脚。
  5. 在 Valid 分支读取 Value;Not Valid 表示载荷类型不符。正式角色界面还应检查 Target 是自己观察的 Avatar,再处理 Magnitude 或更新表现。

普通的 Then 输出只表示监听启动后的继续执行,收到消息后执行的是 On Message Received。需要监听父标签时,可从 Break Async Message.Message Source Id 区分真实来源,再选择正确的载荷类型。

发送消息

发送时把业务结构体封装为 Instanced Struct,并用与监听方一致的消息 Id 入队。下面只展示三个核心节点,业务结构体从调用方传入。

发送:封装载荷并按消息 Id 入队文档节点
查看节点文本
Begin Object Class=/Script/BlueprintGraph.K2Node_InstancedStruct Name="PackPayload"
   FunctionReference=(MemberParent="/Script/CoreUObject.Class'/Script/Engine.BlueprintInstancedStructLibrary'",MemberName="MakeInstancedStruct")
   NodePosX=0
   NodePosY=0
   NodeGuid=4BB17B4D93114B6BB692CF5E967A9E4F
   CustomProperties Pin (PinId=A9A0654A55C341EDB1DE29027FAB1DB4,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
   CustomProperties Pin (PinId=BD7F3462490740818E4FF1758C7927E8,PinName="Value",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.ScriptStruct'/Script/StarryGame.StarryVerbMessage'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=True,PinType.bIsConst=True,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
   CustomProperties Pin (PinId=03ABD95BAB0645BD997C6A4373FD01BB,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,LinkedTo=(QueueDamage 457F050F39924E09BA5A135BB417E3F0,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
   CustomProperties Pin (PinId=848F8BC26EEC477A9A609318940BA7AC,PinName="ReturnValue",PinFriendlyName=INVTEXT("Return Value"),Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.ScriptStruct'/Script/CoreUObject.InstancedStruct'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,LinkedTo=(QueueDamage EC540AEAA1544A688E167B46856AA502,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
End Object
Begin Object Class=/Script/BlueprintGraph.K2Node_MakeStruct Name="MakeMessageId"
   StructType="/Script/CoreUObject.ScriptStruct'/Script/AsyncMessageSystem.AsyncMessageId'"
   ShowPinForProperties(0)=(PropertyName="InternalMessageTag",PropertyFriendlyName="InternalMessageTag",bShowPin=True,bCanToggleVisibility=True)
   bMadeAfterOverridePinRemoval=True
   NodePosX=0
   NodePosY=102
   NodeGuid=0C39A88600EE47FAA2D66636E369D282
   CustomProperties Pin (PinId=535DE018E647427E8A256C81A9A412CE,PinName="InternalMessageTag",PinFriendlyName=INVTEXT("Internal Message Tag"),PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.ScriptStruct'/Script/GameplayTags.GameplayTag'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
   CustomProperties Pin (PinId=E6D0F188044A4EF6B78E776335D6AA6B,PinName="AsyncMessageId",PinFriendlyName=INVTEXT("Async Message Id"),Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.ScriptStruct'/Script/AsyncMessageSystem.AsyncMessageId'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,LinkedTo=(QueueDamage 866AD7D97DB94BA9BC8959464FD34238,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
End Object
Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="QueueDamage"
   FunctionReference=(MemberParent="/Script/CoreUObject.Class'/Script/AsyncMessageSystem.AsyncMessageSystemBlueprintLibrary'",MemberName="QueueAsyncMessageForBroadcast")
   NodePosX=470
   NodePosY=0
   NodeGuid=4EA0F83692E4444380D2FB5C536B6746
   CustomProperties Pin (PinId=457F050F39924E09BA5A135BB417E3F0,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,LinkedTo=(PackPayload 03ABD95BAB0645BD997C6A4373FD01BB,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
   CustomProperties Pin (PinId=86CF11C132344107A7C19FD2572F7199,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
   CustomProperties Pin (PinId=866AD7D97DB94BA9BC8959464FD34238,PinName="MessageId",PinFriendlyName=INVTEXT("Message Id"),PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.ScriptStruct'/Script/AsyncMessageSystem.AsyncMessageId'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=True,PinType.bIsConst=True,LinkedTo=(MakeMessageId E6D0F188044A4EF6B78E776335D6AA6B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
   CustomProperties Pin (PinId=EC540AEAA1544A688E167B46856AA502,PinName="Payload",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.ScriptStruct'/Script/CoreUObject.InstancedStruct'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=True,PinType.bIsConst=True,LinkedTo=(PackPayload 848F8BC26EEC477A9A609318940BA7AC,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
   CustomProperties Pin (PinId=2B96C76173C34A668609BAA375832575,PinName="DesiredEndpoint",PinFriendlyName=INVTEXT("Desired Endpoint"),PinType.PinCategory="interface",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.Class'/Script/AsyncMessageSystem.AsyncMessageBindingEndpointInterface'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
   CustomProperties Pin (PinId=73C109E4FD41444B8DC4C5EE100BB7AA,PinName="ReturnValue",PinFriendlyName=INVTEXT("Success"),Direction="EGPD_Output",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
End Object
  1. 将已有的 Starry Verb Message 结构体接到 Make Instanced Struct.Value。测试时可以构造 Verb = Starry.Damage.Message、Magnitude = 25、Target = 要观察的 Avatar 的结构体。
  2. 从业务入口执行 Make Instanced Struct,再将它的白色执行输出接到 Queue Async Message for Broadcast;这个封装节点有执行引脚。
  3. Make Instanced Struct.Return Value 接 Payload;Make Async Message Id 选择同一个 Starry.Damage.Message,输出接发送节点的 Message Id。
  4. Desired Endpoint 留空,使用当前 World 的默认范围。

Message Id 决定路由,载荷里的 Verb 是业务字段,二者不会自动互相填写。Success 只表示进入了相关接收队列,不表示接收逻辑已执行。监听要先于发送启动,回调会在监听的接收阶段运行。

这里的手动发送只发布通知,不扣血、不应用 Gameplay Effect,也不自动联网。项目正式伤害路径已经发布消息,不再额外重复发送。已有标签与载荷字段见项目消息与排查。

保存任务并停止监听

启动监听后,将 AsyncMessageTask 输出提升为对象引用变量,例如 DamageMessageTask。上图将启动节点的 then 接到 Set 保存变量,不接 On Message Received;保存任务不需要等第一条消息到达。

关闭界面、结束本次功能或 Actor EndPlay 时,按以下顺序清理:

  1. 检查保存的任务引用是否有效。
  2. 以它为 Target 调用 Stop Listening for Async Message。
  3. 清空变量;下次启动时创建新任务,避免重复登记。
解绑:停止保存的监听任务并清空引用文档节点
查看节点文本
Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="GetDamageTask"
   VariableReference=(MemberName="DamageMessageTask",bSelfContext=True)
   NodePosX=0
   NodePosY=53
   NodeGuid=087585EF373F4B45BFBE4D99A78CDA4B
   CustomProperties Pin (PinId=CA6CD8E68FCB4879A24EAD5409C4ED54,PinName="DamageMessageTask",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.Class'/Script/AsyncMessageSystem.AsyncAction_ListenForAsyncMessage'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,LinkedTo=(StopDamageTask 50DCCC9E02874963888C1BB02959CA69,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
End Object
Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="StopDamageTask"
   FunctionReference=(MemberParent="/Script/CoreUObject.Class'/Script/AsyncMessageSystem.AsyncAction_ListenForAsyncMessage'",MemberName="StopListeningForAsyncMessage")
   NodePosX=330
   NodePosY=0
   NodeGuid=7566B7C4D34F4745BF27017B8861A901
   CustomProperties Pin (PinId=CB815866A778412BB569E6A9C3C42D8B,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
   CustomProperties Pin (PinId=50DCCC9E02874963888C1BB02959CA69,PinName="self",PinFriendlyName=INVTEXT("Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.Class'/Script/AsyncMessageSystem.AsyncAction_ListenForAsyncMessage'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,LinkedTo=(GetDamageTask CA6CD8E68FCB4879A24EAD5409C4ED54,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
   CustomProperties Pin (PinId=F72887C6B2A249438D5957CAFFFB9466,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,LinkedTo=(ClearDamageTask 42A0AA81D8F74AE88A769553B8689A2D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
End Object
Begin Object Class=/Script/BlueprintGraph.K2Node_VariableSet Name="ClearDamageTask"
   VariableReference=(MemberName="DamageMessageTask",bSelfContext=True)
   NodePosX=760
   NodePosY=24
   NodeGuid=AE788A9D2B3640E2961A654E1BADACA0
   CustomProperties Pin (PinId=42A0AA81D8F74AE88A769553B8689A2D,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,LinkedTo=(StopDamageTask F72887C6B2A249438D5957CAFFFB9466,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
   CustomProperties Pin (PinId=2B484F9C4BC04468BE059C7127646FD8,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
   CustomProperties Pin (PinId=A855DDB6A1404DC28AD962073D9A1DE2,PinName="DamageMessageTask",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.Class'/Script/AsyncMessageSystem.AsyncAction_ListenForAsyncMessage'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
End Object

图中执行入口接自己的关闭逻辑或 EndPlay;调用前确保任务引用有效。Target 必须是之前保存的监听任务,Set 节点的值留空以清除引用。

蓝图任务注册在 GameInstance 中,不能仅凭 Actor 或 Widget 离开视野就假定任务停止。World 关闭有兜底清理,但不能代替功能退出时主动解绑。

这三组图依据 UE 5.8 真实类型与引脚整理,用于说明核心接线;本轮未创建工程蓝图资产或运行 PIE。实际验证时,先启动监听,再发送已知载荷,确认只进入一次 Valid;停止监听后再次发送,自己的回调应不再执行。

对应原生用法见 C++ 收发与解绑,路由与线程约束见标签、时机与生命周期。

实现入口:引擎插件 AsyncAction_ListenForMessage、AsyncMessageBlueprintLibrary、AsyncMessage,引擎 BlueprintInstancedStructLibrary,项目 Framework/Messages/StarryVerbMessage.h。

Starry手册导览从模块进入子模块与具体功能,查阅功能用途、配置步骤、技术架构和扩展方法。工程分层与系统协作了解 Framework、Gameplay 与通用插件的依赖方向,以及配置装配和运行状态的边界。模块总览与接入从行为系统、执行系统与机会调度了解 AstraAI,再为角色配置第一套组合决策。组合与覆盖正确区分优先级、行为分数与 Stack 顺序,按完整路径组织可撤销的配置。评分与抢占沿着条件、优先级、分数、持续有效性与冷却,解释一个行为为何开始或退出。Logic 与生命周期把动作接入 Start、Cancel、Cleanup,正确处理共享模板、蓝图实例与过期异步回调。BT、StateTree 与 HTN复用控制器上的树组件,正确传入数据、报告整树结果并等待安全退出。Objective 与机会生成把领域事实整理成当前机会,让评分只读数据,让生成器独立管理订阅。命令发布与领取发布一条命令后,经机会评估、Take、执行与 EndUse 完成一次受控使用。行为区域用可挂载的 Zone 组件分配行为层,并把回区机会与实际导航分开。调试与排查从初始化到候选、机会、应用层与后端,沿真实运行路径定位 AI 没有行动的原因。模块总览与使用了解通用调试工具的操作、远程连接与窗口扩展,再由各模块的排查说明定位具体问题。netImgui 远程面板在独立桌面程序查看调试窗口,区分远程 UI、游戏视口绘制与玩法网络权限。窗口扩展与属性绘制复用窗口生命周期、反射 Inspector 和场景绘制,避免为每个调试页重做基础设施。模块总览与接入从配置绑定、动作处理、通道缓存与玩家改键了解 Input,再接入角色的输入配置。绑定与配置生命周期理解跨 IMC 的共享绑定、配置所有权、延迟初始化,以及切换角色时的清理。Handler 与能力分派选择正确的输入阶段,把输入交给移动、GAS、GameplayEvent 或 UI,保持共享 Handler 无玩家状态。修饰器与双击选择输入值变换所在层,理解玩家设置修饰器与 Double Tap 的时序规则。通道输入缓存按 GameplayTag 通道开窗,保留首批或末批输入,正常关闭执行,中断取消丢弃。改键与玩家设置通过 GameSettings 统一编辑与应用,区分 SharedSettings 偏好和 Enhanced Input 键映射数据。调试与排查使用 Gamepad 与 Actions 观察和模拟输入,沿设备、映射、绑定、缓存与能力定位问题。模块总览与接入使用 UE 5.8 原生 Async Message System,把事件通知与接收方解耦,查阅消息收发、路由和 Starry 的实际接入。蓝图收发与解绑通过消息 Id、监听、载荷封装与解包的核心连线,掌握蓝图收发和任务解绑。C++ 收发与解绑按取得系统、登记监听、读取载荷、发送与解绑的顺序,查阅原生 C++ 接口用法。标签、时机与生命周期理解消息的标签层级、World 和 Endpoint 路由、游戏线程派发、载荷快照与 C++ 监听清理。项目消息与排查查阅 Starry 已接入的消息标签、载荷和触发点,区分本地通知、状态复制与 RPC 转发,并沿真实链路排查。模块总览与项目接入管理软引用加载、有序回调与任务作用域,了解指示器画布的实际接入,以及加载完成后的资源和宿主生命周期。软引用加载与 C++ 用法用组件加载软对象和控件类,保存加载结果,理解路径数组、同步回调、失败结果,以及重载与退出时的取消清理。主资产与资源驻留按主资产 ID 和 Bundle 预加载资源,理解句柄保留、取消与 GC 引用的关系,以及 AssetManager 和打包配置的职责。回调顺序与独立作用域理解并行加载与有序回调的区别,使用 FAsyncScope 分开取消任务,了解 AsyncEvent、开始完成通知和等待条件的当前边界。在文档中说明蓝图用法将真实蓝图节点嵌入正文,结合步骤、引脚和连线说明功能,节点文本随文章保存。维护这本手册本地文件与网页编辑共用一份 MDX,日常只改内容与关系,沿用共享版式和图表。