feat(M1): project skeleton - character base, ASC, AttributeSet, Enhanced Input

M1 — Project Skeleton:
- MMAbilitySystemComponent: ASC skeleton (extends UAbilitySystemComponent)
- MMAttributeSet: 7 core attributes (Health/MaxHealth/Mana/MaxMana/AttackPower/DefensePower/MoveSpeed)
- MMCharacterBase: character base with ASC, top-down camera, Enhanced Input binding
- MMPlayerController: mouse cursor enabled for top-down view
- MMGameMode: default pawn and controller class setup
- SaberCharacter: Saber class entry point (empty, Phase 0)
- AGENTS.md: updated build dependency list

All public APIs documented with /// Doxygen comments (Chinese).
Pure C++ driven, no editor dependency.
This commit is contained in:
不明不惑
2026-05-02 06:32:46 +08:00
parent 8a7cb24024
commit 266e817771
14 changed files with 602 additions and 41 deletions

View File

@@ -112,7 +112,7 @@ MM/
## 构建依赖
当前已添加的模块:
- Core, CoreUObject, Engine, InputCore, EnhancedInput
- Core, CoreUObject, Engine, InputCore, EnhancedInput, GameplayAbilities, GameplayTags, GameplayTasks
如果需要 UI取消注释 Slate/SlateCore
如果需要网络:添加 OnlineSubsystem

View File

