:蓝图基础(上))
UE5 入门系列四蓝图入门 —— 事件图表与可视化编程思维前面我们搭好了环境、熟悉了编辑器也理解了 UE 的框架类。从本篇开始我们正式进入写逻辑的阶段先用蓝图完成第一个可交互功能完全不写一行代码。一、蓝图到底是什么蓝图Blueprint是虚幻引擎的可视化脚本系统——你用连节点的方式写程序它编译之后同样是真正的代码。*蓝图能做的C 几乎都能做反过来蓝图的很多能力比如设计师直接改参数正是 C 给不了的。在真实项目中两者是搭档而不是替代关系。UE 中蓝图有几种形式本篇先讲解最主要的一种蓝图类蓝图类型说明Blueprint Class蓝图类可复用的游戏对象带自己的逻辑Level Blueprint关卡蓝图当前关卡的逻辑Blueprint Interface蓝图接口对象间的共同语言Widget Blueprint控件蓝图UI 界面二、创建你的第一个蓝图类1. 创建 Actor 蓝图在内容浏览器中右键 →蓝图类Blueprint Class在弹窗中选择Actor所有可放进关卡的对象的基类命名为BP_MyFirstActor蓝图类通常以BP_开头2. 认识蓝图编辑器双击打开BP_FirstActor你会看到一个和关卡编辑器完全不同的界面。重点关注四个区域Viewport视口给 Actor 挂模型灯光等一些列组件Construction Script构造脚本摆放/刷新时执行的逻辑只在编辑器里运行Event Graph事件图表运行的大部分逻辑都在这里例如BeginPlay、Tick等Class Default / Details细节设置类默认值相当于C当中的给定默认值3. 添加组件打开视口界面左侧Components组件面板可以看到当前蓝图的组件结构点击Add添加就可以添加对应的组件了这里搜索static Mesh添加一个静态网格体组件选中新添加的组件在右侧 **Details 细节 **面板中Static Mesh处选择Cube设置完成后在视口当中就可以看到对应的正方体了保存编译然后把BP_MyFirstActor拖到关卡当中一个方块就会出现到场景当中。此时 Cube 是一个组件Component而BP_FirstActor是Actor。Actor 是放进世界的单位组件是挂在 Actor 身上的零件。三、事件图表打开Event Graph事件图表其中默认存在Event BeginPlay和Event Tick。这里先来了解其中的规则1. 执行线与数据线蓝图节点之间有两种连线白色执行线 “先做什么、后做什么”描述顺序彩色数据线 “把数据传给谁”描述数据流向简单来说白色执行线就是执行顺序彩色就是传递参数数据2. 事件蓝图的程序没有main函数一切从事件Event开始执行。最常用的三个事件事件触发时机Event BeginPlay游戏开始、对象存在的瞬间只触发一次Event Tick每一帧都触发Event ActorBeginOverlap有东西进入这个 Actor 的碰撞范围时示例在Event BeginPlay事件后拖出节点Print String输出Hello UE5!保存编译运行在屏幕左上角就能看到打印出来的文字3. 执行顺序同一个事件内部程序严格沿白线一步一步走但同一帧触发的多个事件之间谁也不等谁。这意味着不要在 BeginPlay 里假设别的对象已经准备好了更安全的方式是用自定义事件或接口在需要时主动索取Delay节点是异步的白线走到 Delay 不会卡住等待而是挂起这条执行链时间到了再从 Delay 后面继续。其他执行链不受影响四、变量与流程控制1. 变量在左侧My Blueprint面板点击Variable命名为TestInt类型选择Integer编译后把默认值设置为0。注意变量名旁边有个小眼睛图标点亮后这个变量会出现在关卡的 Details 面板中可以直接在编辑器里改值变量类型常见的变量类型bool、Type、int、integer64、float、Name、String、Text、Vector向量、Rotator旋转等。2. Branch 分支Branch分支就相当于 C/C 当中的 if-else当条件为真时执行一个分支条件为假时执行另外一个分支。实践走进指定区域只触发一次拖出Event ActorBeginOverlap连接Branch节点条件连一个布尔变量bIsTriggeredTrue 分支什么都不做False 分支连接Print String输出走进指定区域然后Set bIsTriggerd true保存编译运行游戏控制角色走进方块只会触发一次输出。注意在Actor蓝图当中必须有一个碰撞体组件比如Box Collision、Sphere Collision或Capsule Component。光有静态网格体Static Mesh是不够的思考如果忘了把bIsTriggered置为 true会发生什么每次走进来都打印3. Loop 批量处理For Loop 就相当于 C/C 当中的 for 循环拖出ForLoop节点First Index 起始索引值Last Index 结束索引值Loop Body 循环逻辑主体Index 本次循环的索引值Completed Loop执行结束最后执行。在 Begin Play 后连接 For Loop 节点设置 First Index 0Last Index 4Loop Body 连Print String输入接 Loop 的 Index 引脚在 Completed 后连Print String输出End运行后会依次打印 0~4。与 Branch 组合就是所有逻辑的基本骨架分支决定走哪条路循环决定走多少次。五、函数 vs 宏 vs 自定义事件随着节点的变多把所有逻辑都放到Begin Play/Tick当中显得很臃肿也不便于观察和维护所以就要将它们打包复用就像 C 当中封装函数那样。蓝图当中提供了三种打包方式对比项函数 Function宏 Macro自定义事件 Custom Event返回值支持可做纯函数支持没有执行引脚一对进/出可有多对只有输出实现位置独立图表就地展开文本替换本图表内类比算一件事并交还结果复制粘贴一段节点通知某件事发生了六、实战做一个开关门理解完蓝图基础这里做一个真正能用的东西玩家走近门门自动打开玩家离开门自动关闭1. 需求分析把需求翻译成蓝图语言玩家语言蓝图语言走近门玩家进入门的碰撞范围Event ActorBeginOverlap门自动打开修改门的旋转SetActorRotation玩家离开玩家离开门的碰撞范围Event ActorEndOverlap门自动关闭转回原来的角度2. 搭建门的身体新建蓝图类BP_Door继承自Actor添加组件Static Mesh选Door类的门框模型或者使用Cube代替添加组件Box Collision盒体碰撞比门框模型要大一点3. 实现开关逻辑开门在Event ActorBeginOverlap事件当中设置旋转角度yaw 90开门Event ActorBeginOverlap 中关门Event ActorEndOverlap 中编译、把门摆进关卡、运行控制角色走进走出门就会自动关闭和打开了。4. 平滑开关门现在实现的门是瞬间切换很生硬这里改进一下做开关门的动画使用Timeline节点创建一条 0~1 的浮点曲线时长 1 秒。添加Timeline节点双击打开时间轴设置时长为 1 秒。加两个关键帧将Timeline节点输出连接到LerpRotatorLerpRotatorA 表示初始状态B表示结束状态Alpha表示插值系数这里 A 关门角度B 开门角度Alpha Timeline的输出将Lerp结果连到SetActorRotation开门时 Play正向播放 Timeline关门时Reverse。门就会丝滑地旋转开关。本篇小结认识了蓝图的几种形式重点搞懂了Blueprint Class—— 它由组件Component拼装而成本身是一个可以放进世界的Actor。在Event Graph里建立了两个核心直觉白色执行线管顺序彩色数据线管传参程序没有 main 函数一切从事件开始。用变量 Branch实现了 “只触发一次” 的判定用For Loop完成了批量重复。知道了函数、宏、自定义事件三种打包方式的区别逻辑变多之后不会再把所有节点堆在 BeginPlay 里。最后用Timeline Lerp Set Relative Rotation把一个生硬的 “瞬移门” 改成了丝滑的自动开关门。