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:
@@ -112,7 +112,7 @@ MM/
|
||||
## 构建依赖
|
||||
|
||||
当前已添加的模块:
|
||||
- Core, CoreUObject, Engine, InputCore, EnhancedInput
|
||||
- Core, CoreUObject, Engine, InputCore, EnhancedInput, GameplayAbilities, GameplayTags, GameplayTasks
|
||||
|
||||
如果需要 UI:取消注释 Slate/SlateCore
|
||||
如果需要网络:添加 OnlineSubsystem
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
## 一、游戏概述
|
||||
|
||||
- **类型**:俯视角即时动作刷怪(类暗黑破坏神)
|
||||
- **风格**:Fate 系列 Seven Classes 职业体系
|
||||
- **风格**:七职阶灵感的原创职业体系
|
||||
- **人数**:4-5 人组队联机
|
||||
- **引擎**:Unreal Engine 5.7
|
||||
- **技术栈**:GAS(Gameplay Ability System)、纯 C++ 驱动
|
||||
- **技术栈**:GAS(Gameplay Ability System)、Enhanced 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(只读展示状态,不拥有玩法数据)
|
||||
|
||||
Online(Phase 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 角色
|
||||
```
|
||||
|
||||
114
Source/MM/Core/MMCharacterBase.cpp
Normal file
114
Source/MM/Core/MMCharacterBase.cpp
Normal 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
141
Source/MM/Core/MMCharacterBase.h
Normal file
141
Source/MM/Core/MMCharacterBase.h
Normal 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;
|
||||
};
|
||||
9
Source/MM/Core/MMGameMode.cpp
Normal file
9
Source/MM/Core/MMGameMode.cpp
Normal file
@@ -0,0 +1,9 @@
|
||||
#include "MMGameMode.h"
|
||||
#include "MMCharacterBase.h"
|
||||
#include "MMPlayerController.h"
|
||||
|
||||
AMMGameMode::AMMGameMode()
|
||||
{
|
||||
DefaultPawnClass = AMMCharacterBase::StaticClass();
|
||||
PlayerControllerClass = AMMPlayerController::StaticClass();
|
||||
}
|
||||
28
Source/MM/Core/MMGameMode.h
Normal file
28
Source/MM/Core/MMGameMode.h
Normal 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();
|
||||
};
|
||||
7
Source/MM/Core/MMPlayerController.cpp
Normal file
7
Source/MM/Core/MMPlayerController.cpp
Normal file
@@ -0,0 +1,7 @@
|
||||
#include "MMPlayerController.h"
|
||||
|
||||
AMMPlayerController::AMMPlayerController()
|
||||
{
|
||||
bShowMouseCursor = true;
|
||||
DefaultMouseCursor = EMouseCursor::Default;
|
||||
}
|
||||
30
Source/MM/Core/MMPlayerController.h
Normal file
30
Source/MM/Core/MMPlayerController.h
Normal 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;
|
||||
};
|
||||
1
Source/MM/GAS/AbilitySystem/MMAbilitySystemComponent.cpp
Normal file
1
Source/MM/GAS/AbilitySystem/MMAbilitySystemComponent.cpp
Normal file
@@ -0,0 +1 @@
|
||||
#include "MMAbilitySystemComponent.h"
|
||||
22
Source/MM/GAS/AbilitySystem/MMAbilitySystemComponent.h
Normal file
22
Source/MM/GAS/AbilitySystem/MMAbilitySystemComponent.h
Normal 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:
|
||||
// 当前为空骨架,后续在此添加自定义方法和属性
|
||||
};
|
||||
19
Source/MM/GAS/AbilitySystem/MMAttributeSet.cpp
Normal file
19
Source/MM/GAS/AbilitySystem/MMAttributeSet.cpp
Normal 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);
|
||||
}
|
||||
82
Source/MM/GAS/AbilitySystem/MMAttributeSet.h
Normal file
82
Source/MM/GAS/AbilitySystem/MMAttributeSet.h
Normal 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;
|
||||
};
|
||||
7
Source/MM/Player/SaberCharacter.cpp
Normal file
7
Source/MM/Player/SaberCharacter.cpp
Normal file
@@ -0,0 +1,7 @@
|
||||
#include "SaberCharacter.h"
|
||||
|
||||
ASaberCharacter::ASaberCharacter(const FObjectInitializer& ObjectInitializer)
|
||||
: Super(ObjectInitializer)
|
||||
{
|
||||
// Phase 0: Saber 无额外逻辑,使用基类默认配置
|
||||
}
|
||||
28
Source/MM/Player/SaberCharacter.h
Normal file
28
Source/MM/Player/SaberCharacter.h
Normal 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);
|
||||
};
|
||||
Reference in New Issue
Block a user