news 2026/11/1 20:36:54

虚幻引擎_UI搭建流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
虚幻引擎_UI搭建流程

基本步骤:

1. 新建继承自UserWidget类型的 C++ 类,命名为HUDWidget。

2. 基于上述HUDWidget类,创建一个对应的蓝图子类, 命名为WBP_HUD

3. 完善UI内容

4. 在目标C++类中调用:有三种常见的方法:

在PlayerController中:
在角色类中:
在游戏模式中:

//.cpp // 1. 获取游戏世界里的第一个玩家控制器 (索引 0) // 如果你在玩家控制器里写代码, 就无需获取控制器 APlayerController* TargetPC = UGameplayStatics::GetPlayerController(this, 0); if (TargetPC && HUDWidgetClass) { // 如果你在玩家控制器里写代码, 就无需用TaegetPC, 直接用this就可以 HUDWidget = CreateWidget<UHUDWidget>(TargetPC, HUDWidgetClass); if (HUDWidget) { HUDWidget->AddToViewport(); } }
//.h #include "HUDWidget.h" UPROPERTY(EditAnywhere) TSubclassOf<UHUDWidget> HUDWidgetClass; UPROPERTY(VisibleAnywhere) UHUDWidget* HUDWidget;

1. 在 PlayerController 中调用 (👑 行业标准/最佳实践)

这是最推荐的方案,特别是对于复杂的项目。

逻辑含义:PlayerController 代表“玩家的大脑/灵魂”。无论你的坦克是炸了、换了一辆新坦克、还是玩家正在观看死亡回放,控制器的生命周期是一直存在的。

适用场景:

  • 常驻 UI:血条、弹药、小地图、暂停菜单。

  • 跨载具游戏:比如像《GTA》或《战地》,玩家从坦克出来走进飞机,UI 应该由控制器负责切换,而不是由坦克负责。

代码逻辑:

// PlayerController.cpp void AMyPlayerController::BeginPlay() { if (IsLocalPlayerController() && HUDClass) { // 只给本地玩家创建 HUDWidget = CreateWidget(this, HUDClass); HUDWidget->AddToViewport(); } }

优缺点:

  • ✅最稳定:坦克炸了,UI 不会莫名其妙消失(除非你手动移除)。

  • ✅分屏完美支持:引擎会自动为玩家 1 生成控制器 1,为玩家 2 生成控制器 2。每个控制器只管自己的 UI,互不干扰。

  • ❌稍微麻烦:你需要新建一个 C++ Controller 类并在 GameMode 里配置它。


2. 在角色/Pawn类 (Tank) 中调用 (⚡️ 简单直接/适合本项目)

这是最适合你当前项目的方案(如果你不想创建 Controller 类)。

逻辑含义:Tank 代表“躯体”。“因为我有了这具身体,所以我才需要看这具身体的血量”。

适用场景:

  • 强绑定 UI:这个 UI 只是为了显示这辆坦克的特定信息(比如坦克的过热条)。

  • 简单项目:没有复杂的重生、换车逻辑。

代码逻辑:

// Tank.cpp void ATank::BeginPlay() { if (IsLocallyControlled() && HUDClass) { // 关键:只在被玩家控制时显示 APlayerController* PC = Cast<APlayerController>(GetController()); if (PC) { HUDWidget = CreateWidget(PC, HUDClass); HUDWidget->AddToViewport(); } } }

优缺点:

  • ✅最直观:血量变量就在 Tank 里,UI 也在 Tank 里创建,传参非常方便。

  • ✅自动化分屏:生成两辆坦克,自然就生成了两份 UI。

  • ❌生命周期风险:如果坦克炸了(调用 Destroy),挂在坦克身上的 UI 指针也就丢了(虽然 UI 可能还在屏幕上,但你无法再更新它,或者导致内存泄漏)。通常需要在 EndPlay 或死亡时手动 RemoveFromParent。


3. 在 GameMode 中调用 (❌ 反面教材/通常不推荐)

除非是特殊情况,否则强烈不建议在这里创建玩家的 HUD(血条等)。

逻辑含义:GameMode 代表“裁判/规则”。裁判不应该管某个具体球员穿什么鞋子(UI)。

