ARPG 游戏战斗系统设计详解
ARPG(Action Role-Playing Game,动作角色扮演游戏) 的战斗系统需要兼顾 操作性、打击感、技能组合、AI 交互 等多个方面。
本指南将详细解析 ARPG 战斗系统的核心要素、设计思路与优化方案,适用于 Unity、UE4 及自研引擎开发。
1. ARPG 战斗系统的核心要素
🎯 1.1 战斗核心机制
- 即时战斗(Real-Time Combat):无回合制,玩家实时控制角色进行攻击、闪避、技能释放等操作。
- 技能系统(Skill System):角色拥有不同的技能,支持连招、冷却、消耗资源(如 MP、能量)。
- 动画驱动(Animation-Based Combat):攻击、技能、闪避等动作依赖动画系统,可能包含 Root Motion。
- 碰撞检测(Hit Detection):使用 碰撞体(Hitbox)或 追踪射线(Raycast) 进行伤害判定。
- 敌人 AI(Enemy AI):敌人有攻击、闪避、寻路等行为,可能包括状态机或行为树(Behavior Tree)。
- 属性与数值(Stats & Attributes):角色的 HP、MP、攻击力、防御力、暴击率等数值影响战斗效果。
2. 战斗系统架构
📌 2.1 主要模块
模块 | 功能 |
---|---|
角色控制(Character Controller) | 处理玩家输入、移动、攻击、技能释放 |
动画系统(Animation System) | 角色动画驱动攻击、技能、受击、闪避 |
技能系统(Skill System) | 管理技能释放、冷却、组合 |
伤害计算(Damage System) | 计算攻击伤害、暴击、防御、Buff |
碰撞检测(Hit Detection) | 使用 Hitbox、Raycast 进行伤害判定 |
敌人 AI(Enemy AI) | 控制敌人行为(巡逻、攻击、闪避) |
战斗 UI(Combat UI) | 显示 HP、MP、技能冷却等状态 |
3. 角色控制与动画系统
🎮 3.1 玩家角色控制
- 输入映射(Input Mapping):
- 轻攻击(Light Attack) →
左键 / X
- 重攻击(Heavy Attack) →
右键 / Y
- 闪避(Dodge) →
空格 / B
- 技能释放(Skill) →
Q/E/R
- 锁定目标(Lock-On) →
Tab
- 轻攻击(Light Attack) →
- 移动与旋转(Movement & Rotation):
- 使用 Character Controller 或 Root Motion 控制角色移动。
- 锁定系统(Lock-On System) 允许玩家锁定敌人,自动调整摄像机。
🎬 3.2 动画系统
- 动画状态机(Animation State Machine):
Idle
→Walk/Run
→Attack
→Skill
→Dodge
→Hit
→Death
- 通过 动画事件(Animation Event) 触发攻击判定。
- Root Motion vs. 物理控制(Physics-Based Movement):
- Root Motion:动画驱动移动,适用于精准连招。
- 物理控制:代码控制移动,适用于自由战斗。
✅ 示例(Unity Animator)
animator.SetTrigger("Attack");
✅ 示例(UE4 动画蓝图)
void AMyCharacter::PlayAttackAnimation()
{
PlayAnimMontage(AttackMontage);
}
4. 伤害判定与碰撞检测
⚔ 4.1 碰撞检测方式
方式 | 优点 | 缺点 |
---|---|---|
Hitbox(碰撞体) | 精确,可匹配动画 | 需要手动调整 Hitbox |
Raycast(射线检测) | 适用于远程攻击 | 可能误伤未命中敌人 |
Trigger(触发器) | 适合范围技能 | 精度较低,可能误判 |
✅ 示例(Unity - Hitbox 检测)
void CheckHit()
{
Collider[] hitEnemies = Physics.OverlapSphere(attackPoint.position, attackRange, enemyLayers);
foreach (var enemy in hitEnemies)
{
enemy.GetComponent<Health>().TakeDamage(damage);
}
}
✅ 示例(UE4 - 碰撞体检测)
void AMyCharacter::OnAttack()
{
TArray<AActor*> HitActors;
AttackCollider->GetOverlappingActors(HitActors);
for (AActor* Actor : HitActors)
{
Actor->TakeDamage(AttackDamage, DamageEvent, GetController(), this);
}
}
5. 技能系统
🔮 5.1 技能数据结构
字段 | 作用 |
---|---|
技能名称(Name) | 技能的名称 |
伤害(Damage) | 造成的基础伤害 |
冷却时间(Cooldown) | 释放后的等待时间 |
消耗(Cost) | MP / 体力消耗 |
技能类型(Type) | 近战、远程、AOE |
特效(VFX/SFX) | 视觉 / 音效表现 |
✅ 技能数据结构(C++)
USTRUCT(BlueprintType)
struct FSkillData
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FString Name;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float Damage;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float Cooldown;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float Cost;
};
🎮 5.2 技能释放流程
- 检查冷却时间(Cooldown)
- 消耗 MP / 体力
- 播放动画 + 触发 Hitbox
- 生成特效(VFX + SFX)
- 执行技能逻辑(伤害、Buff)
- 进入冷却状态
✅ 示例(C++ 技能释放)
void AMyCharacter::UseSkill(FSkillData Skill)
{
if (CurrentMana < Skill.Cost || IsCooldown) return;
CurrentMana -= Skill.Cost;
PlayAnimMontage(Skill.Animation);
StartCooldown(Skill.Cooldown);
}
6. 敌人 AI(Enemy AI)
🤖 6.1 AI 逻辑
- 巡逻(Patrol):在特定区域巡逻。
- 追踪(Chase):检测到玩家后追击。
- 攻击(Attack):靠近玩家后进行攻击。
- 闪避(Dodge):躲避玩家攻击。
✅ 示例(UE4 行为树 AI)
void AEnemyAI::OnSeePlayer(APawn* Player)
{
BlackboardComponent->SetValueAsObject("Target", Player);
AIController->MoveToActor(Player);
}
7. 伤害计算
💥 7.1 计算公式
Damage = (BaseDamage + WeaponDamage) * (1 + Strength / 100) - TargetArmor;
🔥 7.2 伤害类型
- 物理伤害(Physical Damage)
- 魔法伤害(Magic Damage)
- 暴击伤害(Critical Damage)
- Dot 伤害(持续伤害,如中毒)
✅ 示例(UE4 伤害计算)
float FinalDamage = BaseDamage * DamageMultiplier;
Target->TakeDamage(FinalDamage, DamageEvent, GetController(), this);
8. 结论
📌 ARPG 战斗系统的核心:
- 角色控制 & 动画驱动
- 碰撞检测(Hitbox / Raycast)
- 技能系统(冷却、伤害、特效)
- 敌人 AI(巡逻、攻击、闪避)
- 伤害计算(数值系统)
🚀 合理设计战斗系统,使其既具有流畅的操作感,又能提供深度的策略性!
ARPG 战斗日志系统实现
在 ARPG 游戏中,战斗日志(Combat Log) 主要用于:
✅ 记录战斗事件(攻击、技能、伤害、暴击、闪避等)
✅ 调试战斗系统(检测数值计算是否正确)
✅ UI 显示反馈(玩家可查看战斗详情)
✅ 多人战斗同步日志(用于 PvP、团队战斗)
本指南将介绍 战斗日志的架构设计、数据结构、存储方式(本地/网络)、UI 显示,适用于 Unity / UE4 / 自研引擎。
1. 战斗日志的核心组成
模块 | 作用 |
---|---|
CombatLogManager | 负责管理、记录战斗日志 |
CombatLogEntry | 具体的战斗日志数据结构 |
CombatLogStorage | 存储战斗日志(内存 / 文件 / 网络) |
CombatLogUI | 负责在 UI 上显示日志 |
2. 战斗日志的数据结构
📌 2.1 结构设计
一个战斗日志通常包含:
- 时间戳(Timestamp):记录事件触发的时间
- 事件类型(EventType):攻击、技能、暴击、闪避、治疗等
- 攻击者(Attacker):施加伤害的对象
- 目标(Target):受到影响的对象
- 伤害数值(Damage):最终计算的伤害值
- 附加效果(Effects):是否暴击、是否触发 Buff、是否闪避
📌 2.2 C++ 结构体(UE4)
USTRUCT(BlueprintType)
struct FCombatLogEntry
{
GENERATED_BODY()
UPROPERTY(BlueprintReadOnly)
float Timestamp;
UPROPERTY(BlueprintReadOnly)
FString EventType;
UPROPERTY(BlueprintReadOnly)
FString AttackerName;
UPROPERTY(BlueprintReadOnly)
FString TargetName;
UPROPERTY(BlueprintReadOnly)
float Damage;
UPROPERTY(BlueprintReadOnly)
FString Effects;
FCombatLogEntry()
: Timestamp(0), Damage(0), EventType("Unknown"), Effects("None") {}
};
✅ 示例日志
[12:30:45] 玩家A 使用【火球术】对 敌人B 造成 300 伤害(暴击)
[12:30:46] 敌人B 使用【挥砍】对 玩家A 造成 120 伤害
[12:30:47] 玩家A 闪避了 敌人B 的攻击
📌 2.3 C# 结构体(Unity)
[System.Serializable]
public struct CombatLogEntry
{
public float Timestamp;
public string EventType;
public string Attacker;
public string Target;
public float Damage;
public string Effects;
public CombatLogEntry(float timestamp, string eventType, string attacker, string target, float damage, string effects)
{
Timestamp = timestamp;
EventType = eventType;
Attacker = attacker;
Target = target;
Damage = damage;
Effects = effects;
}
}
3. 战斗日志管理器
📌 3.1 UE4 版(C++)
UCLASS()
class MYGAME_API UCombatLogManager : public UObject
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadOnly)
TArray<FCombatLogEntry> CombatLogs;
void AddLogEntry(FString EventType, FString Attacker, FString Target, float Damage, FString Effects)
{
FCombatLogEntry NewEntry;
NewEntry.Timestamp = FPlatformTime::Seconds();
NewEntry.EventType = EventType;
NewEntry.AttackerName = Attacker;
NewEntry.TargetName = Target;
NewEntry.Damage = Damage;
NewEntry.Effects = Effects;
CombatLogs.Add(NewEntry);
UE_LOG(LogTemp, Log, TEXT("[%f] %s 对 %s 造成 %f 伤害 (%s)"),
NewEntry.Timestamp, *Attacker, *Target, Damage, *Effects);
}
};
✅ 示例调用
CombatLogManager->AddLogEntry("技能攻击", "玩家A", "敌人B", 300, "暴击");
📌 3.2 Unity 版(C#)
using System.Collections.Generic;
using UnityEngine;
public class CombatLogManager : MonoBehaviour
{
public List<CombatLogEntry> CombatLogs = new List<CombatLogEntry>();
public void AddLogEntry(string eventType, string attacker, string target, float damage, string effects)
{
CombatLogEntry newEntry = new CombatLogEntry(Time.time, eventType, attacker, target, damage, effects);
CombatLogs.Add(newEntry);
Debug.Log($"[{newEntry.Timestamp}] {attacker} 对 {target} 造成 {damage} 伤害 ({effects})");
}
}
✅ 示例调用
combatLogManager.AddLogEntry("技能攻击", "玩家A", "敌人B", 300, "暴击");
4. 战斗日志存储
📌 4.1 存储在本地(文件存储)
📌 UE4 版
void SaveLogToFile()
{
FString LogFilePath = FPaths::ProjectSavedDir() + "CombatLog.txt";
FString LogContent;
for (const FCombatLogEntry& Log : CombatLogs)
{
LogContent += FString::Printf(TEXT("[%f] %s 对 %s 造成 %f 伤害 (%s)\n"),
Log.Timestamp, *Log.AttackerName, *Log.TargetName, Log.Damage, *Log.Effects);
}
FFileHelper::SaveStringToFile(LogContent, *LogFilePath);
}
📌 Unity 版
using System.IO;
public void SaveLogToFile()
{
string logFilePath = Application.persistentDataPath + "/CombatLog.txt";
string logContent = "";
foreach (var log in CombatLogs)
{
logContent += $"[{log.Timestamp}] {log.Attacker} 对 {log.Target} 造成 {log.Damage} 伤害 ({log.Effects})\n";
}
File.WriteAllText(logFilePath, logContent);
}
5. 战斗日志 UI 显示
📌 5.1 UI 组件
组件 | 作用 |
---|---|
TextMeshPro(Unity)/ UTextBlock(UE4) | 显示日志内容 |
ScrollView / ScrollBox | 允许滚动查看日志 |
Clear Button | 清空日志 |
📌 5.2 Unity UI 更新
using UnityEngine;
using TMPro;
public class CombatLogUI : MonoBehaviour
{
public TextMeshProUGUI logText;
private CombatLogManager logManager;
void Start()
{
logManager = FindObjectOfType<CombatLogManager>();
UpdateLogUI();
}
public void UpdateLogUI()
{
logText.text = "";
foreach (var log in logManager.CombatLogs)
{
logText.text += $"[{log.Timestamp}] {log.Attacker} 对 {log.Target} 造成 {log.Damage} 伤害 ({log.Effects})\n";
}
}
}
✅ 每次战斗事件发生时,自动更新 UI
logManager.AddLogEntry("普通攻击", "玩家A", "敌人B", 100, "无");
combatLogUI.UpdateLogUI();
6. 结论
功能 | 实现方式 |
---|---|
战斗日志数据结构 | FCombatLogEntry (UE4) / CombatLogEntry (Unity) |
日志管理器 | 记录 & 维护战斗日志 |
日志存储 | 内存存储 / 文件存储 |
日志 UI 显示 | TextMeshPro (Unity) / UTextBlock (UE4) |
🔹 战斗日志系统不仅用于调试,也可以增强玩家体验(PvP 复盘、战斗回放)。
🔹 结合 UI 和文件存储,可以让战斗日志更具交互性和可读性!