@@ -7,10 +7,10 @@
## 一、游戏概述
- **类型**:俯视角即时动作刷怪(类暗黑破坏神)
- **风格**Fate 系列 Seven Classes 职业体系
- **风格**七职阶灵感的原创职业体系
- **人数**4-5 人组队联机
- **引擎**Unreal Engine 5.7
- **技术栈**GASGameplay Ability System、纯 C++ 驱动
- **技术栈**GASGameplay Ability SystemEnhanced Input、纯 C++ 驱动
### 核心玩法循环
@@ -84,12 +84,10 @@
| 攻击速度 | 影响攻击频率和技能施放速度 |
| 移动速度 | 角色移动快慢 |
#### 战斗属性(隐藏
#### 战斗属性(后续扩展
| 属性 | 说明 |
|------|------|
| 命中 | 影响攻击是否命中 |
| 闪避 | 影响是否躲开攻击 |
| 穿甲 | 忽略目标部分防御 |
| 免伤 | 直接减少受到的伤害百分比 |
| 格挡率 | Rider 专属,格挡概率 |
@@ -97,15 +95,15 @@
| 技能冷却缩减 | 技能 CD 缩短比例 |
| 元素抗性 | 各种元素伤害减免 |
命中和闪避在 MVP 中不做随机面板检定,改由碰撞、走位、翻滚无敌帧、格挡窗口和技能前摇/后摇表达操作性。
### 伤害计算流程(草案)
```
原始伤害 = 攻击力 × 技能倍率 × (暴击 ? 暴击伤害 : 1.0)
命中率检定 = 基础命中 - 目标闪避
命中后:
实际防御 = 目标防御 × (1 - 穿甲率)
减伤后伤害 = 原始伤害 × (1 - 免伤率) - 实际防御
最终伤害 = max(减伤后伤害, 1)
实际防御 = 目标防御 × (1 - 穿甲率)
减伤后伤害 = 原始伤害 × (1 - 免伤率) - 实际防御
最终伤害 = max(减伤后伤害, 1)
```
---
@@ -206,45 +204,117 @@ Boss 房(关卡最终挑战)
---
## 八、MVP 计划Phase 1
## 八、阶段规划
### 目标:跑通核心循环
### Phase 0技术垂直切片
**职业:** Saber + Archer一近一远
目标是证明核心技术链能跑通,不追求内容量。
**关卡:** 1 个随机生成关卡3-5 房间1 Boss
- **职业**Saber 单职业。
- **战斗**基础移动、普攻、1 个主动技能、受击、死亡。
- **敌人**1 种小怪,先用纯 C++ 简单状态机追击/攻击。
- **关卡**:静态或线性 3 房间测试流程,不做真正随机生成。
- **掉落**1 个简化装备掉落,用 C++ 默认数据表达。
- **UI**:只做必要 HUD血量、技能冷却、结算文本
- **不含**Archer、技能树、宝具、精英怪、Boss、联机。
**装备:** 简化版
- 2 品质(普通白、稀有蓝)
- 2-3 条词条
- 不含装备技能
- 不做强化/分解/合成
### Phase 1单机 MVP
**技能树:** 简化版
- 每个职业 3-4 个技能节点
- 仅升级给点
目标是跑通一次完整单机循环。
**宝具:** 先做 1 个Saber
- **职业**Saber 完整基础包,含 2-3 个主动技能和 1 个宝具。
- **关卡**3-5 房间轻随机流程,含 1 个 Boss 房。
- **敌人**小怪、1 种精英怪、1 个 Boss。
- **装备**:普通/稀有 2 品质2-3 条词条,不含装备技能,不做强化/分解/合成。
- **成长**:等级和经验,技能树 UI 延后,只保留自动解锁或简单点数占位。
- **不含**联机、Archer 宝具、复杂随机词条池、商店房。
**不含:** 联机(先单机跑通)
### Phase 2内容扩展
### MVP 里程碑
- Archer 加入基础技能包,宝具视 Phase 1 稳定度决定。
- 技能树 UI、装备强化/分解/合成、更多房间类型、更多职业。
- AI 可从 C++ 状态机升级到 Behavior Tree但必须由 C++ 创建/引用资产,不能依赖编辑器手工配置。
### Phase 3联机验证
- 开始 2 人 Listen Server 验证,再扩展到 4-5 人。
- 复核 GAS 复制、掉落归属、怪物 AI 权威端、结算同步。
- Dedicated Server、OnlineSubsystem/EOS/Steam 等放在该阶段评估。
### 近期里程碑
| 阶段 | 内容 |
|------|------|
| M1 | 项目骨架GAS 集成、角色基类、AttributeSet、基础移动 |
| M2 | 战斗基础:普攻、受击、死亡、伤害计算 |
| M3 | Saber 技能3-4 个主动技能 + 宝具 |
| M4 | Archer 技能3-4 个主动技能 + 宝具 |
| M5 | 怪物 AI小怪行为树、精英怪、Boss |
| M6 | 关卡生成:多房间随机生成 |
| M7 | 装备掉落:简化版掉落 + 词条 |
| M8 | 技能树:简化版 UI + 点数分配 |
| M9 | 打磨整合:完整循环跑通 |
| M0 | 插件/Build.cs 准备:启用 GAS 相关插件和模块依赖 |
| M1 | 项目骨架角色基类、ASC、AttributeSet、Enhanced Input 移动 |
| M2 | 战斗基础:碰撞命中、普攻、伤害 GE、受击、死亡 |
| M3 | Saber 垂直切片1 个主动技能、冷却、基础 HUD |
| M4 | 小怪切片C++ 状态机、追击、攻击、死亡掉落 |
| M5 | 线性 3 房间流程:出生、清房、结算 |
| M6 | Phase 1 扩展Boss、轻随机房间、Saber 宝具、简化装备词条 |
---
## 九、技术架构概要
## 九、系统边界与技术架构
### 模块定义原则
本项目保持单 UE Runtime 模块 `MM`,不拆新的 UE Module。下面的“模块”指 `Source/MM/` 下的逻辑子系统目录,用于拆任务、控依赖和控文件所有权。
跨系统通信优先使用接口、组件公开 API、委托事件和 GAS Effect/Tag不让 Component 直接依赖特定 Actor 类型。
### 系统依赖关系
```
Core
Player/Input ──→ GAS ──→ Combat
│ ↑ ↓
│ │ Equipment
↓ │ ↓
Level ───────→ AI ─────→ Progression
UI只读展示状态不拥有玩法数据
OnlinePhase 3 起接入,反向约束 PlayerState / ASC 归属)
```
### 逻辑模块职责
| 逻辑模块 | 目录 | 职责 | 依赖规则 |
|----------|------|------|----------|
| Core | `Core/` | GameMode、GameState、PlayerController、全局流程 | 可调度其他系统,不放具体战斗公式 |
| Player | `Player/` | 玩家角色、输入绑定、相机、职业入口 | 依赖 GAS/Combat不直接管理装备随机 |
| GAS | `GAS/` | ASC、AttributeSet、Ability、GameplayEffect、GameplayTag | 承载技能和属性变化,不生成关卡或 UI |
| Combat | `Combat/` | 碰撞命中、投射物、伤害计算、阵营/目标筛选 | 调用 GAS 应用效果,不持久化装备数据 |
| AI | `AI/` | 敌人控制器、C++ 状态机、Boss 行为入口 | Phase 0/1 先不用编辑器行为树资产 |
| Level | `Level/` | 房间流程、刷怪点、清房判定、结算入口 | 只请求生成敌人/奖励,不计算词条 |
| Equipment | `Equipment/` | 物品定义、装备组件、词条、掉落生成 | 通过 GAS 修改属性,不直接驱动 UI |
| Progression | `Progression/` | 经验、等级、技能点、解锁规则 | 授予能力或点数,不处理输入 |
| UI | `UI/` | HUD、结算、技能树界面 | 只读订阅状态,通过 Controller/Component 发请求 |
| Online | `Online/` | 联机、会话、复制策略 | Phase 3 前只保留架构兼容,不实现功能 |
### 数据和资产策略
- Phase 0/1 的配置优先用 C++ 默认值、`USTRUCT``UDataAsset` 子类和 `UPROPERTY(EditAnywhere)` 默认值表达。
- 允许 C++ 使用 `ConstructorHelpers::FObjectFinder` 引用已存在资产,但不能要求用户在编辑器里手动拖拽、连蓝图节点或配置变量。
- Behavior Tree、复杂 DataAsset、UMG Widget Blueprint 都不是 MVP 前提;如后续使用,必须有 C++ fallback 或 C++ 创建/引用路径。
- 所有公开类、属性、函数继续按 `AGENTS.md` 写中文 `///` Doxygen 注释。
### UE 插件与 Build.cs 依赖
| 阶段 | UE 插件 / 模块 | 修改位置 | 用途 |
|------|----------------|----------|------|
| 已有 | `ModelingToolsEditorMode` | `MM.uproject` | 编辑器建模工具,仅 Editor 目标使用,不作为运行时依赖 |
| Phase 0 | `GameplayAbilities` 插件;`GameplayAbilities``GameplayTags``GameplayTasks` 模块 | `MM.uproject``Source/MM/MM.Build.cs` | GAS 技能、属性、效果、Tag |
| Phase 0 | `EnhancedInput` 模块 | 已在 `MM.Build.cs` | 输入绑定和动作映射 |
| Phase 0/1 | `UMG``Slate``SlateCore` 模块 | 首个 C++ Widget 落地时加入 `MM.Build.cs` | HUD、结算、技能树 UI |
| Phase 1 | `AIModule``NavigationSystem` 模块 | 使用 UE AIController/NavMesh/Behavior Tree 时加入 `MM.Build.cs` | AI 控制、寻路、行为树任务 |
| Phase 3 | `OnlineSubsystem`、具体平台插件EOS/Steam/Null | 联机阶段再加入 | 会话、匹配、Dedicated Server 支持 |
当前不创建项目自定义 UE Plugin。若后续需要拆自定义插件候选边界为 `MMCombat``MMProgression``MMOnline`,但必须先由用户明确批准,因为每个插件都会引入新的 UE Module 和维护成本。
### 目录草案
```
Source/MM/
@@ -255,25 +325,28 @@ Source/MM/
├── GAS/
│ ├── AbilitySystem/
│ │ ├── MMAbilitySystemComponent.cpp # ASC 扩展
│ │ └── MMAttributeSet.cpp # 属性集
│ │ └── MMAttributeSet.cpp # Phase 0/1 核心属性集
│ ├── Abilities/
│ │ ├── MMGameplayAbility.cpp # 技能基类
│ │ ├── Saber/ # Saber 技能
│ │ └── Archer/ # Archer 技能
│ │ └── Archer/ # Phase 2 Archer 技能
│ └── Effects/
│ ├── MMGameplayEffect_Base.cpp # GE 基类
│ └── MMGameplayEffect_Damage.cpp # 伤害 GE
├── Combat/
│ ├── DamageCalculation.cpp # 伤害计算(命中/闪避/穿甲/免伤
│ ├── DamageCalculation.cpp # 伤害计算(无随机命中/闪避)
│ └── ProjectileBase.cpp # 投射物基类
├── Equipment/
│ ├── ItemDefinition.cpp # 物品定义DataAsset
│ ├── EquipmentComponent.cpp # 装备管理组件
│ └── AffixTable.cpp # 词条表
├── Progression/
│ ├── LevelComponent.cpp # 经验和等级
│ └── SkillUnlockTable.cpp # 技能解锁规则
├── AI/
│ ├── MMAIController.cpp # AI 控制器
│ ├── MMBossAIController.cpp # Boss AI
│ └── Behaviors/ # 行为树任务
│ └── States/ # Phase 0/1 C++ 状态机
├── Level/
│ ├── RoomGenerator.cpp # 房间随机生成
│ └── RoomData.cpp # 房间数据定义
@@ -283,5 +356,5 @@ Source/MM/
│ └── SkillTreeWidget.cpp # 技能树 UI
└── Player/
├── SaberCharacter.cpp # Saber 角色
└── ArcherCharacter.cpp # Archer 角色
└── ArcherCharacter.cpp # Phase 2 Archer 角色
```

