UE蓝图 分支(Branch)节点和源码

系列文章目录

UE蓝图 Get节点和源码
UE蓝图 Set节点和源码
UE蓝图 Cast节点和源码
UE蓝图 分支(Branch)节点和源码


文章目录

  • 系列文章目录
  • 一、分支节点功能
  • 二、分支节点用法
  • 三、分支节点使用场景
  • 四、分支节点实现过程
  • 五、分支节点相关源码


一、分支节点功能

在这里插入图片描述

在Unreal Engine(UE)的蓝图中,Branch节点是一个非常重要的的逻辑控制节点,它允许你根据某个条件(Condition)的真假来执行不同的逻辑路径。这个节点在编程中相当于一个if-else语句,用于控制程序的流程。

在UE蓝图中使用Branch节点时,你通常会连接一个布尔值(Boolean)到节点的Condition引脚。这个布尔值可以是来自其他节点的输出,也可以是一个固定的值(如true或false)。然后,你可以在IfTrueIfFalse两个输出引脚上连接你想要执行的操作或逻辑。

  • 如果Condition引脚接收到的值为true,那么从IfTrue引脚引出的逻辑将会被执行。
  • 如果Condition引脚接收到的值为false,那么从IfFalse引脚引出的逻辑将会被执行。

这样,你就可以根据不同的条件来动态地改变你的游戏或应用程序的行为。这在制作交互式游戏、响应玩家输入、处理不同的事件场景等方面都非常有用。


二、分支节点用法

在Unreal Engine(UE)的蓝图中使用分支节点,你需要按照以下步骤进行操作:

  1. 创建分支节点:首先,在蓝图中右击,选择“流程控制” -> “分支”来创建一个分支节点。这将添加一个具有条件(Condition)输入和两个输出引脚(True和False)的节点。

  2. 连接条件输入:接下来,你需要将一个布尔值或表达式连接到分支节点的Condition输入引脚。这个布尔值或表达式的结果将决定分支节点执行哪个分支。

  3. 设置True分支:在分支节点的True输出引脚上,你可以连接任何你希望在条件为真时执行的逻辑或操作。这可以是一个函数调用、变量设置、另一个逻辑节点等。

  4. 设置False分支:同样,在分支节点的False输出引脚上,你可以连接在条件为假时应该执行的逻辑或操作。

  5. 编译和测试:完成节点设置后,确保你的蓝图没有编译错误,并在游戏中测试分支节点的行为。你可以通过改变连接到Condition引脚的值来验证分支是否正确执行。

  6. 调试和优化:如果分支节点的行为不符合预期,使用UE的调试工具来查找问题并进行相应的调整。

记住,分支节点的行为完全依赖于Condition引脚的输入值。确保你的条件表达式正确无误,并且连接到正确的引脚。此外,分支节点通常用于控制程序的流程,因此确保你的逻辑流程符合你的游戏或应用程序的需求。

三、分支节点使用场景

Unreal Engine(UE)蓝图中的分支节点(Branch Node)具有广泛的应用场景,主要用于实现条件逻辑,让游戏或应用程序的行为能够根据不同的条件进行变化。以下是一些具体的应用场景示例:

  1. 玩家交互与决策:在游戏中,分支节点可以用于处理玩家的交互和决策。例如,玩家面对一个选择时,分支节点可以根据玩家的选择(由输入事件触发)来执行不同的游戏逻辑,如不同的对话路径、任务结果或游戏事件。

  2. AI行为树:在AI行为树中,分支节点用于决定AI角色的行为。根据环境状态、目标优先级或其他条件,分支节点可以帮助AI选择最合适的行动方案,如巡逻、搜寻、攻击或逃跑。

  3. 游戏事件与状态管理:在游戏逻辑中,分支节点可用于处理游戏事件和状态的变化。例如,根据玩家的当前状态(如健康值、能量水平或武器状态)来执行不同的游戏逻辑,如允许或禁止某些操作,或触发特定的事件。

  4. 条件性任务执行:在任务或剧情流程中,分支节点允许开发者根据任务条件(如任务状态、玩家行为或环境变量)来执行不同的任务步骤或结果。这有助于创建更丰富、更灵活的剧情体验。

  5. 网络和多玩家交互:在多人在线游戏中,分支节点可以用于处理网络状态、玩家状态或其他玩家的行为。根据这些条件,游戏可以执行不同的逻辑,如同步玩家状态、处理网络延迟或处理玩家间的交互。

  6. 动态环境交互:在动态环境中,分支节点可用于处理与环境的交互。例如,根据物体的状态(如是否被破坏、是否被拾取等)来执行不同的逻辑,如改变环境状态、播放音效或触发其他事件。

