Unity3D RPG 入门项目(十一)主角完整战斗、怪物自动刷新、四大类型技能系统

核心知识点:主角多战斗状态机、远近攻击分段移动逻辑、点击打断战斗、伤害防御保底计算、怪物批量定时刷新、生成区域随机偏移、四种技能(增益 / 强化 / 单体 / 群体)、技能 CD 遮罩倒计时、鼠标切换目标施法、buff 时效管理、技能打断机制

一、主角完整战斗状态体系

1 概念

主角拆分行走、普通攻击、死亡三大主状态;攻击状态内部再细分「追击移动」「原地施法」子状态,解决远距离点怪死循环 BUG,区分点击地面 / 点击怪物两套移动逻辑。

2 特性 / 规则

  1. 状态枚举:Walk(行走)、Attack(攻击)、Dead(死亡);攻击内分子状态 Move 追击、Idle 施法;

  2. 核心数值约束:玩家最小攻击距离<怪物最大追击距离,防止双方互相无法攻击、无限回血死循环;

  3. 交互规则:战斗状态下点击地面直接清空攻击目标、退出战斗;

  4. 死亡锁定所有操作,禁止移动、施法、吃药。

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 特性 / 规则

  1. 攻击速率全局控制普攻间隔;

  2. 动画时长区分普通 / 暴击,计时器未达到动画时长跳过伤害;

  3. 单次攻击完成重置计时器,切换待机动画等待下一轮。

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 特性 / 规则

  1. 防御只减免 70% 伤害,避免数值失衡;

  2. 保底固定 20 点最低伤害;

  3. 受伤协程实现模型红色闪烁、Miss 文字弹窗;

  4. 血量归零切换死亡状态,屏蔽所有交互操作。

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 特性 / 规则

  1. 三类怪物独立计时器、最大存活数量、刷新间隔;

  2. 生成时 X/Z 随机正负偏移,避免全部堆叠在同一点;

  3. 怪物死亡回调刷新管理器,当前数量 1,释放刷新名额;

  4. 运行时动态生成,无需场景预先摆放大量怪物。

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 分类规则

  1. 增益型:即时回血回蓝,按下直接生效,无施法瞄准;

  2. 强化型:临时提升攻击 / 攻速,持续 N 秒,时效结束移除加成;

  3. 单体技能:消耗蓝进入瞄准模式,鼠标点目标释放;

  4. 群体技能:指定范围 AO 伤害,无需锁定,可自定义半径。

3 通用基础规则

  1. 使用前校验蓝量,不足弹窗提示;

  2. 使用后开启 CD 遮罩填充倒计时;

  3. 施法过程可点击地面 / 切换技能打断。

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 特性规则

  1. 增益:读取技能 HP/MP 数值,调用 PlayerStatus 恢复方法,不超过上限;

  2. 强化:记录原始基础攻击 / 攻速,协程等待持续时间结束还原;

  3. 释放播放专属施法动画、脚底特效;

  4. 蓝量不足直接拦截,不进入施法流程。

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 特性规则

  1. 进入瞄准状态更换鼠标图标;

  2. 射线检测怪物,超出技能施法范围弹窗提示;

  3. 选中怪物播放施法动画、生成伤害特效;

  4. 施法中途任意地面点击直接取消,不扣除蓝量。

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 特性规则

  1. 配置表定义 AO 半径、伤害数值;

  2. 物理球形碰撞检测范围内所有 Enemy;

  3. 对每个怪物独立判定闪避、扣血逻辑;

  4. 释放动画完成后统一生成范围特效。

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 战斗模块,作为核心战斗项目案例。

相关推荐
Behaviour3 小时前
Unity AI 生态横评对比:官方 AI Beta / Unity CLI / 团结 Codely / 社区 MCP 四大阵营选型
人工智能·unity·ai·游戏引擎·aigc·ai编程
学习星球3 小时前
OpenHarness 全面配置教学——从游戏开发工作流引入
c++·游戏·ai·ai编程
狂云歌3 小时前
2025年读书回顾,AI+游戏+历史
人工智能·学习·游戏
敢敢のwings10 小时前
世界模型与FlashWorld:从“在梦中学习“到秒级3D场景生成
android·学习·3d
Madokaly13 小时前
基类 DG.Tweening.Tween的源码解读
unity
tanghonghanhaoli13 小时前
【图书翻译】有意义的游戏设计:桌面游戏的方法论与心理学(第4章)
游戏
Behaviour15 小时前
Unity游戏之Jenkins的安装部署应用
游戏·unity·jenkins
tanghonghanhaoli15 小时前
【图书翻译】有意义的游戏设计:桌面游戏的方法论与心理学(第3章)
游戏