View File

@@ -0,0 +1,114 @@
#include "MMCharacterBase.h"
#include "MMAbilitySystemComponent.h"
#include "MMAttributeSet.h"
#include "EnhancedInputSubsystems.h"
#include "EnhancedInputComponent.h"
#include "GameFramework/Controller.h"
#include "GameFramework/PlayerController.h"
#include "Engine/LocalPlayer.h"
#include "Kismet/GameplayStatics.h"
#include "DrawDebugHelpers.h"
AMMCharacterBase::AMMCharacterBase(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
// ---- 能力系统组件 ----
AbilitySystemComponent = CreateDefaultSubobject<UMMAbilitySystemComponent>(TEXT("AbilitySystemComponent"));
AbilitySystemComponent->SetIsReplicated(true);
AbilitySystemComponent->SetReplicationMode(EGameplayEffectReplicationMode::Minimal);
// AttributeSet 不在构造函数中创建,通过 ASC->InitStats 在 BeginPlay 中初始化
// ---- 摄像机系统 ----
CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
CameraBoom->SetupAttachment(RootComponent);
CameraBoom->TargetArmLength = 800.0f;
CameraBoom->bUsePawnControlRotation = false;
CameraBoom->SetWorldRotation(FRotator(-60.0f, 0.0f, 0.0f));
TopDownCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("TopDownCamera"));
TopDownCamera->SetupAttachment(CameraBoom);
}
UAbilitySystemComponent* AMMCharacterBase::GetAbilitySystemComponent() const
{
return AbilitySystemComponent;
}
void AMMCharacterBase::BeginPlay()
{
Super::BeginPlay();
// ---- 通过 ASC 初始化属性集 ----
if (AbilitySystemComponent)
{
// InitStats 内部会创建指定类的 AttributeSet 实例并初始化默认值
const TSubclassOf<UAttributeSet> SetClass = UMMAttributeSet::StaticClass();
const UMMAttributeSet* InitSet = AbilitySystemComponent->InitStats(SetClass, nullptr);
// 缓存指针以便直接访问
AttributeSet = const_cast<UMMAttributeSet*>(InitSet);
}
// ---- 注册默认输入映射上下文 ----
if (APlayerController* PC = Cast<APlayerController>(Controller))
{
if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(
PC->GetLocalPlayer()))
{
Subsystem->AddMappingContext(DefaultMappingContext, 0);
}
}
}
void AMMCharacterBase::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
if (UEnhancedInputComponent* EnhancedInput = Cast<UEnhancedInputComponent>(PlayerInputComponent))
{
EnhancedInput->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AMMCharacterBase::Move);
EnhancedInput->BindAction(LookAction, ETriggerEvent::Triggered, this, &AMMCharacterBase::Look);
}
}
void AMMCharacterBase::Move(const FInputActionValue& Value)
{
const FVector2D MovementVector = Value.Get<FVector2D>();
if (Controller && !MovementVector.IsZero())
{
// 获取控制器的旋转(仅使用 Yaw
const FRotator ControlRotation = Controller->GetControlRotation();
const FRotator YawRotation(0.0f, ControlRotation.Yaw, 0.0f);
// 计算前后和左右方向向量
const FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
// 应用移动
AddMovementInput(ForwardDirection, MovementVector.Y);
AddMovementInput(RightDirection, MovementVector.X);
}
}
void AMMCharacterBase::Look(const FInputActionValue& Value)
{
// 获取鼠标在世界空间中的位置,使角色面朝该方向
if (APlayerController* PC = Cast<APlayerController>(Controller))
{
FHitResult HitResult;
if (PC->GetHitResultUnderCursor(ECC_Visibility, false, HitResult))
{
const FVector TargetLocation = HitResult.Location;
const FVector CharacterLocation = GetActorLocation();
// 计算朝向目标的方向向量(忽略 Z 轴)
const FVector LookDirection = (TargetLocation - CharacterLocation).GetSafeNormal2D();
if (!LookDirection.IsNearlyZero())
{
const FRotator TargetRotation = LookDirection.Rotation();
SetActorRotation(FRotator(0.0f, TargetRotation.Yaw, 0.0f));
}
}
}
}