在这些场景中,分支节点的灵活性使得开发者能够根据游戏或应用程序的具体需求来创建复杂的逻辑结构,从而实现更加丰富和动态的用户体验。通过组合不同的节点类型和条件判断,开发者可以构建出各种复杂的条件分支逻辑。

四、分支节点实现过程

  • 创建输入输出引脚
public void allocateDefaultPins() {createPin(EGPD_Input, EdGraphSchemaK2.PC_Exec, EdGraphSchemaK2.PN_Execute);EdGraphPin conditionPin = createPin(EGPD_Input, EdGraphSchemaK2.PC_Boolean, EdGraphSchemaK2.PN_Condition);EdGraphPin truePin = createPin(EGPD_Output, EdGraphSchemaK2.PC_Exec, EdGraphSchemaK2.PN_Then);EdGraphPin falsePin = createPin(EGPD_Output, EdGraphSchemaK2.PC_Exec, EdGraphSchemaK2.PN_Else);super.allocateDefaultPins();
}
  • 调用KCHandler_Branch 注册net

  • 编译创建分支Statement

// First skip the if, if the term is false
FBlueprintCompiledStatement& SkipIfGoto = Context.AppendStatementForNode(Node);
SkipIfGoto.Type = KCST_GotoIfNot;
SkipIfGoto.LHS = *CondTerm;
Context.GotoFixupRequestMap.Add(&SkipIfGoto, ElsePin);// Now go to the If branch
FBlueprintCompiledStatement& GotoThen = Context.AppendStatementForNode(Node);
GotoThen.Type = KCST_UnconditionalGoto;
GotoThen.LHS = *CondTerm;
Context.GotoFixupRequestMap.Add(&GotoThen, ThenPin);

五、分支节点相关源码

源码文件:
K2Node_IfThenElse.h
K2Node_IfThenElse.cpp
相关类:
KCHandler_Branch
UK2Node_IfThenElse


