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

系列文章目录

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.hqwc.cn/news/478958.html

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

相关文章

数据采集三防平板丨三防平板电脑丨停车场应用

随着现代科技的不断发展&#xff0c;三防平板已经成为许多人工作和生活的必备工具。在停车场这个场景中&#xff0c;三防平板的应用可以大大提高停车场管理的效率和安全性。 停车场是现代城市交通管理的重要组成部分&#xff0c;它直接关系到城市交通的流畅和公共安全。停车场…

BUGKU-WEB 留言板1

题目描述 题目截图如下&#xff1a; 进入场景看看&#xff1a; 解题思路 之间写过一题类似的&#xff0c;所以这题应该是有什么不同的那就按照之前的思路进行测试试试提示说&#xff1a;需要xss平台接收flag&#xff0c;这个和之前说的提示一样 相关工具 xss平台&#xf…

『论文阅读|研究用于视障人士户外障碍物检测的 YOLO 模型』

研究用于视障人士户外障碍物检测的 YOLO 模型 摘要1 引言2 相关工作2.1 障碍物检测的相关工作2.2 物体检测和其他基于CNN的模型 3 问题的提出4 方法4.1 YOLO4.2 YOLOv54.3 YOLOv64.4 YOLOv74.5 YOLOv84.6 YOLO-NAS 5 实验和结果5.1 数据集和预处理5.2 训练和实现细节5.3 性能指…

Spring6学习技术|简要介绍+安装环境+入门案例+log4j2日志

学习材料 尚硅谷Spring零基础入门到进阶&#xff0c;一套搞定spring6全套视频教程&#xff08;源码级讲解&#xff09; 碎碎念一下吧&#xff0c;javaWeb跟完了全程。还是感觉啥也不知道&#xff0c;啥也没学会。2025年春天能找到实习吗&#xff1f;真的好担心。 环境安装 纠…

Python打发无聊时光:5.用PyQt实现简陋的用户交互界面

第一步:安装PyQt5库 在终端输入: pip install pyqt5 第二步:复制下列代码 import sys from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QPushButton from PyQt5.QtCore import Qt from PyQt5.QtGui import QFontclass I…

【ArcGIS Pro二次开发】(82):玩个花活_控规指标块生成

一、要实现的效果 废话不多说&#xff0c;这次要实现的是类似控规指标块的标注&#xff1a; 这里只是示例&#xff0c;用了5个格子&#xff0c;做成9个格子也是可以的。 实现这个效果最关键的是要用到Pro中的复合标注。 关于复合标注的用法可以搜一下帮助里的【使用复合注释…

泰尔指数、城乡收入差距1990-2022年(原始数据+测算数据集)

参考龙海明&#xff08;2015&#xff09;、程名望&#xff08;2019&#xff09;的做法&#xff0c;本文采用泰尔指数测算城乡收入差距。也采用陈斌开、林毅夫&#xff08;2013&#xff09;的做法&#xff0c;用城镇居民人均可支配收入除以农村居民人均纯收入来衡量城乡收入差距…

MCAL知识点(二十七):TC275如何通过GPT12实现ABZ解码

目录 1、概述 2、代码实现 1、概述 GPT12 - General Purpose Timer Unit (GPT12):通用定时器单元,具备较为灵活的定时器结构,可以用来做定时器、事件计数、脉冲宽度测量、产生PWM、频率调制、ABZ编码器增量测量。文章记录一下如何通过GPT12实现编码器ABZ信号的测量。 注意…

unity学习(15)——服务器组装(1)

1.新建好的c#项目如下&#xff1a; 文件夹中内容如下&#xff1a; 此时已经可以通过vs2022打开.sln文件&#xff0c;就可以打开项目了。 2.我们把逆向后&#xff08;主程序&#xff09;的内容的代码粘贴过去。有些逆向功底&#xff0c;很快可以定位到&#xff0c;服务器的入口…

二维码钓鱼激增587%:用户陷入社交诈骗陷阱!

Check Point软件技术公司发布的新研究揭示了典型的QR码攻击&#xff0c;通过Check Point的实时网络威胁地图&#xff0c;在两周内发现了2万起QR码钓鱼和恶意软件攻击事件&#xff0c;突显了QR码在网络犯罪分子面前的脆弱性。 QR码是"Quick Response Code"&#xff08…

sensitive-word v0.13 特性版本发布 支持英文单词全词匹配

拓展阅读 sensitive-word-admin v1.3.0 发布 如何支持分布式部署&#xff1f; sensitive-word-admin 敏感词控台 v1.2.0 版本开源 sensitive-word 基于 DFA 算法实现的高性能敏感词工具介绍 更多技术交流 业务背景 对于英文单词 Disburse 之类的&#xff0c;其中的 sb 字母会被…

CDC 整合方案:MySQL > Flink CDC > Kafka > Hudi

博主历时三年精心创作的《大数据平台架构与原型实现&#xff1a;数据中台建设实战》一书现已由知名IT图书品牌电子工业出版社博文视点出版发行&#xff0c;点击《重磅推荐&#xff1a;建大数据平台太难了&#xff01;给我发个工程原型吧&#xff01;》了解图书详情&#xff0c;…