View File

@@ -0,0 +1,141 @@
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "AbilitySystemInterface.h"
#include "GameFramework/SpringArmComponent.h"
#include "Camera/CameraComponent.h"
#include "InputActionValue.h"
#include "InputMappingContext.h"
#include "InputAction.h"
#include "MMCharacterBase.generated.h"
class UMMAbilitySystemComponent;
class UMMAttributeSet;
/// MM 项目的角色基类。
///
/// 所有游戏角色(包括玩家和 AI的基类集成了能力系统组件ASC和属性集AttributeSet
///
/// # 功能
/// - 提供 ``UMMAbilitySystemComponent`` 和 ``UMMAttributeSet`` 的访问
/// - 默认俯视角摄像机SpringArm + Camera
/// - Enhanced Input 移动和视角输入处理
///
/// # 使用示例
///
/// ```cpp
/// // 获取 ASC
/// auto* ASC = Cast<UMMAbilitySystemComponent>(Character->GetAbilitySystemComponent());
/// // 获取移动速度
/// float Speed = Character->GetAttributeSet()->GetMoveSpeed();
/// ```
///
/// - SeeAlso: ACharacter, IAbilitySystemInterface
UCLASS()
class AMMCharacterBase : public ACharacter, public IAbilitySystemInterface
{
GENERATED_BODY()
public:
/// 构造函数,创建子组件并设置默认参数。
AMMCharacterBase(const FObjectInitializer& ObjectInitializer);
// ==================== 能力系统 ====================
/// 获取能力系统组件。
///
/// 实现 ``IAbilitySystemInterface`` 接口,使 ASC 可通过接口查询。
///
/// - Returns: 指向 ``UMMAbilitySystemComponent`` 的指针
virtual UAbilitySystemComponent* GetAbilitySystemComponent() const override;
/// 获取属性集。
///
/// - Returns: 指向 ``UMMAttributeSet`` 的指针
UMMAttributeSet* GetAttributeSet() const { return AttributeSet; }
// ==================== 组件 ====================
/// 能力系统组件。
///
/// 管理 Gameplay Effects、Abilities 和 Tags。
/// - Note: 在构造函数中通过 ``CreateDefaultSubobject`` 创建
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Ability")
UMMAbilitySystemComponent* AbilitySystemComponent;
/// 属性集。
///
/// 包含生命、法力、攻击力、防御力等核心战斗属性。
/// - Important: 该对象通过 ``ASC->InitStats()`` 在 ``BeginPlay`` 中创建,而非在构造函数中作为子对象创建。
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Ability")
UMMAttributeSet* AttributeSet;
// ==================== 摄像机 ====================
/// 弹簧臂组件。
///
/// 连接 Character 和摄像机,提供缓冲和碰撞检测。
/// - Note: ``TargetArmLength`` 默认 800俯视角 -60 度
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera")
USpringArmComponent* CameraBoom;
/// 俯视角摄像机。
///
/// 固定在弹簧臂末端,提供俯视游戏视角。
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera")
UCameraComponent* TopDownCamera;
// ==================== 输入 ====================
/// 默认输入映射上下文。
///
/// 在 ``BeginPlay`` 中注册到本地玩家的 Enhanced Input 子系统。
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
UInputMappingContext* DefaultMappingContext;
/// 移动输入动作。
///
/// 绑定 WASD 或摇杆,产生角色在世界空间中的移动。
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
UInputAction* MoveAction;
/// 视角/面向输入动作。
///
/// 绑定鼠标位置,控制角色面朝鼠标指向的世界位置。
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
UInputAction* LookAction;
// ==================== 输入处理函数 ====================
/// 处理移动输入。
///
/// 从 ``FInputActionValue`` 中提取 2D 向量X=前后Y=左右),
/// 结合 ``Controller->GetControlRotation()`` 的朝向计算世界空间中的移动方向。
///
/// - Parameter Value: 输入值,类型为 ``FInputActionValue::Axis2D``
UFUNCTION()
void Move(const FInputActionValue& Value);
/// 处理视角/面向输入。
///
/// 获取鼠标在世界空间中的位置,使角色旋转面朝该方向。
///
/// - Parameter Value: 输入值
UFUNCTION()
void Look(const FInputActionValue& Value);
protected:
/// 游戏开始时的初始化逻辑。
///
/// - 初始化属性集(通过 ``ASC->InitStats``
/// - 注册默认输入映射上下文到本地玩家
virtual void BeginPlay() override;
/// 当 Pawn 被控制器控制时调用。
///
/// 在此绑定输入处理函数。
///
/// - Parameter PlayerInputComponent: 玩家的输入组件
virtual void SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) override;
};

