umg传递数据到HUD的第三种方法-按事件驱动

本文介绍了事件驱动UI更新的方式,通过对比直接传递成员变量和使用get()函数,阐述了在HUD构造函数中绑定事件到控制器的代理设计模式。当用户按下特定键如P键时,能量值会乘以0.9进行更新,这种方式增强了代码的灵活性和解耦性。

前面讲了两种,一个是直接传成员变量,一种是get()函数。

回顾下:

1,在hud的构造函数蓝图中,传递controller的指针过去,作为成员变量

2,(1)传成员变量

this->value = controller->value;

(2)传递函数

getXXX <-> return node 对

好比

std::string getStr()

{

std::string newValue = controller->value;

return newValue;

}

第一二种方法大同小异。只是书写方式的不同。

现在看事件驱动UI更新。也就是代理的方式

1,在UI的构造函数里,不再传指针,而是bind事件,事件的一端是UI,另一端则将controller->newValue;

2,在人物的控制端,在事件调度器建立事件,一有输入,则调用这个事件,这边造炸药包,谁愿绑谁绑,炸着谁算谁。这边造好后,只管输入,更新值,按按钮即可。

energy事件类似。

这次传Energy,只要按P键,则energy*0.9

 

 

2,在HUD蓝图端构造函数获得Character指针,并绑定事件到Character

energy事件类似

运行结果

