﻿# 水体游泳系统实现说明

## 功能概述
只有鸭子（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显示或其他游戏逻辑

