94 lines
3.5 KiB
Markdown
94 lines
3.5 KiB
Markdown
# 水体游泳系统实现说明
|
||
|
||
## 功能概述
|
||
只有鸭子(Mallard)可以在水中游泳,其他鸟类碰到水会死亡。
|
||
|
||
## 实现细节
|
||
|
||
### 1. HeronPlayer.h 新增内容
|
||
|
||
#### 公共方法
|
||
- `IsInWater()`: 蓝图可调用的函数,返回玩家是否在水中的状态
|
||
|
||
#### 碰撞事件处理
|
||
- `OnComponentBeginOverlap()`: 检测角色进入水体
|
||
- `OnComponentEndOverlap()`: 检测角色离开水体
|
||
|
||
#### 私有成员
|
||
- `bIsInWater`: 布尔值,标记角色是否在水中
|
||
|
||
### 2. HeronPlayer.cpp 实现逻辑
|
||
|
||
#### BeginPlay()
|
||
在游戏开始时绑定碰撞事件到Capsule组件:
|
||
```cpp
|
||
CapsuleComp->OnComponentBeginOverlap.AddDynamic(this, &AHeronPlayer::OnComponentBeginOverlap);
|
||
CapsuleComp->OnComponentEndOverlap.AddDynamic(this, &AHeronPlayer::OnComponentEndOverlap);
|
||
```
|
||
|
||
#### OnComponentBeginOverlap()
|
||
当角色与其他物体发生碰撞时:
|
||
1. 检查碰撞对象是否有"Water"标签
|
||
2. 如果是水体,将`bIsInWater`设置为true
|
||
3. 通过`HeronPlayerState->GetCurrentAbilityType()`获取当前鸟类型
|
||
4. 如果不是Mallard(鸭子),调用`Die()`函数
|
||
5. 如果是Mallard,输出日志表示可以游泳
|
||
|
||
#### OnComponentEndOverlap()
|
||
当角色离开碰撞区域时:
|
||
1. 检查是否离开的是水体
|
||
2. 将`bIsInWater`设置为false
|
||
|
||
## 使用方法
|
||
|
||
### 在编辑器中设置水体
|
||
1. 创建一个Actor作为水体(可以使用Box Trigger或其他碰撞体)
|
||
2. 在该Actor的Details面板中,找到Tags部分
|
||
3. 添加标签"Water"
|
||
|
||
### 测试
|
||
1. 确保HeronPlayerState正确设置了当前能力类型
|
||
2. 使用Mallard能力时,角色可以安全进入水体
|
||
3. 使用其他能力(Default/Heron, Penguin, Woodpecker)时,角色进入水体会触发死亡
|
||
|
||
## 关于 Die() 函数的蓝图使用
|
||
|
||
`Die()` 函数使用了 `BlueprintNativeEvent` 修饰符,其工作方式如下:
|
||
|
||
- `Die()` (BlueprintNativeEvent) - C++ 中处理核心死亡逻辑(禁用输入等)
|
||
- `OnDeathVisual()` (BlueprintImplementableEvent) - 蓝图中实现视觉效果(动画、音效等)
|
||
### BlueprintNativeEvent 的行为:
|
||
|
||
1. **如果不在蓝图中重载 `Die` 事件**:会自动调用 C++ 的 `Die_Implementation()` 默认实现
|
||
2. **如果在蓝图中重载 `Die` 事件**:会完全替换 C++ 实现,不会调用 C++ 代码
|
||
|
||
1. 打开角色蓝图(基于 HeronPlayer 的蓝图)
|
||
### 推荐的使用方式:
|
||
#### 方案 1:使用蓝图事件调度器(推荐)
|
||
在蓝图中不重载 `Die`,而是监听 `OnDeath` 事件来添加自定义行为:
|
||
```
|
||
1. 在蓝图的 Event Graph 中
|
||
2. 创建自定义事件绑定到 `OnDeath`(需要在 C++ 中添加事件调度器)
|
||
3. 在事件中添加死亡动画、音效等
|
||
|
||
#### 方案 1:完全重载 Die()
|
||
如果需要完全自定义死亡逻辑,可以在蓝图中重载 `Die` 事件:
|
||
- **注意**:重载后会替换 C++ 的默认实现,需要自己处理所有逻辑
|
||
|
||
#### 方案 2:扩展死亡系统
|
||
#### 方案 2:完全在蓝图中实现
|
||
如果需要完全控制死亡逻辑,可以在蓝图中重载 `Die` 事件,实现:
|
||
- 禁用输入
|
||
- 播放死亡动画
|
||
- 播放死亡音效
|
||
- 延迟后重生
|
||
- `OnDeathBefore()` - 死亡前调用
|
||
- `OnDeathAfter()` - 死亡后调用
|
||
|
||
## 注意事项
|
||
- 水体Actor必须有"Water"标签才能被正确识别
|
||
- 可以在蓝图中重载`Die()`函数来自定义死亡行为(播放动画、重生等)
|
||
- 在蓝图中可以通过 `Parent: Die` 节点调用 C++ 的默认实现
|
||
- `IsInWater()`函数可以在蓝图中用于UI显示或其他游戏逻辑
|
||
|