View File

@@ -0,0 +1,9 @@
#include "MMGameMode.h"
#include "MMCharacterBase.h"
#include "MMPlayerController.h"
AMMGameMode::AMMGameMode()
{
DefaultPawnClass = AMMCharacterBase::StaticClass();
PlayerControllerClass = AMMPlayerController::StaticClass();
}

View File

@@ -0,0 +1,28 @@
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "MMGameMode.generated.h"
/// MM 项目的游戏模式基类。
///
/// 设置默认的 Pawn 类和玩家控制器类。
/// 后续可在此添加关卡流程控制、刷怪规则等逻辑。
///
/// # 默认配置
///
/// | 属性 | 默认类 | 说明 |
/// |------|--------|------|
/// | DefaultPawnClass | ``AMMCharacterBase`` | 后续可切换为具体职业类 |
/// | PlayerControllerClass | ``AMMPlayerController`` | 俯视角鼠标控制 |
///
/// - SeeAlso: AGameModeBase, AMMCharacterBase, AMMPlayerController
UCLASS()
class AMMGameMode : public AGameModeBase
{
GENERATED_BODY()
public:
/// 构造函数,设置默认 Pawn 和控制器类。
AMMGameMode();
};

View File

@@ -0,0 +1,7 @@
#include "MMPlayerController.h"
AMMPlayerController::AMMPlayerController()
{
bShowMouseCursor = true;
DefaultMouseCursor = EMouseCursor::Default;
}

