核心知识点:主角多战斗状态机、远近攻击分段移动逻辑、点击打断战斗、伤害防御保底计算、怪物批量定时刷新、生成区域随机偏移、四种技能(增益 / 强化 / 单体 / 群体)、技能 CD 遮罩倒计时、鼠标切换目标施法、buff 时效管理、技能打断机制
一、主角完整战斗状态体系
1 概念
主角拆分行走、普通攻击、死亡三大主状态;攻击状态内部再细分「追击移动」「原地施法」子状态,解决远距离点怪死循环 BUG,区分点击地面 / 点击怪物两套移动逻辑。
2 特性 / 规则
-
状态枚举:Walk(行走)、Attack(攻击)、Dead(死亡);攻击内分子状态 Move 追击、Idle 施法;
-
核心数值约束:玩家最小攻击距离<怪物最大追击距离,防止双方互相无法攻击、无限回血死循环;
-
交互规则:战斗状态下点击地面直接清空攻击目标、退出战斗;
-
死亡锁定所有操作,禁止移动、施法、吃药。
3 代码核心片段
public enum PlayerState { Walk, Attack, Dead }
public enum AttackSubState { ChaseMove, CastIdle }
// 鼠标射线选中怪物逻辑
if(Input.GetMouseButtonDown(0)){
RaycastHit hit;
if(Physics.Raycast(ray, out hit, layerMask)){
EnemyAI enemy = hit.collider.GetComponent<EnemyAI>();
if(enemy != null && enemy.curState != EnemyState.Dead){
attackTarget = hit.transform;
playerState = PlayerState.Attack;
attackTimer = 0;
}
}
else{
// 点击地面清空战斗目标,退出攻击状态
attackTarget = null;
playerState = PlayerState.Walk;
}
}
// 攻击状态分段逻辑
if(playerState == PlayerState.Attack && attackTarget != null){
float dis = Vector3.Distance(transform.position, attackTarget.position);
if(dis > minAtkDis){
subState = AttackSubState.ChaseMove;
// 朝向怪物持续追击
Vector3 targetDir = new Vector3(attackTarget.x, transform.position.y, attackTarget.z);
transform.LookAt(targetDir);
transform.Translate(transform.forward * chaseSpeed * Time.deltaTime);
anim.Play("Walk");
}
else{
subState = AttackSubState.CastIdle;
NormalAttackLogic(); // 原地循环普攻
}
}
4 相关对比
无分层攻击逻辑 VS 主 / 子双层状态
单层逻辑:点怪远距离直接攻击,怪物脱离范围立刻回血,死循环; 双层状态:先追击再施法,距离分层判定,战斗逻辑闭环无 BUG。
5 模块拓展
增加格挡、闪避、蓄力攻击子状态。
二、主角普攻计时器防持续扣血
1 概念
攻击动画时长绑定冷却计时器,动画未播放完成不重复造成伤害,解决 Update 每帧持续秒怪 Bug。
2 特性 / 规则
-
攻击速率全局控制普攻间隔;
-
动画时长区分普通 / 暴击,计时器未达到动画时长跳过伤害;
-
单次攻击完成重置计时器,切换待机动画等待下一轮。
3 代码片段
void NormalAttackLogic(){
attackTimer += Time.deltaTime;
anim.Play(normalAtkAnim);
float animDur = isCrit ? critAnimTime : normalAnimTime;
if(attackTimer < animDur) return;
// 动画播放完毕,仅触发一次伤害
attackTimer = 0;
float rand = Random.Range(0f,1f);
string atkAnim = rand > 0.3f ? normalAtk : critAtk;
anim.Play(atkAnim);
// 对怪物造成伤害
int totalAtk = PlayerStatus.Instance.BaseAtk + PlayerStatus.Instance.EquipAtk;
bool isKill = attackTarget.GetComponent<EnemyAI>().TakeDamage(totalAtk);
if(isKill){
attackTarget = null;
playerState = PlayerState.Walk;
}
}
4 对比
无计时器直接扣血 VS 动画时长锁定伤害
无计时器:Update 持续触发伤害,怪物瞬间清空血量; 时长判定:一次动画仅一次伤害,符合动画打击帧设计。
5 拓展
使用动画帧事件替代计时器精准绑定伤害点。
三、角色受伤伤害计算(防御保底机制)
1 概念
怪物攻击主角时,总伤害 = 敌方攻击力 玩家防御,差值过低设置最低保底伤害,防止防御过高完全无伤。
2 特性 / 规则
-
防御只减免 70% 伤害,避免数值失衡;
-
保底固定 20 点最低伤害;
-
受伤协程实现模型红色闪烁、Miss 文字弹窗;
-
血量归零切换死亡状态,屏蔽所有交互操作。
3 代码片段
public void TakeDamage(int enemyAtk){
if(playerState == PlayerState.Dead) return;
float realDmg = enemyAtk - PlayerStatus.Instance.BaseDef * 0.7f;
int finalDmg = Mathf.Max((int)realDmg, 20);
PlayerStatus.Instance.CurHp -= finalDmg;
StartCoroutine(HurtFlash());
if(PlayerStatus.Instance.CurHp <= 0){
PlayerStatus.Instance.CurHp = 0;
playerState = PlayerState.Dead;
anim.Play("Dead");
// 弹出复活充值弹窗
}
}
4 对比
直接减法扣血 VS 防御比例 + 保底
纯减法:高防御怪物完全不掉血,数值体系崩溃; 比例减免 + 保底:数值平衡,永远存在最低伤害。
5 拓展
护甲穿透、百分比伤害机制。
四、怪物定时批量自动刷新系统
1 概念
场景设置怪物生成空节点,分小 / 中 / 大怪物三类预制,计时器定时在节点周边随机坐标生成,怪物死亡同步扣除当前计数,达到上限停止刷新。
2 特性 / 规则
-
三类怪物独立计时器、最大存活数量、刷新间隔;
-
生成时 X/Z 随机正负偏移,避免全部堆叠在同一点;
-
怪物死亡回调刷新管理器,当前数量 1,释放刷新名额;
-
运行时动态生成,无需场景预先摆放大量怪物。
3 代码片段
// 怪物刷新管理器
public class MonsterSpawnMgr{
public Transform smallSpawnPoint;
public int smallMax = 5;
public int smallCur;
public float smallInterval = 3f;
private float timer;
void Update(){
timer += Time.deltaTime;
if(timer >= smallInterval && smallCur < smallMax){
timer = 0;
// 随机生成坐标
float randX = Random.Range(-5, 5);
float randZ = Random.Range(-5, 5);
Vector3 spawnPos = new Vector3(
smallSpawnPoint.position.x + randX,
smallSpawnPoint.y,
smallSpawnPoint.position.z + randZ
);
GameObject monster = Instantiate(smallPref, spawnPos, Quaternion.identity);
monster.GetComponent<EnemyAI>().spawnMgr = this;
smallCur++;
}
}
// 怪物死亡回调
public void MonsterDie(){
smallCur--;
}
}
4 对比
场景静态怪物 VS 动态定时刷新
静态:怪物打完无法恢复,副本一次性; 动态定时:持续产出怪物,野外刷怪 RPG 标准设计。
5 拓展
分时段刷新、精英怪概率刷新、区域怪物刷新上限控制。
五、四大技能类型整体框架
1 概念
技能分为四类:增益 Buff、强化 Buff、单体锁定攻击、群体范围攻击,统一配置表存储蓝耗、CD、动画、特效、持续时长。
2 分类规则
-
增益型:即时回血回蓝,按下直接生效,无施法瞄准;
-
强化型:临时提升攻击 / 攻速,持续 N 秒,时效结束移除加成;
-
单体技能:消耗蓝进入瞄准模式,鼠标点目标释放;
-
群体技能:指定范围 AO 伤害,无需锁定,可自定义半径。
3 通用基础规则
-
使用前校验蓝量,不足弹窗提示;
-
使用后开启 CD 遮罩填充倒计时;
-
施法过程可点击地面 / 切换技能打断。
4 代码片段(快捷栏 CD 基础)
public class SkillSlot{
public SkillInfo skillData;
public Image cdMask;
public Text cdText;
private float cdTimer;
private bool isCd;
void Update(){
if(!isCd) return;
cdTimer -= Time.deltaTime;
cdMask.fillAmount = cdTimer / skillData.cdTotal;
cdText.text = cdTimer.ToString("F1");
if(cdTimer <= 0){
isCd = false;
cdText.gameObject.SetActive(false);
}
}
// 释放技能开启CD
public void StartCd(){
isCd = true;
cdTimer = skillData.cdTotal;
cdText.gameObject.SetActive(true);
}
}
4 对比
单一即时技能 VS 四类型分层技能体系
单一:无瞄准、无持续 buff,玩法单薄; 四类分层:治疗、增伤、单体爆发、AO 清怪完整战斗循环。
5 拓展
技能连招、被动天赋、装备减 CD 属性。
六、增益 / 强化 Buff 技能逻辑
1 概念
增益即时恢复血量蓝;强化临时提升攻击攻速,协程计时时效结束还原基础属性,两套技能均无需瞄准,快捷键直接释放。
2 特性规则
-
增益:读取技能 HP/MP 数值,调用 PlayerStatus 恢复方法,不超过上限;
-
强化:记录原始基础攻击 / 攻速,协程等待持续时间结束还原;
-
释放播放专属施法动画、脚底特效;
-
蓝量不足直接拦截,不进入施法流程。
3 代码片段
// 强化技能释放
IEnumerator CastBuffSkill(){
playerState = PlayerState.Attack;
anim.Play(buffAnim);
yield return new WaitForSeconds(animTime);
// 叠加属性
float atkMul = skillData.atkPercent / 100f;
float spdMul = skill.spdPercent / 100f;
int tempAtk = (int)(PlayerStatus.Instance.BaseAtk * atkMul);
float tempSpd = baseAtkSpeed * spd;
PlayerStatus.Instance.BaseAtk += tempAtk;
attackSpeed = tempSpd;
// Buff持续倒计时
yield return new WaitForSeconds(skill.duration);
// 时效结束还原
PlayerStatus.Instance.BaseAtk -= tempAtk;
attackSpeed = baseAtk;
anim.Play("Walk");
playerState = PlayerState.Walk;
}
4 对比
一次性加成 VS 时效 buff
永久加成:数值无限膨胀,策划无法平衡; 限时 buff:战斗短期爆发,脱离战斗失效,可控数值。
5 拓展
多层 buff 叠加、刷新持续时间机制。
七、单体锁定技能(瞄准施法 + 打断机制)
1 概念
按下技能快捷键消耗蓝,切换鼠标瞄准样式,点击怪物释放;点击地面 / 切换技能直接打断施法,返还蓝量。
2 特性规则
-
进入瞄准状态更换鼠标图标;
-
射线检测怪物,超出技能施法范围弹窗提示;
-
选中怪物播放施法动画、生成伤害特效;
-
施法中途任意地面点击直接取消,不扣除蓝量。
3 代码片段
// 单体技能预瞄准
public void LockSingleTarget(){
if(!PlayerStatus.Instance.CostMp(skillData.mpCost)){
TipPanel.Show("蓝量不足!");
return;
// 切换瞄准鼠标
CursorManager.Instance.SetAimCursor();
// 标记进入技能瞄准模式
isAimSkill = true;
}
// 鼠标点击判定
if(isAimSkill){
RaycastHit hit;
if(Physics.Raycast(ray, out hit)){
EnemyAI enemy = hit.collider.GetComponent<EnemyAI>();
if(enemy != null){
float dis = Vector3.Distance(transform.position, hit.point);
if(dis > skillData.castRange){
TipPanel.Show("目标超出施法距离!");
CancelAim();
return;
}
CastSingleSkill(enemy);
isAimSkill = false;
}
}
else{
// 点地面打断,返还蓝量
PlayerStatus.Instance.CurMp += skillData.mpCost;
CancelAim();
}
}
4 对比
直接释放单体 VS 瞄准可打断设计
无瞄准:无需选择目标,自动锁定最近怪物,操作简单缺少策略; 瞄准 + 打断:玩家自主选择输出目标,走位可取消技能,增加操作深度。
5 拓展
技能蓄力增伤机制。
八、群体 AO 范围技能
1 概念
无需选中目标,按下直接在玩家周边生成范围伤害特效,范围内全部怪物批量扣血,适合清理小怪群。
2 特性规则
-
配置表定义 AO 半径、伤害数值;
-
物理球形碰撞检测范围内所有 Enemy;
-
对每个怪物独立判定闪避、扣血逻辑;
-
释放动画完成后统一生成范围特效。
3 代码片段
void CastAoeSkill(){
anim.Play(aoeAnim);
yield return new WaitForSeconds(animTime);
// 球形范围检测
Collider[] hitCols = Physics.OverlapSphere(transform.position, skillData.aoeRadius, enemyLayer);
foreach(var col in hitCols){
EnemyAI enemy = col.GetComponent<EnemyAI>();
if(enemy != null && enemy.curState != EnemyState.Dead){
enemy.TakeDamage(skillData.dmg);
}
}
// 生成AOE特效
GameObject eff = Instantiate(skill.effPref, transform.position, Quaternion.identity);
Destroy(eff, 2f);
}
4 对比
单体定点伤害 VS AOE 群体伤害
单体:单目标高伤,BOSS 战专用; AOE:多小怪清场,野外刷怪效率高,两类技能搭配形成循环。
5 拓展
灼烧持续 AOE、减速范围技能。
综合拓展
1 完整业务流程 主角点击怪物进入追击状态→贴近循环普攻→怪物定时随机刷新→四类技能快捷键释放(回血 / 增伤 / 单体瞄准 / AOE)→技能 CD 倒计时遮罩→瞄准状态点击地面打断→怪物死亡扣除刷新名额→主角受伤防御保底计算→死亡锁定全部操作;
2 高频 Bug 排查清单 人怪互相无法攻击:玩家最小攻击距离大于怪物最大追击距离; 技能无限释放:未添加 CD 计时器遮罩;瞄准无法取消:缺少地面点击打断逻辑; 怪物扎堆生成:无 X/Z 随机偏移;防御完全无伤:未设置保底伤害;
3 核心考点 主角双层战斗状态机、怪物动态定时刷新、四类技能设计差异、Buff 时效还原、瞄准施法打断、AOE 球形范围检测、伤害防御保底计算;
4 进阶拓展学习方向 技能连招系统、装备 CD 缩减、元素克制伤害、副本分段刷新、玩家复活机制;
5 实战落地要求 主角战斗 + 怪物自动刷新 + 完整四技能系统整合进 RPG 战斗模块,作为核心战斗项目案例。