class FKCHandler_Branch : public FNodeHandlingFunctor
{
public:FKCHandler_Branch(FKismetCompilerContext& InCompilerContext): FNodeHandlingFunctor(InCompilerContext){}virtual void Compile(FKismetFunctionContext& Context, UEdGraphNode* Node) override{// For imperative nodes, make sure the exec function was actually triggered and not just included due to an output data dependencyFEdGraphPinType ExpectedExecPinType;ExpectedExecPinType.PinCategory = UEdGraphSchema_K2::PC_Exec;FEdGraphPinType ExpectedBoolPinType;ExpectedBoolPinType.PinCategory = UEdGraphSchema_K2::PC_Boolean;UEdGraphPin* ExecTriggeringPin = Context.FindRequiredPinByName(Node, UEdGraphSchema_K2::PN_Execute, EGPD_Input);if ((ExecTriggeringPin == NULL) || !Context.ValidatePinType(ExecTriggeringPin, ExpectedExecPinType)){CompilerContext.MessageLog.Error(*LOCTEXT("NoValidExecutionPinForBranch_Error", "@@ must have a valid execution pin @@").ToString(), Node, ExecTriggeringPin);return;}else if (ExecTriggeringPin->LinkedTo.Num() == 0){CompilerContext.MessageLog.Warning(*LOCTEXT("NodeNeverExecuted_Warning", "@@ will never be executed").ToString(), Node);return;}// Generate the output impulse from this nodeUEdGraphPin* CondPin = Context.FindRequiredPinByName(Node, UEdGraphSchema_K2::PN_Condition, EGPD_Input);UEdGraphPin* ThenPin = Context.FindRequiredPinByName(Node, UEdGraphSchema_K2::PN_Then, EGPD_Output);UEdGraphPin* ElsePin = Context.FindRequiredPinByName(Node, UEdGraphSchema_K2::PN_Else, EGPD_Output);if (Context.ValidatePinType(ThenPin, ExpectedExecPinType) &&Context.ValidatePinType(ElsePin, ExpectedExecPinType) &&Context.ValidatePinType(CondPin, ExpectedBoolPinType)){UEdGraphPin* PinToTry = FEdGraphUtilities::GetNetFromPin(CondPin);FBPTerminal** CondTerm = Context.NetMap.Find(PinToTry);if (CondTerm != NULL) //{// First skip the if, if the term is false{FBlueprintCompiledStatement& SkipIfGoto = Context.AppendStatementForNode(Node);SkipIfGoto.Type = KCST_GotoIfNot;SkipIfGoto.LHS = *CondTerm;Context.GotoFixupRequestMap.Add(&SkipIfGoto, ElsePin);}// Now go to the If branch{FBlueprintCompiledStatement& GotoThen = Context.AppendStatementForNode(Node);GotoThen.Type = KCST_UnconditionalGoto;GotoThen.LHS = *CondTerm;Context.GotoFixupRequestMap.Add(&GotoThen, ThenPin);}}else{CompilerContext.MessageLog.Error(*LOCTEXT("ResolveTermPassed_Error", "Failed to resolve term passed into @@").ToString(), CondPin);}}}
};UK2Node_IfThenElse::UK2Node_IfThenElse(const FObjectInitializer& ObjectInitializer): Super(ObjectInitializer)
{
}void UK2Node_IfThenElse::AllocateDefaultPins()
{const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>();CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_Execute);UEdGraphPin* ConditionPin = CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Boolean, UEdGraphSchema_K2::PN_Condition);K2Schema->SetPinAutogeneratedDefaultValue(ConditionPin, TEXT("true"));UEdGraphPin* TruePin = CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_Then);TruePin->PinFriendlyName =LOCTEXT("true", "true");UEdGraphPin* FalsePin = CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_Else);FalsePin->PinFriendlyName = LOCTEXT("false", "false");Super::AllocateDefaultPins();
}FText UK2Node_IfThenElse::GetNodeTitle(ENodeTitleType::Type TitleType) const
{return LOCTEXT("Branch", "Branch");
}FLinearColor UK2Node_IfThenElse::GetNodeTitleColor() const
{return GetDefault<UGraphEditorSettings>()->ExecBranchNodeTitleColor;
}FSlateIcon UK2Node_IfThenElse::GetIconAndTint(FLinearColor& OutColor) const
{static FSlateIcon Icon("EditorStyle", "GraphEditor.Branch_16x");return Icon;
}FText UK2Node_IfThenElse::GetTooltipText() const
{return LOCTEXT("BrancStatement_Tooltip", "Branch Statement\nIf Condition is true, execution goes to True, otherwise it goes to False");
}UEdGraphPin* UK2Node_IfThenElse::GetThenPin() const
{UEdGraphPin* Pin = FindPin(UEdGraphSchema_K2::PN_Then);check(Pin);return Pin;
}UEdGraphPin* UK2Node_IfThenElse::GetElsePin() const
{UEdGraphPin* Pin = FindPin(UEdGraphSchema_K2::PN_Else);check(Pin);return Pin;
}UEdGraphPin* UK2Node_IfThenElse::GetConditionPin() const
{UEdGraphPin* Pin = FindPin(UEdGraphSchema_K2::PN_Condition);check(Pin);return Pin;
}FNodeHandlingFunctor* UK2Node_IfThenElse::CreateNodeHandler(FKismetCompilerContext& CompilerContext) const
{return new FKCHandler_Branch(CompilerContext);
}void UK2Node_IfThenElse::GetMenuActions(FBlueprintActionDatabaseRegistrar& ActionRegistrar) const
{// actions get registered under specific object-keys; the idea is that // actions might have to be updated (or deleted) if their object-key is  // mutated (or removed)... here we use the node's class (so if the node // type disappears, then the action should go with it)UClass* ActionKey = GetClass();// to keep from needlessly instantiating a UBlueprintNodeSpawner, first   // check to make sure that the registrar is looking for actions of this type// (could be regenerating actions for a specific asset, and therefore the // registrar would only accept actions corresponding to that asset)if (ActionRegistrar.IsOpenForRegistration(ActionKey)){UBlueprintNodeSpawner* NodeSpawner = UBlueprintNodeSpawner::Create(GetClass());check(NodeSpawner != nullptr);ActionRegistrar.AddBlueprintAction(ActionKey, NodeSpawner);}
}FText UK2Node_IfThenElse::GetMenuCategory() const
{return FEditorCategoryUtils::GetCommonCategory(FCommonEditorCategory::FlowControl);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/691863.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mysql数据库主从集群从库Slave因为RelayLog过多过大引起服务器硬盘爆满生产事故实战解决

Mysql数据库主从集群从库slave因为RelayLog过多过大引起从库服务器硬盘爆满生产事故实战解决 一、MySQL数据库主从集群概念 MySQL数据库主从集群是一种高可用性和读写分离的数据库架构&#xff0c;它基于MySQL的复制&#xff08;Replication&#xff09;技术来同步数据。在主…

【Kotlin】Kotlin流程控制

1 选择结构 Kotlin 中选择结构主要包含 if -else、when 语句&#xff0c;并且可以返回结果。 1.1 if-else 1.1. 条件选择 fun main() {var score 85if (score > 90) {println("优秀")} else if (score > 80) {println("良好")} else if (score &…

信息安全法律法规体系

信息安全法律法规体系 我国信息安全法规体系可以分为4层。 法律层面具体对应的法律、法规一般性法律规定宪法、国家安全法、国家秘密法、治安管理处理条例等虽然没有专门针对信息安全的条款,但约束了信息安全相关的行为规范和惩罚信息网络犯罪的法律《中华人名共和国刑法》《…

MySQL篇之主从同步原理

一、原理 MySQL主从复制的核心就是二进制日志。 二进制日志&#xff08;BINLOG&#xff09;记录了所有的 DDL&#xff08;数据定义语言&#xff09;语句和 DML&#xff08;数据操纵语言&#xff09;语句&#xff0c;但不包括数据查询&#xff08;SELECT、SHOW&#xff09;语句。…

19-树-填充每个节点的下一个右侧节点指针 II

这是树的第19篇算法&#xff0c;力扣链接。 给定一个二叉树&#xff1a; struct Node {int val;Node *left;Node *right;Node *next; } 填充它的每个 next 指针&#xff0c;让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点&#xff0c;则将 next 指针设置为 NULL 。…

继ChatGPT后的又一王炸!Sora模型解析与体验通道

前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff1a;https://www.captainbed.cn/z ChatGPT体验地址 文章目录 前言OpenAI体验通道Spacetime Latent Patches 潜变量时空碎片, 建构视觉语言系统…

“薪”的一年程序员裁员潮技术变革情况下 程序员就业机会在哪里?

引言&#xff1a;一对来自中国的工程师夫妻在美国的不幸身亡&#xff0c;疑似与谷歌的裁员有关&#xff0c;这一事件再次引发了人们对技术变革下裁员对程序员影响的关注。 一、针对裁员潮的一些看法 在我看来&#xff0c;技术变革对程序员的影响是双面的。一方面&#xff0c;…

代码随想录算法训练营day16

题目&#xff1a;104.二叉树的最大深度、111.二叉树的最小深度、222.完全二叉树的节点个数 参考链接&#xff1a;代码随想录 104.二叉树的最大深度 思路&#xff1a;上次是用层序遍历的思路做过。这次想一点不一样的思路&#xff0c;对于一个二叉树的最大深度其实即为其两个…

【Python机器学习】详解Python机器学习进行时间序列预测

&#x1f517; 运行环境&#xff1a;Python &#x1f6a9; 撰写作者&#xff1a;左手の明天 &#x1f947; 精选专栏&#xff1a;《python》 &#x1f525; 推荐专栏&#xff1a;《算法研究》 &#x1f510;#### 防伪水印——左手の明天 ####&#x1f510; &#x1f497; 大家…

C++:const关键字

一、const成员变量(常成员变量) 1、只能使用初始化列表对常成员变量进行初始化&#xff1b; 2、常成员变量可以被访问&#xff0c;但是不能被修改&#xff1b; 3、类中所有构造函数都必须在初始化列表对常成员函数进行初始化(包括拷贝构造&#xff0c;移动构造)。 声明&am…

加固平板电脑在无人机的应用|亿道三防onerugged

无人机技术的快速发展已经在许多领域展现出巨大潜力&#xff0c;而加固平板电脑的应用在无人机领域中扮演着重要角色。 首先&#xff0c;加固平板电脑在无人机探测设备中发挥着关键作用。无人机探测设备通常需要实时传输高清图像和数据&#xff0c;以支持各种监测、勘测和检测…

蓝桥杯DP算法——背包问题(C++)

目录 一、01背包问题 二、完全背包问题 三、多重背包问题 四、多重背包问题&#xff08;优化版&#xff09; 五、分组背包问题 一、01背包问题 01背包问题就是有N件物品&#xff0c;一个空间大小为V的背包&#xff0c;每个物品只能使用一次&#xff0c;使得背包中所装物品…

职场数据分析必备|数据库入门之可视化工具Navicat

1、下载 Navicat &#xff08;1&#xff09;官网下载&#xff1a;https://navicatformysql.en.softonic.com/download 下载图示&#xff1a; 数据库入门&#xff08;二&#xff09;可视化工具Navicat​mp.weixin.qq.com/s?__bizMzU3Mzk0OTIzNA&mid100001258&idx1&…

el-table实现嵌套表格的展示

需求 一个表单中存在子表 列表返回格式 实现 实现思路 el-table中在嵌套一个el-table&#xff0c;这样数据格式就没问题了&#xff0c;主要就是样式 将共同的列放到一列中&#xff0c;通过渲染自定义表头render-header&#xff0c;将表头按照合适的宽度渲染出来 <el-…

品牌如何做好话题营销?这三点很关键

从“野性消费”到“疯四文学”&#xff0c;这些品牌让人记住的并不是某个内容&#xff0c;而是一个社交谈资&#xff0c;这些都算是成功的品牌话题&#xff0c;品牌话题的优势在于激活品牌&#xff0c;始终保持品牌活力&#xff0c;今天媒介盒子就来和大家聊聊&#xff1a;品牌…

免费3D模型网站大盘点,你推荐哪一个?

越来越多的设计师开始使用3D模型来提高效率、降低成本、提升效果和用户体验等。然而&#xff0c;寻找高质量的免费3D模型网站并不是一件容易的事情。今天&#xff0c;我们就来为大家介绍一些优秀的免费3D模型网站。 一、建e网 建e网是一个专业的室内设计资源平台&#xff0c;为…

Java的Lock(二)

自旋锁 VS 适应性自旋锁 堵塞或者notify一个Java线程需要操作系统切换CPU状态来完成(详情请参考11408)。这种状态切换需要耗费CPU时间。如果同步代码块种的内容过于简单。状态切换消耗的时间可能比用户代码执行的时间还要长。 在许多场景中,同步资源的锁定时间很短,为了这一…

初识aurora

高速接口 传输速率达到Gbit/s 硬件上的高速接口 SFP VPX FMC等 软件上的高速接口 高速接口的IP核 &#xff0c;起到串并转换等作用 &#xff0c;一般高速接口就调用IP核 auroraIP核 将有效数据打包成aurora帧格式再通过gt收发器传输出去 &#xff0c;一般用在两个fpga之…

电子防潮柜如何应对潮湿问题?

智能化时代的到来&#xff0c;让电子产品成为人们生活中的必需品&#xff0c;电子产品对存储环境的要求非常高。潮湿会产生发霉、生锈、氧化、腐蚀、变形等现象&#xff0c;缩短了电子产品的寿命。绝大部分电子产品都要求在清洁低湿干燥的环境中存放&#xff0c;环境中的温湿度…

【每周AI简讯】OpenAI推出王炸文生视频模型Sora

ChatGPT中文版https://ai7.pro OpenAI推出王炸文生视频模型Sora OpenAI 宣布推出名为 Sora 的新型文本到视频模型。Sora 能根据用户的文本提示&#xff0c;生成长达一分钟的逼真视频。它可以创造出细节丰富的场景、复杂的摄影机运动以及表情丰富的多个角色。Sora 是一种扩散模…