View File

@@ -0,0 +1,30 @@
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "MMPlayerController.generated.h"
/// MM 项目的玩家控制器。
///
/// 负责管理玩家输入和鼠标光标显示。
/// 俯视角视角下需要显示鼠标光标,以便玩家通过鼠标控制角色朝向。
///
/// - Note: 输入映射在 ``AMMCharacterBase::BeginPlay`` 中注册,
/// 控制器本身不持有输入逻辑。
/// - SeeAlso: APlayerController, AMMCharacterBase
UCLASS()
class AMMPlayerController : public APlayerController
{
GENERATED_BODY()
public:
/// 构造函数,设置默认控制器参数。
AMMPlayerController();
/// 是否显示鼠标光标。
///
/// 俯视角游戏需要始终显示鼠标光标,用于角色朝向和点击交互。
/// 默认为 ``true``。
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
bool bShowMouseCursorInGame = true;
};

View File

@@ -0,0 +1 @@
#include "MMAbilitySystemComponent.h"

View File

@@ -0,0 +1,22 @@
#pragma once
#include "CoreMinimal.h"
#include "AbilitySystemComponent.h"
#include "MMAbilitySystemComponent.generated.h"
/// MM 项目的能力系统组件。
///
/// 继承自 ``UAbilitySystemComponent``,作为项目中所有 Actor 的能力系统核心组件。
/// 负责管理 Gameplay Effects、Gameplay Abilities 和 Gameplay Tags。
///
/// 当前为骨架类,后续将添加自定义的交互逻辑。
///
/// - SeeAlso: UAbilitySystemComponent
UCLASS()
class UMMAbilitySystemComponent : public UAbilitySystemComponent
{
GENERATED_BODY()
public:
// 当前为空骨架,后续在此添加自定义方法和属性
};