为什么不推荐:

  1. 服务器端运行:GameMode 只存在于服务器。在网络联机游戏中,客户端根本没有 GameMode,这会导致 UI 根本创建不出来。

  2. 所有权混乱:GameMode 不属于任何一个玩家。

  3. 分屏噩梦:你必须写 for 循环遍历所有玩家来给他们发 UI,如果玩家中途加入或退出,管理起来非常痛苦。

唯一适用的场景:

  • 全局广播:比如“服务器将在 5 分钟后关闭”、“全服公告”。

  • 单人游戏的特殊流程:比如 Level 加载画面(但通常也不用 GameMode 做)。

代码逻辑(为了演示为什么麻烦):

// GameMode.cpp void AMyGameMode::BeginPlay() { // 你必须手动获取每一个控制器,非常僵硬 APlayerController* PC = UGameplayStatics::GetPlayerController(this, 0); CreateWidget(PC, ...)->AddToViewport(); }

总结与选择建议

以本地双人分屏坦克对战项目为例:

维度PlayerControllerCharacter (Tank)GameMode
推荐指数⭐⭐⭐⭐⭐ (最标准)⭐⭐⭐⭐ (最快捷)⭐ (别用)
UI 归属感UI 属于玩家 (大脑)UI 属于载具 (身体)UI 属于上帝 (规则)
坦克死亡后UI 依然存活,可显示"复活倒计时"UI 通常随坦克一起销毁与坦克无关,但这很不合理
分屏适配完美自动适配完美自动适配需要手动写循环管理

5. 在蓝图中挂载

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/11/1 22:47:02

金融投研平台如何导入CKEDITOR中的股票走势图到C#.NET?

各位爷们儿&#xff0c;咱西安程序员又双叒叕接到个神仙需求&#xff01;客户要给CKEditor装个"超级粘贴板"&#xff0c;说是要能直接从Word里CtrlC/V&#xff0c;连Excel表格、PPT公式、PDF图片都要原样搬过来。这哪是编辑器啊&#xff0c;这分明是要造个"文档…

作者头像 李华
网站建设 2026/11/1 5:34:24

教育考试系统怎样解决CKEDITOR公式截图防作弊上传?

山东某国企项目需求实现记录&#xff1a;基于CKEditor4的Word/微信内容集成方案 一、需求分析与技术选型 核心需求&#xff1a; 编辑器插件需支持&#xff1a; Word粘贴&#xff08;保留格式图片自动上传&#xff09;Word/Excel/PPT/PDF导入&#xff08;保留格式图片&#xff…

作者头像 李华
网站建设 2026/10/21 16:07:03

我的AI测试模型,现在能预测“哪个Bug修复会引入新Bug”

——突破软件质量保障的“修复悖论”困局 一、引言&#xff1a;修复的诅咒与测试新战场 在持续交付的敏捷洪流中&#xff0c;软件测试团队面临一个残酷悖论&#xff1a;39%的生产环境缺陷源自修复性变更&#xff08;2025年ISTQB全球报告&#xff09;。当开发人员提交一个Bug修…

作者头像 李华
网站建设 2026/11/1 4:10:32

一个 C Core,同时被 JNI 和 dart:ffi 调用

——从 0 设计一套“可跨语言复用”的 native 核心库关键词&#xff1a;FFI / JNI / dart:ffi / C Core / 系统边界 / 句柄模型 / 架构设计一、这篇文章我们到底要验证什么&#xff1f;不是验证&#xff1a;JNI 会不会写dart:ffi 会不会用而是验证一件更重要的事&#xff1a;&a…

作者头像 李华
网站建设 2026/11/2 1:18:30

医疗领域,PHP大文件上传与下载的示例步骤?

大三学长毕业设计救星&#xff1a;原生JS大文件传输系统&#xff08;附完整代码&#xff09; 兄弟&#xff0c;作为刚摸爬滚打完毕设的信息安全专业学长&#xff0c;太懂你现在的处境了——找工作要作品&#xff0c;大文件上传需求卡壳&#xff0c;网上开源代码全是“断头路”…

作者头像 李华
网站建设 2026/10/27 8:52:55

Java版LeetCode热题100之「删除链表的倒数第 N 个结点」详解

Java版LeetCode热题100之「删除链表的倒数第 N 个结点」详解 本文约9200字&#xff0c;全面深入剖析 LeetCode 第19题《删除链表的倒数第 N 个结点》。涵盖题目解析、三种解法&#xff08;计算长度法、栈法、双指针法&#xff09;、复杂度分析、面试高频问答、实际开发应用场景…

作者头像 李华