ParadoxNotion-Slate学习笔记与拓展计划
前言
要准备开始把状态帧同步方案接入Moba项目了,其中比较重要的两部分是战斗系统的重构以及技能编辑器的适配,前者先不谈,内容多而细碎,后面会单独出文章整理说明。技能编辑器目前使用了是基于节点的行为树编辑器,说实话对于技能的配置与效果的预览并不友好,但不可否认的是其逻辑组织能力雀食优秀,为了弥补其短板,准备接入一个Timeline编辑器,我的选择是ParadoxNotion-Slate,理由是界面美观,可拓展性较好,源码注释详细简洁。
这篇文章就是梳理下Slate的架构以及技能编辑器的适配思路。
Slate版本:2.0.2
正文
基础架构
由表及里主要有CutsceneGroup,CutsceneTrack,ActionClip三层结构,三者都实现IDirectable接口
CutsceneGroup:包含多个CutsceneTrack与多个Section,其中Section被用于划分CutsceneTrack区域和快捷编辑
CutsceneTrack:包含多个ActionClip
ActionClip:一个具体的行为片段,例如播放一段动画,播放一个特效,移动一段距离
具体 ...
2021.7.9日记
最近见识了一些人的行为方式,并反思了自己有无类似会让别人产生不适的行为,故有此戒文。
愿自己满腹经纶时,仍能谦以待人,温如君子。
愿自己有所长进时,能乐于分享,不苍白炫耀。
愿自己与人交谈时,能设身处地,善于倾听。
愿自己被人批评时,能抓住本质,不欲盖弥彰,固步自封。
愿自己愠怒难耐时,能保持清醒,不恶语伤人。
愿自己烦于生活时,能想到生活的美好,变得更加乐观向上。
愿自己烦于自己时,能正视自己,与自己和解。
愿自己半间不界时,能坚持不懈,努力达成目标。
愿自己短于他人时,能不吝赞美,互相进步。
愿自己走出半生时,归来仍是少年。
使用Shader实现LOL血条分隔线效果
前言
马上要去上班了,这阵子雀食是啥都不想干,技能编辑器接Slate又费脑子,索性整点小活吧,想起来当前Moba项目的血条间隔还是用虚拟列表做的,性能捉急,准备用Shader重新实现一下。
正文
所谓血条间隔就是在血条中使用分割线来帮助玩家快速计算自身生命值的,个人认为是一个非常优秀的设计,比如下面的大塔姆,玩家可以在一秒钟之内就可以知道其还有360左右的生命值
因为血条间隔宽度和数量与战斗中英雄最大生命值有关,所以根据战斗中的英雄最大血量计算得出每个血条间隔的宽度值,传入Shader进行计算绘制,所以需要进行一些换算,现有以下条件
血条宽度为107px
英雄最大生命值为3700
血条每格代表100生命值
首先是血条间隔的数量,为 3700/100 = 37 个,而这37个间隔要均匀分布在107px中,所以每个间隔的宽度为100 / 37 = 2.70,注意,是100,不是107,因为我们绘制血条间隔与血条UI自身的宽度完全无关,根本原因是我们在Shader中会使用uv.x * 100的方式来构建一个虚拟的血条,所以不论英雄最大生命值是多少,都要除100。
123456Pe ...
万用技能指示器
前言
这几天研究了下 技能指示器 发现作者好久没更新了,而且由于其用到了Projector组件,无法在URP管线下正常工作,所以我把它的Shader稍微改了下,接口之类的也改了下,如果需要技能指示器贴合地形的话可以接入 https://github.com/ColinLeung-NiloCat/UnityURPUnlitScreenSpaceDecalShader ,本仓库 也给了一个示例。
使用此指示器需要Odin插件,因为需要在编辑器编辑指示器的大小,实时预览,用到了OnValueChanged特性。
预览图如下
功能
非指向性
指向性(无范围提示)
指向性(有范围提示)
区域选择性
可变角扇形
状态指示器
贴花
使用说明
指示器基类中重要字段,支持运行时使用其对应属性实时更改。
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717 ...
(译)C#的反射为什么慢?怎么加快反射调用?
前言
我们知道C#反射慢,但是当中很多人不知道它为什么慢,并且如何解决反射调用方法慢的问题呢? 这篇文章会给你一个答案。本文译自:https://mattwarren.org/2016/12/14/Why-is-Reflection-slow/
C#的反射为什么慢
反射的设计初衷
在运行时非常快的访问我们所需要的代码的信息。
在编译时非常直接的访问生成代码所需的信息。
垃圾回收器/计算堆栈能够在不对程序加锁/分配内存的情况下访问必要的信息。
能极大减少一次性需要加载的类型数量。
能极大减少给定类型加载时所需要加载的额外类型数目。
类型系统数据结构必须在NGEN映像中是可存储的。
我们可以看到,它只强调了最少依赖加载,并没有说我们可以直接从元数据获取所有CLR数据类型。也没有说所有的反射用法都是快的,只是说反射获取一些信息很快。 MethodTable的数据被分为“热”和“冷”两种数据结构来提升工作效率和缓存利用率,MethodTable本身只存储那些在程序稳定状态(是否可以翻译成一般运行时?)下被需求的“热”数据。EEClass储存那些只在类型加载时,JIT编译时,反射时需 ...
基于行为树的MOBA技能系统:动画系统
动画系统已有重构版本,可前往 朝花夕拾·动画系统的重构 进行查看
前言
基于行为树的Moba技能系统系列文章总目录:https://www.lfzxb.top/nkgmoba-totaltabs/
这一篇来谈谈动画系统部分,别的先不说,先给大伙来个开幕雷击
相信很多读者都受过这个蜘蛛网的荼毒+迫害,事实上我并不是很能知道Unity出这个蜘蛛网有什么用,折磨我们吗?
其实我们想一想,我们真的需要这种可视化吗?
我对于这个问题的答案是否定的,在游戏开发中我们会有自己的状态系统,而动画系统往往就是与我们自己的状态系统相绑定的,根据状态来播放相应的动画,所以我们的需求就是切换状态然后播放动画,不需要知道,也不需要想象哪个动画可以切换到另一个动画,哪个不可以,这都是由我们状态系统控制的,所以完全不需要这个可视化工具,也不需要每次都一大堆的SetXXX,只需要几个能用的API就行。
所以众多开发者也是不堪其辱,干脆不用这个蜘蛛网方案,退而求其次,使用Animation自己控制播放,但是这样的话就没有办法使用Animator的新功能,比如动画重定向、Blend Tree、Avatar Mas ...
基于行为树的MOBA技能系统:Buff系统
## 前言
基于行为树的Moba技能系统系列文章总目录:https://www.lfzxb.top/nkgmoba-totaltabs/
本篇文章主要讲一下Buff系统的设计。Buff系统是战斗系统中最为重要的一个部件,我们技能效果就是依靠Buff系统实现的,比如伤害,治疗,破甲,眩晕,护盾,斩杀等,也就是说一个技能真正的核心就是组成它的那些Buff,这一点其实在《可视化节点技能编辑器的制作》一文中的示例中有体现。
这就可以引申出一个“万物皆Buff”的思想,所有的行为/效果都可以用一个Buff来实现,常规的比如一个持续伤害Buff,特殊的比如一个播放特效Buff,往客户端同步数据Buff。
指导思想有了,并且经过《可视化节点技能编辑器的制作》文中Buff系统相关介绍,我们可以知道这种方式确实可行,那么具体怎么抽象出一个健壮的Buff系统就是我们需要考虑的事情了。
本文更多的是介绍Buff系统Runtime的架构设计,Editor的架构设计可从下图得知,更详细的内容在《可视化节点技能编辑器的制作》中:
正文
基类抽象
首先我们Runtime下的Buff需要有数据载体,用于记载此 ...
基于行为树的MOBA技能系统:碰撞系统
前言
基于行为树的Moba技能系统系列文章总目录:https://www.lfzxb.top/nkgmoba-totaltabs/
一些游戏中简单的碰撞系统,可能就是手写几个圆形,矩形,扇形就够用了,但是Moba类游戏很多技能碰撞体是畸形的,比如派克的R,男枪的Q,R等都是不规则的,所以我们需要一个稳健的物理库来支持这些,自己处理碰撞体顶点数据,创建碰撞体到物理世界中,因为游戏类型原因,我选择了Box2D:https://github.com/erincatto/Box2D,对于FPS游戏,只有Bullet(3D物理库):https://github.com/bulletphysics/bullet3 可选,这里就不多说了。
由于碰撞系统本身需要和技能系统产生非常紧密的联系,所以涉及到的内容也会比较多,主要包括
Box2D物理库介绍
Box2D碰撞体编辑器拓展,负责制作碰撞体和导出碰撞体数据:https://www.lfzxb.top/box2d-unityvistualeditor/
Box2D碰撞关系编辑器拓展,负责维护碰撞体之间的碰撞关系,并自动生成代码:https://w ...
基于行为树的MOBA技能系统:数值系统
前言
基于行为树的Moba技能系统系列文章总目录:https://www.lfzxb.top/nkgmoba-totaltabs/
在战斗系统中数值系统也是一个核心的系统,当今主流做法是将一个属性分为两个相关联的属性,比如最大生命值就会被分为基础最大生命值 + 额外最大生命值两者之和
基础最大生命值一般而言是初始恒定的
额外最大生命值一般而言是受英雄自身属性,等级,装备,Buff影响的,比如对于力量英雄而言+1力量会为英雄提供20最大生命值,提升一级会为英雄提升80最大生命值,一件装备会提升20%额外最大生命值
其他的例如攻击力,移速,魔法值,法强,护甲,魔抗等都是如此。
此外,还有常见的伤害处理,减速处理等间接影响属性的类型。
分类
战斗数据处理主要分为两大类
直接作用于属性上,例如最大生命值,魔法恢复速度,移速等
间接作用于属性上,例如伤害,减速,魔法消耗等
并且直接作用复杂度 < 间接作用复杂度
由于间接作用类型的存在,我们就不能用诸如
final = ((base + add) * (100 + pct) / 100);
的形式来处理属性变更了,我们需要找到 ...
基于行为树的MOBA技能系统:技能系统与网络同步
前言
基于行为树的Moba技能系统系列文章总目录:https://www.lfzxb.top/nkgmoba-totaltabs/
从我个人的感受而言,如果说技能系统开发难度为7,那么网络同步的开发难度就是10,因为它的触手涉及技能系统方方面面,稍有不慎就会有可怕的连锁反应导致混乱。
包括守望先锋的三面分享,其中网络同步部分读起来最为吃力,断层的感觉最强,但越是这样,越能说明守望先锋网络同步方案的健壮性
对于本文内容的拓展延伸与具体实现,参见
基于行为树的MOBA技能系统:基于状态帧的战斗,技能编辑器与录像回放系统设计
基于行为树的MOBA技能系统:基于状态帧的战斗,技能编辑器与录像回放系统开发手札
本文大量内容参照了:《守望先锋》GDC2017技术分享精粹重制版总目录 中的文章
守望先锋网络同步总结
同步数据设计
感觉先说明一下网络同步环境和数据结构的设计比较容易理解一些
客户端和服务端都各自维护着整局游戏所有的实体和数据,差别就是客户端不负责逻辑计算,逻辑计算是服务器权威的,客户端要能从服务器发来的帧数据恢复到和服务器发送数据那一帧相同的世界状态
对于客户端来说,本地有 ...