View File

@@ -0,0 +1,19 @@
#include "MMAttributeSet.h"
void UMMAttributeSet::PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data)
{
Super::PostGameplayEffectExecute(Data);
// 获取被修改的属性
const FString AttributeName = Data.EvaluatedData.Attribute.GetName();
if (AttributeName.IsEmpty())
{
return;
}
const float NewValue = Data.EvaluatedData.Magnitude;
// 记录属性变更日志
UE_LOG(LogTemp, Log, TEXT("[MMAttributeSet] 属性变更: %s = %.2f"),
*AttributeName, NewValue);
}

View File

@@ -0,0 +1,82 @@
#pragma once
#include "CoreMinimal.h"
#include "AttributeSet.h"
#include "AbilitySystemComponent.h"
#include "MMAttributeSet.generated.h"
/// MM 项目的属性集。
///
/// 定义角色的核心战斗属性,包含生命、法力、攻击力、防御力和移动速度。
/// 所有属性通过 Gameplay Effect 系统进行修改,并在 ``PostGameplayEffectExecute``
/// 中记录变更日志。
///
/// | 属性 | 说明 |
/// |------|------|
/// | Health | 当前生命值 |
/// | MaxHealth | 最大生命值 |
/// | Mana | 当前法力值 |
/// | MaxMana | 最大法力值 |
/// | AttackPower | 攻击力 |
/// | DefensePower | 防御力 |
/// | MoveSpeed | 移动速度 |
///
/// - SeeAlso: UAttributeSet, UAbilitySystemComponent
UCLASS()
class UMMAttributeSet : public UAttributeSet
{
GENERATED_BODY()
public:
/// 当前生命值。
///
/// 范围 ``[0, MaxHealth]``,当 Health <= 0 时角色死亡。
/// - Note: 修改时自动 clamp 到有效范围
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Attributes")
FGameplayAttributeData Health;
/// 最大生命值。
///
/// 角色能拥有的最大生命值上限。
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Attributes")
FGameplayAttributeData MaxHealth;
/// 当前法力值。
///
/// 范围 ``[0, MaxMana]``,用于释放技能等能力消耗。
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Attributes")
FGameplayAttributeData Mana;
/// 最大法力值。
///
/// 角色能拥有的最大法力值上限。
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Attributes")
FGameplayAttributeData MaxMana;
/// 攻击力。
///
/// 影响普通攻击和技能造成的伤害。
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Attributes")
FGameplayAttributeData AttackPower;
/// 防御力。
///
/// 减少受到的伤害。
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Attributes")
FGameplayAttributeData DefensePower;
/// 移动速度。
///
/// 角色的基础移动速度,单位为 UE 世界单位/秒。
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Attributes")
FGameplayAttributeData MoveSpeed;
/// 在 Gameplay Effect 执行后调用。
///
/// 用于处理后处理逻辑,例如将伤害值应用到实际属性上、
/// 触发死亡事件、或记录属性变更日志。
///
/// - Parameter Data: Gameplay Effect 的修改回调数据,包含目标属性、修改值和来源信息
/// - SeeAlso: UAttributeSet::PostGameplayEffectExecute
virtual void PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data) override;
};

View File

@@ -0,0 +1,7 @@
#include "SaberCharacter.h"
ASaberCharacter::ASaberCharacter(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
// Phase 0: Saber 无额外逻辑,使用基类默认配置
}

View File

@@ -0,0 +1,28 @@
#pragma once
#include "CoreMinimal.h"
#include "Core/MMCharacterBase.h"
#include "SaberCharacter.generated.h"
/// Saber 职业角色。
///
/// 七职阶中的近战平衡型职业,使用剑作为武器。
/// Phase 0 阶段仅作为 ``AMMCharacterBase`` 的子类入口,
/// 后续将添加 Saber 专属技能(剑技连招、格挡反击)。
///
/// # 计划功能
///
/// - 剑技连招系统
/// - 格挡反击机制
/// - 宝具:誓约胜利之剑(范围斩击)
///
/// - SeeAlso: AMMCharacterBase
UCLASS()
class ASaberCharacter : public AMMCharacterBase
{
GENERATED_BODY()
public:
/// 构造函数。
ASaberCharacter(const FObjectInitializer& ObjectInitializer);
};