<think>我们正在处理一个关于在UE5中使用UI按钮控制蓝图灯光开启关闭的问题。 根据用户提供的引用信息,我们可以整合以下知识点: 1. 引用[1]提到Widget蓝图(控件蓝图)是创建UI的基础,使用UMG设计器,可以布局UI元素并绑定逻辑。 2. 引用[2]提到事件(Events)的概念,我们可以使用系统事件或自定义事件来执行逻辑。 3. 引用[3]提到了修改蓝图中物体的碰撞设置,以及参考官方文档的链接,但这个问题主要关注灯光控制,所以碰撞设置可能不是重点,但可以注意蓝图之间的通信。 4. 引用[4]提到了事件分发器(Event Dispatcher)蓝图接口(Blueprint Interface),这些可以用于不同蓝图之间的通信。 因此,实现UI按钮控制灯光的大致思路如下: 步骤1:创建灯光蓝图,其中包含控制灯光开启关闭的逻辑(比如通过变量控制灯光组件的可见性或者强度)。 步骤2:创建UI控件蓝图,添加按钮(比如“开灯”“关灯”按钮)。 步骤3:在UI控件蓝图中为按钮添加点击事件,然后通过某种方式(如事件分发器、蓝图接口、直接获取灯光蓝图实例并调用其函数)来触发灯光蓝图中的开启关闭功能。 考虑到解耦灵活性,推荐使用事件分发器或蓝图接口。但根据引用[4]的事件分发器用法,我们可以采用事件分发器来通知灯光状态改变。 详细步骤: 1. 创建灯光蓝图(例如:BP_Light): - 添加一个点光源(Point Light)或聚光源等。 - 创建两个自定义事件,例如:TurnOnLightTurnOffLight。 - 在TurnOnLight中,设置光源的强度为正常值(比如5000)或者设置可见性为true- 在TurnOffLight中,设置光源的强度为0或者设置可见性为false。 - 为了在UI中触发,我们需要一个事件分发器。在灯光蓝图中创建一个事件分发器,例如命名为“LightSwitchDispatcher”,它带有一个布尔参数(表示开或关)。然后,我们可以将TurnOnLightTurnOffLight事件绑定到这个事件分发器上(根据布尔值决定调用哪个事件)?或者我们也可以不用事件分发器,而是让UI直接调用灯光蓝图中的自定义事件?但是,由于UI灯光蓝图可能属于不同的对象,直接调用可能不太方便,我们可以采用另一种方式:在灯光蓝图中暴露一个公共函数,比如“SetLightState(bool bOn)”,然后在这个函数里根据布尔值调用TurnOnLight或TurnOffLight。 2. 创建UI控件蓝图(例如:WBP_LightControl): -UMG中添加两个按钮:“开灯”“关灯”。 - 为每个按钮添加OnClicked事件。 - 在按钮点击时,我们需要调用灯光蓝图中的函数。如何调用? - 方案1:在UI控件蓝图中获取灯光蓝图的实例,然后直接调用其公共函数(需要将灯光蓝图实例的引用传递到UI控件蓝图中)。 - 方案2:使用事件分发器(Event Dispatcher)绑定(Bind)的方式。 3. 将UI控件蓝图添加到视口: - 在玩家控制器或者HUD中创建这个UI控件,并添加到视口。 4. 建立UI控件灯光蓝图的联系: - 通常,我们可以在关卡蓝图中进行连接,或者在玩家控制器中连接。 这里我们采用一种常见做法:在关卡蓝图中创建灯光蓝图的实例UI控件实例,然后将灯光蓝图实例的函数绑定到UI控件的事件上。 具体步骤(以方案1为例,直接调用函数): 步骤1:创建灯光蓝图(BP_Light): - 打开BP_Light,添加一个函数,命名为“SetLightState”,添加一个布尔类型输入参数“bOn”。 - 在函数内部,使用分支节点(Branch)判断bOn: - 如果为真,执行TurnOnLight(这是一个自定义事件,或者可以直接在函数内部写逻辑) - 如果为假,执行TurnOffLight - 也可以不创建自定义事件,直接在函数内部设置光源的强度: ```cpp // 伪代码 if (bOn) { PointLight->SetIntensity(5000.0f); } else { PointLight->SetIntensity(0.0f); } ``` 步骤2:创建UI控件蓝图(WBP_LightControl): - 添加两个按钮:Button_OnButton_Off。 - 在图表中,为Button_On添加OnClicked事件,然后触发一个自定义事件(比如OnButtonOnClicked)。 - 同样,为Button_Off添加OnClicked事件,触发OnButtonOffClicked。 - 我们需要一个变量来持有灯光蓝图的引用。因此,在WBP_LightControl中添加一个对象变量,命名为“TargetLight”,类型为BP_Light(或者其基类,如Actor)。 - 在OnButtonOnClicked事件中,检查TargetLight是否有效,如果有效,调用TargetLight的SetLightState函数,参数为true- 在OnButtonOffClicked事件中,调用SetLightState(false)。 步骤3:在关卡蓝图中: - 假设我们在场景中放置了一个BP_Light实例(比如命名为BP_Light_Instance)。 - 创建一个WBP_LightControl实例(使用Create Widget节点),然后将其添加到视口(Add to Viewport)。 - 然后,设置这个UI控件实例的TargetLight变量为BP_Light_Instance。 这样,当点击UI按钮时,就会调用灯光蓝图的函数,从而改变灯光状态。 但是,引用[4]提到了事件分发器,我们也可以使用事件分发器来实现: 另一种方案(事件分发器): - 在UI控件蓝图中声明一个事件分发器,命名为“OnLightSwitchRequested”,带有一个布尔参数(bOn)。 - 在按钮点击时,广播这个事件分发器(带相应的参数)。 - 在灯光蓝图中,当创建时(比如BeginPlay),获取UI控件实例(或者通过玩家控制器等方式获取),然后绑定UI控件的事件分发器到灯光蓝图的自定义事件(或函数)上。 - 但是,这样需要灯光蓝图去绑定UI的事件,耦合方向反了,而且获取UI实例可能比获取灯光实例更麻烦。 因此,我们通常采用第一种直接调用的方式,或者使用蓝图接口(Blueprint Interface)来解耦。 蓝图接口的方式: - 创建一个蓝图接口(例如:BPI_LightControl),里面定义一个函数“SetLightState”(带布尔参数,不实现)。 - 让灯光蓝图实现这个接口(在类设置中)。 - 在UI控件蓝图中,我们不需要持有具体的灯光蓝图类型,而是持有这个接口类型的变量。这样,任何实现了该接口的蓝图都可以被控制。 这里,考虑到用户是初学者,我们采用第一种直接调用的方式(简单直接)。 下面我们用蓝图节点来说明关键步骤: 在WBP_LightControl中: - 变量:TargetLight(类型为BP_Light,对象引用) - 事件:OnButtonOnClicked -> 调用 TargetLight 的 SetLightState 函数,传入 true- 事件:OnButtonOffClicked -> 调用 TargetLight 的 SetLightState 函数,传入 false。 在BP_Light中: - 函数:SetLightState(bool bOn) Branch on bOn: True: PointLight->Set Intensity(5000.0) // 或者设置可见性等其他属性 False: PointLight->Set Intensity(0.0) 注意:灯光的控制也可以通过设置可见性(Set Visibility)来实现,但设置强度为0也能达到关灯的效果。 步骤4:在关卡蓝图中,将灯光实例赋值给UI控件的TargetLight变量。 但是,如果灯光实例是在关卡中放置的,那么我们可以通过“Get All Actors Of Class”来获取,或者直接引用。 示例关卡蓝图节点: 1. 创建控件:Create WBP_LightControl -> Return Value (WBP_LightControl 实例) 2. 添加到视口:Add to Viewport 3. 获取灯光实例:可以直接通过拖拽场景中的灯光实例到关卡蓝图中,或者使用“Get All Actors Of Class”(如果只有一个的话,取数组第一个) 4. 设置控件的TargetLight变量:Set (Widget实例) -> TargetLight = (灯光实例) 这样,整个流程就完成了。 总结步骤: 1. 创建灯光蓝图,实现控制开关的函数。 2. 创建UI控件蓝图,包含两个按钮,并定义灯光引用变量按钮点击事件处理(调用灯光函数)。 3. 在关卡蓝图中创建UI控件实例,获取灯光实例,并将灯光实例赋值给UI控件实例的灯光引用变量。 4. 将UI控件添加到视口。 注意:在实际操作中,可能需要考虑多人游戏、网络复制等情况,但这个问题仅涉及本地控制。 因此,回答如下: </think>在UE5中实现UI按钮控制蓝图灯光开关,可通过以下步骤完成: ### 核心实现步骤 1. **灯光蓝图设置** - 创建`BP_Light`蓝图(继承自Actor) - 添加点光源组件(Point Light) - 创建布尔变量`IsLightOn`(默认false) - 实现灯光控制逻辑: ```cpp // 自定义事件 ToggleLight if (IsLightOn) { PointLight->SetIntensity(0) // 关灯 } else { PointLight->SetIntensity(5000) // 开灯(强度值根据需求调整) } IsLightOn = !IsLightOn // 状态翻转 ``` 2. **UI控件蓝图** - 创建控件蓝图`WBP_LightSwitch` - 添加按钮`Button_Switch` - 为按钮绑定点击事件: ```cpp // Button_Switch OnClicked 事件 Execute Console Command("ce ToggleLight") // 发送控制台指令 ``` 3. **事件分发器通信** - 在`BP_Light`中创建**事件分发器**`OnLightToggled` - 在关卡蓝图/控制器蓝图中绑定事件: ```cpp // 事件绑定逻辑 WBP_LightSwitch->Button_Switch.OnClicked.AddDynamic(BP_Light, &BP_Light::ToggleLight) ``` 4. **控制台命令辅助(备选方案)** - 在灯光蓝图中声明控制台函数: ```cpp // BP_Light 的 BeginPlay 事件 UKismetSystemLibrary::RegisterConsoleCommand(this, "ToggleLight", FConsoleCommandDelegate::CreateUObject(this, &ABP_Light::ToggleLight)) ``` ### 关键节点说明 1. **数据绑定** - 将UI按钮状态绑定到`IsLightOn`变量实现自动更新(需在控件蓝图中启用变量绑定- 灯光强度变化通过时间轴节点可实现平滑过渡 2. **多灯光控制** - 通过**蓝图接口**统一控制多个灯光: ```cpp // 创建蓝图接口 LightControllable // 实现函数 ToggleLight() // 让所有灯光蓝图实现此接口 ``` 3. **注意事项** - 确保UI控件已添加到视口(`Add to Viewport`) - 灯光Actor需在关卡中实例化 - 多人游戏需考虑网络复制(`Replicates`属性) > 实现效果:点击UI按钮 → 触发事件分发器 → 调用灯光蓝图中的开关逻辑 → 更新光源强度[^1][^4] ### 优化建议 1. 添加灯光状态图标(开/关不同贴图) 2. 使用**数据驱动**方式管理灯光参数 3. 结合`Widget Animation`实现按钮反馈动画
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值