其实技能系统有很多种设计方式,暂且列出一种以前项目的设计。
    目标:
    1.使用尽可能少的类,实现游戏里所有种类的技能。

    2.满足打击感的可调节性、可配置性。 
    3.能基本满足绝大部分角色扮演类游戏(比如ARPG、卡牌、Moba、ACT等),更换项目只需要对代码做微调。 ACT类,连击技能需要在技能类调用之前做计数,剩余的代码一样。

    需求分析:
        根据上面的目标,我们把攻击分为几个模块  

       1.目标选择   2.攻击准备  3. 开始攻击  4.受击特效与动作  5.伤害结算、飙血浮动条、血条减少。  6.技能打断

       注意。技能打断,可配置该技能在XXX秒--XXX秒之间可被打断。

       就不详细解释了,具体实现看代码,有注释。

   [mw_shl_code=applescript,true]public abstract class SkillBase 
{
    //技能状态
    public SkillState State { get; protected set; }
    public int SkillID { get { return dataVo == null ? 0 : dataVo.ID; } }
    public SkillDataVo dataVo { get; protected set; }

//特效
    protected GameObject effect;
    protected bool ifInitEffect = false; //是否已经播放了特效
    protected float effectBeginTime;
    protected float effectTime = 5f;     //特效时长

//伤害
    protected bool damaged = false;     //是否已经计算了伤害

//动画
    protected float curAnimalLength;//当前动画时长
    protected string animalName;
    protected float CurCd;
    protected SpriteController owner;
    protected float timer;

//回收动作
    protected bool IfUseActionReturn;
    protected float ActionReturnTime;

//攻击目标、角度范围、距离
    protected bool InForward(Transform trans, float _angle, float _dis)
    {
        if (null == trans)
        {
            return false;
        }

// 获得从当前Obj到目标Obj的方向,然后求和当前Obj的朝向夹角。
        Vector2 tarPos = new Vector2(trans.position.x, trans.position.z);
        Vector2 myPos = new Vector2(owner.transform.position.x, owner.transform.position.z);
        Vector2 mydir = new Vector2(owner.transform.forward.x, owner.transform.forward.z);
        Vector2 dir = tarPos - myPos;
        float angle = Vector2.Angle(mydir.normalized, dir.normalized);

if (angle < _angle / 2f)
        {

float toPosDis = Vector2.Distance(tarPos, myPos);
            if (toPosDis <= _dis)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        return false;
    }

public SkillBase(SpriteController obj, int skillID)
    {
        State = SkillState.None;
        this.owner = obj;
        this.CurCd = 0f;

dataVo = ConfigDataManager.GetSkillDataByID(skillID);
        if (owner.ActionMng != null && owner.ActionMng.TryGetAnimationLength(dataVo.actionName, out curAnimalLength))
        {
            //curAnimalLength -= 0f;
        }
        else
            curAnimalLength = 1f;

if (dataVo.BufferID.Length > 0)
        {
            dataVo.bufferEntity = new BufferDataVo[dataVo.BufferID.Length];
            for (int i = 0; i < dataVo.bufferEntity.Length; i++)
            {
                dataVo.bufferEntity = ConfigDataManager.GetConfigBufferData(dataVo.BufferID);
            }
        }
        animalName = dataVo.actionName;

//加载特效
        GameObject effectPre = LoadCache.LoadEffect(dataVo.effectName);
        if (effectPre != null)
        {
            effect = GameObject.Instantiate(effectPre) as GameObject;
            effect.SetActive(false);
        }

}

//  Interrupts
    virtual public void SetInterrupts() { State = SkillState.Interrupts; }

virtual public void ProcessBuffer(int index) {  }

virtual public bool IsCanInterrupts() 
    {
        if (State == SkillState.None)
            return true;

if (dataVo.minInterrupt != -1 && timer <= dataVo.minInterrupt)
            return true;

if (dataVo.maxInterrupt != -1 && timer >= dataVo.maxInterrupt)
            return true;

return false;
    }

virtual public void Execute()  
    {
        switch (State)
        {
            case SkillState.Start:
                break;
            case SkillState.Execution:
                break;
            case SkillState.Interrupts:
                break;
            case SkillState.Finish:
                break;
        }
    
    }

virtual public void Begin()
    {
        State = SkillState.Start;
    }

//这是一个模
    virtual public void DoUpdate() 
    {
        if (State == SkillState.None)
        {
            return;
        }

//  if (owner.mAIState == AIState.Dead)
         //   return;

Execute();
        CalcCd();
    }

public bool IsCanUse()
    {
        return State == SkillState.None;
    }

//CD计时
    public void CalcCd()
    {
        CurCd += RealTime.deltaTime;
        if ( CurCd >= dataVo.CD)
        {
            CurCd = 0f;
        }
    }

}[/mw_shl_code]

我们编写了一个超类,规定了技能的实现过程和方式、以及保存了技能的公有信息。
然后我们实现一个子类,能涵盖绝大部分的技能。

[mw_shl_code=applescript,true]public class Skill_Default : SkillBase 
{

private bool isMove;

SkillEzMoveData moveData;

Vector3 moveDir;

public Skill_Default(SpriteController obj, int skillID)
        : base(obj, skillID)
    {
    }

//遍历场景所有怪物
    void ForALLEnmy()
    {
        Dictionary<long, SpriteController> dic = BattlerDataManager.Instance.DicMonsters;
        //List<long> tmpList = new List<long>();
        foreach (SpriteController controller in dic.Values)
        {
            if (controller.mAIState == AIState.Dead)

continue;

//技能的伤害判断和处理
            bool inforward = InForward(controller.transform, dataVo.attackFanAngle, dataVo.attackFanRange);
            if (inforward)
            {
                int damageValue = dataVo.harm;
                owner.AttackTo(controller, damageValue);
Util.CallMethod("FightingPanel", "UpdateHeroHpMp", BattlerDataManager.Instance.SelfPlayer.SpiritVO.CurHp, BattlerDataManager.Instance.SelfPlayer.SpiritVO.CurMp);   //刷新角色血条

//            if (BattlerDataManager.Instance.SelfPlayer.mAIState  == AIState.Dead)
                //            {
                //                //玩家死亡
                //
                //            }
                if (BattlerDataManager.Instance.SelfPlayer.SpiritVO.CurHp <= 0)
                {
                    //玩家死亡
                    // Util.CallMethod("FightingPanel", "Lose");
                }
            }
        }
    }

public override void Execute()
    {

switch (State)
        {
            case SkillState.Start:
                moveDir = owner.MoveToPostion; 
                timer = 0f;
                effectBeginTime = 0;
                owner.MoveMng.StopMove();
                isMove = false;
               // IfUseActionReturn = false;
                damaged = false;
                ifInitEffect = false;
                //执行
                owner.mAIState = AIState.Attack;
                owner.ActionMng.PlayAnimation(animalName);
                State = SkillState.Execution;

Debug.Log("skill ID "+dataVo.ID);

break;
            case SkillState.Interrupts:
                {
                    Debug.Log("被打断");
                    State = SkillState.None;
                }
                break;
            case SkillState.Execution:
                {
                    timer += Time.deltaTime;

//触发伤害
                    if (!damaged && timer > dataVo.damageTime)
                    {
                        damaged = true;
                        //伤害结算
                        ForALLEnmy();
                    }

//触发特效
                    if (!ifInitEffect && timer > dataVo.fxStartTime)
                    {
                        if (effect != null)
                        {
                            effect.transform.position = owner.transform.position + new Vector3(0, 0.5f, 0)+owner.transform.forward*2;
                            effect.transform.rotation = owner.transform.rotation;
                            effect.SetActive(false);
                            effect.SetActive(true);
                        }

ifInitEffect = true;
                    }

//动画播放结束,并且触发了特效,触发了伤害
                    if (timer >= curAnimalLength && damaged && ifInitEffect)
                    {
                        State = SkillState.Finish;
                    }
                    
                }
            break;

case SkillState.Finish:
                {
                    Debug.Log("Finish");
  if (effect != null)
   effect.SetActive(false);
                    owner.mAIState = AIState.Idle;
                    State = SkillState.None;

}
                break;
        }

}
}
[/mw_shl_code]

有注释的情况下,应该不难看懂,抛砖引玉。

转载于:https://www.cnblogs.com/sundayofit/p/7995474.html

【ARPG/MOBA类游戏游戏系列】技能系统设计相关推荐

  1. Unity3D 大型游戏 MOBA类手机游戏 部分重点 登陆过程(17)

    原文链接http://blog.csdn.net/u013108312/article/details/78574139 支付宝捐赠 1.ResourceManager 这个是我们进入的第一个游戏场景 ...

  2. Unity3D 大型游戏 MOBA类手机游戏 状态机在游戏中的应用(18)

    本文固定链接 http://blog.csdn.net/u013108312/article/details/78824724 状态机在游戏中应用还是比较广泛的,在我以前博客中关于游戏框架中有介绍,感 ...

  3. 关于类DOTA游戏多样化技能系统的设计思考

    在游戏里,每一个人物都有很多的技能.像DOTA,英雄联盟一样,技能也不都是单一的直线判断,而是有很多的花样.这类游戏的技能系统是如何设计的呢? 这里想从自动机的角度来抽象这个问题,以期得到一个更泛化的 ...

  4. buff系统 游戏中_游戏中的技能如何而来? 为ARPG设计一个好用的BUFF系统

    游戏中有宏大的场景地图,丰富的游戏剧情,逼真的人物角色.但要让角色(职业)炫酷起来,还是要靠各个职业的技能来烘托.技能系统,根据游戏类型不同而会有不同,ARPG.回合类RPG.SLG类各个游戏都有技能 ...

  5. 游戏中的技能如何而来? 为ARPG设计一个好用的BUFF系统

    转自:游戏中的技能如何而来? 为ARPG设计一个好用的BUFF系统 - GameRes游资网 游戏中有宏大的场景地图,丰富的游戏剧情,逼真的人物角色.但要让角色(职业)炫酷起来,还是要靠各个职业的技能 ...

  6. 游戏美术干货:各大MOBA类游戏视觉包装设计解析

    MOBA英文全称为Multiplayer Online Battle Arena Games,意为多人联机在线竞技游戏.但是与CS等游戏又明显不同,Moba广泛使用于Dota类游戏,是作为类Dota的 ...

  7. 谈一款MOBA类游戏《码神联盟》的服务端架构设计与实现 (转载)

    原文链接 一.前言 <码神联盟>是一款为技术人做的开源情怀游戏,每一种编程语言都是一位英雄.客户端和服务端均使用C#开发,客户端使用,数据库使用MySQL.这个MOBA类游戏是笔者在学习时 ...

  8. 游戏服务器技能系统,MMORPG游戏服务器技能系统设计【上篇】 - 踏踏实实,认真工作 - CSDN博客...

    MMORPG游戏服务器技能系统设计[上篇] 收藏 本文主要从一个程序员的角度阐述一下mmorpg服务器技能系统的程序框架设计,最近在做这个,就当做一个总结吧,其中某些概念可能没有解释清楚,欢迎大家拍砖 ...

  9. 【Unity3D插件】uMOBA插件分享《Moba类游戏框架插件》

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 QQ群:1040082875 一.前言 今天介绍一款MOBA游戏的插件,已经有一个雏形了,可以作为开发的模 ...

最新文章

  1. 微软python在线学习_微软再推免费在线 Python 教程,面向数据科学和机器学习初学者...
  2. 玩转花式截图、录屏——FastStoneCapture使用指南
  3. python/pandas数据分析(十五)-聚合与分组运算实例
  4. Win32 API之Setlocale函数配置地域化信息函数
  5. 亿级流量电商详情页系统实战:缓存架构+高可用服务架构+微服务架构
  6. redis——实战关注
  7. python中concat的用法_python pandas concat用法及代码示例
  8. Transformer原理解析——一种Open AI和DeepMind都在用的神经网络架构
  9. mysql查询未讲课教师_经典教师 学生 成绩sql面试题再次来袭3(附答案)
  10. 这些屏保让你的 Mac 闲置时也能变得美观实用
  11. 短视频剪辑APP开发快速开发
  12. neu1482 2014辽宁省赛Picking Cabbage(状态压缩)
  13. 唐僧团队要裁员,你会裁谁?
  14. C语言中的光标定位函数
  15. Simscape物理网络建模的基本原理
  16. 如何快速定位接口响应慢问题
  17. LevelDb(二):LevelDb整体架构
  18. Spring集成Hibernate5_03-HibernateDaoSupport
  19. 产品经理(PM)和产品负责人(PO)的区别
  20. 欧冠超级计算机,超级计算机预测欧冠决赛:红军65%概率夺冠 萨拉赫最可能进球...

热门文章

  1. (一)【Matlab】Matlab基础知识
  2. Go 编程模式:k8s Visitor 模式
  3. Dubbo分布式日志追踪
  4. Android触摸屏驱动屏幕翻转
  5. HDMI2.1 4x2 矩阵解决方案:NUVOTON/新唐 KM864807 配MCU M032SIAAE
  6. phpstorm相关问题(不断更新)
  7. PL/SQL根据时间进行查询
  8. 拟态UI4.0-个人主页【完全开源】
  9. 数据结构---模式匹配算法
  10. AMBA AHB面试题连载(一)