166 lines
5.5 KiB
Markdown
166 lines
5.5 KiB
Markdown
# BreakableInterface 使用说明
|
||
|
||
## 概述
|
||
`IBreakableInterface` 是一个可破坏物体的接口,用于啄木鸟能力检测和破坏物体。任何需要被啄木鸟破坏的对象都应该实现这个接口。
|
||
|
||
## 重要提示 ⚠️
|
||
|
||
**如果你的 Wood 类已经继承自 `BaseDestructable`,你不需要做任何改变!**
|
||
|
||
现有的 `NativeDestructThis()` 和 `NativeGetHasTriggedBroken()` 蓝图事件会继续工作。新代码会自动调用这些方法。
|
||
|
||
## 接口方法
|
||
|
||
### 1. NativeDestructThis
|
||
```cpp
|
||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Breakable")
|
||
void NativeDestructThis();
|
||
```
|
||
- **功能**: 破坏物体
|
||
- **用途**: 当啄木鸟技能检测到物体时调用,执行破坏逻辑
|
||
- **实现要求**: 在蓝图中实现(Event NativeDestructThis)
|
||
|
||
### 2. NativeHasTriggeredBroken
|
||
```cpp
|
||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Breakable")
|
||
bool NativeHasTriggeredBroken();
|
||
```
|
||
- **功能**: 检查物体是否已经被破坏
|
||
- **返回值**: `true` = 已破坏, `false` = 未破坏
|
||
- **用途**: 避免重复破坏同一物体
|
||
- **实现要求**: 在蓝图中实现(Event NativeHasTriggeredBroken)
|
||
- **默认返回**: 如果蓝图没有实现,返回 `false`
|
||
|
||
## 在蓝图中实现接口
|
||
|
||
### 方案 A: 为新的 Actor 类实现接口(从零开始)
|
||
|
||
#### 步骤 1: 添加接口
|
||
1. 打开你的蓝图类
|
||
2. 点击工具栏的 **Class Settings**(类设置)
|
||
3. 在 Details 面板找到 **Interfaces** 部分
|
||
4. 点击 **Add** 按钮
|
||
5. 在列表中找到并选择 **BreakableInterface**
|
||
|
||
#### 步骤 2: 实现事件
|
||
|
||
##### Event NativeDestructThis(必须实现)
|
||
1. 在蓝图事件图表中**右键**
|
||
2. 搜索 **"Event Native Destruct This"**
|
||
3. 选择 **Event NativeDestructThis**
|
||
4. 实现破坏逻辑:
|
||
```
|
||
Event NativeDestructThis
|
||
├─ Set bIsBroken = true
|
||
├─ Play Destruction VFX
|
||
├─ Play Destruction Sound
|
||
├─ Destroy Actor (或者 Set Actor Hidden in Game)
|
||
└─ (其他破坏逻辑)
|
||
```
|
||
|
||
##### Event NativeHasTriggeredBroken(必须实现)
|
||
1. 在蓝图事件图表中**右键**
|
||
2. 搜索 **"Event Native Has Triggered Broken"**
|
||
3. 选择 **Event NativeHasTriggeredBroken**
|
||
4. 连接到返回节点,返回破坏状态:
|
||
```
|
||
Event NativeHasTriggeredBroken
|
||
└─ Return Node (连接一个 Boolean 变量 bIsBroken)
|
||
```
|
||
|
||
#### 步骤 3: 添加必要的变量
|
||
在蓝图中添加一个 Boolean 变量:
|
||
- **变量名**: `bIsBroken`
|
||
- **类型**: Boolean
|
||
- **默认值**: false
|
||
|
||
### 方案 B: 现有的 BP_DestructibleWood(已继承 BaseDestructable)
|
||
|
||
**好消息:你不需要改变任何蓝图代码!**
|
||
|
||
如果你的 Wood 蓝图已经实现了:
|
||
- `Event NativeDestructThis`
|
||
- `Event NativeGetHasTriggedBroken`
|
||
|
||
那么它会自动工作,因为接口使用的方法名完全一致。
|
||
|
||
### 调试检查清单
|
||
|
||
如果啄木鸟技能无法破坏物体,请按照以下步骤检查:
|
||
|
||
#### 1. 确认接口已添加
|
||
- [ ] 打开蓝图类
|
||
- [ ] 查看 Class Settings → Interfaces
|
||
- [ ] 确认 **BreakableInterface** 在列表中
|
||
|
||
#### 2. 确认事件已实现
|
||
- [ ] 在事件图表中找到 **Event NativeDestructThis**
|
||
- [ ] 在事件图表中找到 **Event NativeHasTriggeredBroken**
|
||
- [ ] 确认两个事件都有正确的逻辑连接
|
||
|
||
#### 3. 检查返回值
|
||
在 **Event NativeHasTriggeredBroken** 中:
|
||
- [ ] 初始状态应该返回 **false**
|
||
- [ ] 破坏后应该返回 **true**
|
||
- [ ] 确认返回节点正确连接到 `bIsBroken` 变量
|
||
|
||
#### 4. 测试日志输出
|
||
启用调试日志后,你应该看到:
|
||
```
|
||
WoodpeckerAbility: 检测到 Actor: BP_DestructibleWood_C_xxx
|
||
WoodpeckerAbility: BP_DestructibleWood_C_xxx 实现了 BreakableInterface
|
||
WoodpeckerAbility: BP_DestructibleWood_C_xxx HasTriggeredBroken = false
|
||
WoodpeckerAbility: 准备破坏物体 BP_DestructibleWood_C_xxx
|
||
```
|
||
|
||
如果看到:
|
||
```
|
||
BreakableInterface: NativeDestructThis_Implementation 被调用 (默认实现 - 蓝图未重写)
|
||
BreakableInterface: NativeHasTriggeredBroken_Implementation 被调用 (默认实现 - 蓝图未重写)
|
||
```
|
||
说明蓝图**没有**实现接口事件!
|
||
|
||
## 常见问题
|
||
|
||
### Q: 为什么物体一直显示"已经被破坏"?
|
||
A: 检查 `Event NativeHasTriggeredBroken` 是否正确返回 `bIsBroken` 变量,初始值应该是 `false`。
|
||
|
||
### Q: 接口方法没有被调用?
|
||
A:
|
||
1. 确认蓝图类已经添加了 `BreakableInterface` 接口
|
||
2. 确认实现了 `Event NativeDestructThis` 和 `Event NativeHasTriggeredBroken`
|
||
3. 重新编译蓝图
|
||
|
||
### Q: 我的 Wood 类继承自 BaseDestructable,需要改什么吗?
|
||
A: 不需要!保持现有代码不变即可。接口方法名和原有方法名完全一致。
|
||
|
||
### Q: 如何在编辑器中测试?
|
||
A:
|
||
1. 在 WoodpeckerAbility 中将 `bEnableLogging` 设置为 `true`
|
||
2. 运行游戏
|
||
3. 变身为啄木鸟
|
||
4. 靠近可破坏物体并按特殊技能键
|
||
5. 查看输出日志(Output Log)
|
||
|
||
## 技术细节
|
||
|
||
### 接口调用流程
|
||
```cpp
|
||
// 检查是否实现接口
|
||
if (HitActor->Implements<UBreakableInterface>()) {
|
||
// 调用接口方法(如果蓝图实现了会调用蓝图版本,否则调用 C++ 默认实现)
|
||
bool bIsBroken = IBreakableInterface::Execute_NativeHasTriggeredBroken(HitActor);
|
||
|
||
if (!bIsBroken) {
|
||
IBreakableInterface::Execute_NativeDestructThis(HitActor);
|
||
}
|
||
}
|
||
```
|
||
|
||
### BlueprintNativeEvent 说明
|
||
- 使用 `BlueprintNativeEvent` 的函数会自动生成 `Execute_xxx` 和 `xxx_Implementation` 方法
|
||
- 如果蓝图重写了事件,会调用蓝图版本
|
||
- 如果蓝图没有重写,会调用 C++ 的 `_Implementation` 版本
|
||
- 这提供了完美的向后兼容性
|
||
|