能帮到你的话,就给个赞吧 😘
文章目录
- 联动:组件间通过联动逻辑完成任务
-
- [组件的状态 联动 其他组件的行为](#组件的状态 联动 其他组件的行为)
- [组件的行为 受 其他组件的影响](#组件的行为 受 其他组件的影响)
- [组件的状态 联动 其他组件的行为:组件A的状态 联动 组件B的行为](#组件的状态 联动 其他组件的行为:组件A的状态 联动 组件B的行为)
-
- [1.信号发送:组件 A 发送信号](#1.信号发送:组件 A 发送信号)
- [2.行为响应:组件 B 接收信号后并执行预设行为](#2.行为响应:组件 B 接收信号后并执行预设行为)
- [示例:角色死亡时,UI&音效组件 执行预设行为](#示例:角色死亡时,UI&音效组件 执行预设行为)
- [组件的行为 受 其他组件的影响:组件A 的行为 受 组件B 的影响](#组件的行为 受 其他组件的影响:组件A 的行为 受 组件B 的影响)
-
- [行为调整:组件 A 接收信号 并根据 信号内容 调整自身行为](#行为调整:组件 A 接收信号 并根据 信号内容 调整自身行为)
- [信号发送:组件 B 发送信号](#信号发送:组件 B 发送信号)
- [示例:攻击组件 要 根据 防御组件的 "无敌状态" 攻击。](#示例:攻击组件 要 根据 防御组件的 “无敌状态” 攻击。)
- 信号发送机制:接收信号并发送:组件间的交互方式
- 攻击&受击之间的联动
-
- [攻击时不能受击:受击组件受击时 根据攻击组件的状态判断是否可以受击](#攻击时不能受击:受击组件受击时 根据攻击组件的状态判断是否可以受击)
- [受击时不能攻击:攻击组件攻击时 根据受击组件的状态判断是否可以攻击](#受击时不能攻击:攻击组件攻击时 根据受击组件的状态判断是否可以攻击)
- 联动设计
-
- [1.避免双向联动:若 A 联动 B,B 联动 A,则导致组件状态无法预测](#1.避免双向联动:若 A 联动 B,B 联动 A,则导致组件状态无法预测)
- 参考
-
- [编程 组件之间的联动](#编程 组件之间的联动)
联动:组件间通过联动逻辑完成任务
组件的状态 联动 其他组件的行为
组件的行为 受 其他组件的影响
组件的状态 联动 其他组件的行为:组件A的状态 联动 组件B的行为
1.信号发送:组件 A 发送信号
2.行为响应:组件 B 接收信号后并执行预设行为
示例:角色死亡时,UI&音效组件 执行预设行为
cpp
// 血量组件(状态变化源)
class HealthComponent {
private:
float CurrentHealth;
EventBus* EventBus; // 事件总线
public:
HealthComponent(EventBus* Bus) : EventBus(Bus), CurrentHealth(100.0f) {}
void TakeDamage(float Damage) {
CurrentHealth = FMath::Max(0.0f, CurrentHealth - Damage);
// 血量变化时 发布信号
EventBus->Publish(new HealthChangedEvent(CurrentHealth));
// 血量为0时 发布信号
if (CurrentHealth <= 0) {
EventBus->Publish(new DeathEvent());
}
}
};
// UI组件
class UIComponent {
public:
UIComponent(EventBus* Bus) {
// 接收血量变化信号
Bus->Subscribe<HealthChangedEvent>([this](HealthChangedEvent* E) {
UpdateHealthBar(E->NewHealth); // 执行预设行为:更新UI
});
}
};
// 音效组件
class SoundComponent {
public:
SoundComponent(EventBus* Bus) {
// 接收死亡信号
Bus->Subscribe<DeathEvent>([this](DeathEvent* E) {
PlaySound("Death"); // 执行预设行为:播放音效
});
}
};
组件的行为 受 其他组件的影响:组件A 的行为 受 组件B 的影响
行为调整:组件 A 接收信号 并根据 信号内容 调整自身行为
信号发送:组件 B 发送信号
示例:攻击组件 要 根据 防御组件的 "无敌状态" 攻击。
cpp
// 攻击组件(接收无敌信号,根据信号内容调整攻击行为)
class AttackComponent {
private:
EventBus* EventBus;
public:
AttackComponent(EventBus* EventBus) : EventBus(EventBus) {
// 接收无敌信号
Bus->Subscribe<InvincibilityChangedEvent>([this](InvincibilityChangedEvent* E) {
// 根据无敌信号的内容调整攻击行为
if (E->bNewInvincibleState) {
PlayHitEffect(false); // 播放无效攻击特效(未命中)
PlaySound("HitBlocked.wav");
}
else (E->bNewInvincibleState) {
Target->TakeDamage(20.0f, ...); // 造成伤害
PlayHitEffect(true); // 播放有效攻击特效
}
});
}
};
// 防御组件(发布无敌变化信号)
class DefenseComponent {
private:
EventBus* EventBus;
bool bIsInvincible = false;
public:
DefenseComponent(EventBus* EventBus) : EventBus(EventBus) {}
// 激活无敌状态并发布信号
void ActivateInvincibility(float Duration) {
bIsInvincible = true;
// 发布无敌变更信号(通知所有订阅者)
EventBus->Publish(new InvincibilityChangedEvent(bIsInvincible));
// 定时取消无敌
GetWorld()->GetTimerManager().SetTimer(
InvincibilityTimer,
[this]() {
bIsInvincible = false;
EventBus->Publish(new InvincibilityChangedEvent(bIsInvincible));
},
Duration,
false
);
}
};
// 示例
void Example() {
// 创建事件总线
EventBus* GlobalEventBus = new EventBus();
// 创建防御组件
DefenseComponent* DefenseComp = new DefenseComponent(GlobalEventBus);
// 创建攻击组件
AttackComponent* AttackComp = new AttackComponent(GlobalEventBus);
// 触发无敌状态变化(自动通知攻击组件)
DefenseComp->ActivateInvincibility(3.0f); // 3秒无敌
}