笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,国家专利发明人;已出版书籍:《手把手教你架构3D游戏引擎》电子工业出版社和《Unity3D实战核心技术详解》电子工业出版社等。

本篇文章主要是针对我在CSDN做的《算法与游戏实战技术》视频讲座中即将分享的刀光拖尾算法实现的技术文章,详情可以观看视频教程。

刀光拖尾的实现方式主要有两种:一种是美术使用MAX工具制作的特效实现的,也就是美术根据动作调的特效,这个特效是不跟随动作的,只是角色做动作时播放一下特效而已,按照这种方式实现的特效扩展起来非常麻烦,动作只要改动,对应的特效也随之改动,效果如下图所示:

另一种方式是使用曲线插值实现的,它是获取到动作取样点然后带入曲线公式进行插值处理,这种实现方式可以不拘于动作的表现,

直接用代码动态去绘制的,它是跟随动作一起运动的,纹理贴图可以随意更换,而且更易于扩展,效果非常好,当然也可以不用插值实现

,直接通过采样点进行动态绘制,效果如下所示:

笔者以前做端游时,实现过刀光拖尾算法,当时在游戏公司使用的游戏引擎还不完善,很多功能都需要去开发或者完善。引擎的刀光拖尾算法也

需要完成,笔者负责实现刀光的拖尾算法,刚开始我选择的插值算法是贝塞尔曲线,结果插值的效果感觉不很理想,当然使用贝塞尔曲线也是

可以解决问题的,最终选择了B样条曲线插值。下面把我当时实现思路给读者解释一下:角色拿着武器在挥动的过程中是通过动作取样函数获取

到武器挥动时的一系列点。这些点作为关键点带入B样条曲线公式中,关键点之间可以等分成10段或者是多段,这样可以让曲线更加平滑了。

另外要实现刀光的淡入淡出效果,动作取样的关键点可以通过时间控制其产生和消失,这个是跟随动作实现的。

下面介绍一下,使用Unity实现的刀光拖尾,网上也有相关的资料,该拖尾的实现方式并没有使用线性插值,只是将取样点连成三角形面片

然后将材质赋到三角面片上,再根据时间控制其销毁。代码实现的主要思路是先把取样点存入到列表中,再根据这些取样点绘制成三角面片。

最后根据时间对其做淡入淡出效果,先给读者展示的函数是将取样点添加到List表中,函数如下所示:

     public void Itterate(float itterateTime) 
     { position = transform.position;now = itterateTime;// Add a new trail sectionif (sections.Count == 0 || (sections[0].point - position).sqrMagnitude > minDistance * minDistance) {TronTrailSection section = new TronTrailSection();section.point = position;if (alwaysUp)section.upDir = Vector3.up;elsesection.upDir = transform.TransformDirection(Vector3.up);section.time = now;sections.Insert(0, section);}}

接下来就是动作取样了,动作取样是关键点的获取,函数如下所示:

 void RunAnimations (){//if (t > 0) {eulerAngles = transform.eulerAngles;position = transform.position;while (tempT < t) {tempT += animationIncrement;for (int i = 0; i < fadingStates.Count; i++) {if (FadeOutAnimation (fadingStates[i], animationIncrement)) {fadingStates.RemoveAt (i);i--;}}if (currentState != null)FadeInCurrentState (animationIncrement);//m = tempT / t;transform.eulerAngles = new Vector3(Mathf.LerpAngle(lastEulerAngles.x, eulerAngles.x, m),Mathf.LerpAngle(lastEulerAngles.y, eulerAngles.y, m),Mathf.LerpAngle(lastEulerAngles.z, eulerAngles.z, m));transform.position = Vector3.Lerp(lastPosition, position, m);//// ** Samples the animation at that moment//animation.Sample ();//// ** Adds the information to the WeaponTrail//for (int j = 0; j < trails.Count; j++) {if (trails[j].time > 0) {trails[j].Itterate (Time.time - t + tempT);} else {trails[j].ClearTrail ();}}}//// ** End of loop//tempT -= t;//// ** Sets the position and rotation to what they were originallytransform.position = position;transform.eulerAngles = eulerAngles;lastPosition = position;lastEulerAngles = eulerAngles;//// ** Finally creates the meshes for the WeaponTrails (one per frame)//for (int j = 0; j < trails.Count; j++) {if (trails[j].time > 0) {trails[j].UpdateTrail (Time.time, t);}}}}

取样点完成后,开始更新刀光拖尾函数了,函数代码如下所示:

 public void UpdateTrail(float currentTime, float deltaTime) 
{ 
 // ** call once a frame **// Rebuild the mesh   mesh.Clear();//// Remove old sectionswhile (sections.Count > 0 && currentTime > sections[sections.Count - 1].time + time) {sections.RemoveAt(sections.Count - 1);}// We need at least 2 sections to create the lineif (sections.Count < 2)return;//vertices = new Vector3[sections.Count * 2];colors = new Color[sections.Count * 2];uv = new Vector2[sections.Count * 2];//currentSection = sections[0];//// Use matrix instead of transform.TransformPoint for performance reasonslocalSpaceTransform = transform.worldToLocalMatrix;// Generate vertex, uv and colorsfor (var i = 0; i < sections.Count; i++) {//currentSection = sections[i];// Calculate u for texture uv and color interpolationfloat u = 0.0f;if (i != 0)u = Mathf.Clamp01((currentTime - currentSection.time) / time);//// Calculate upwards directionVector3 upDir = currentSection.upDir;// Generate verticesvertices[i * 2 + 0] = localSpaceTransform.MultiplyPoint(currentSection.point);vertices[i * 2 + 1] = localSpaceTransform.MultiplyPoint(currentSection.point + upDir * height);uv[i * 2 + 0] = new Vector2(u, 0);uv[i * 2 + 1] = new Vector2(u, 1);// fade colors out over timeColor interpolatedColor = Color.Lerp(startColor, endColor, u);colors[i * 2 + 0] = interpolatedColor;colors[i * 2 + 1] = interpolatedColor;}// Generate triangles indicesint[] triangles = new int[(sections.Count - 1) * 2 * 3];for (int i = 0; i < triangles.Length / 6; i++) {triangles[i * 6 + 0] = i * 2;triangles[i * 6 + 1] = i * 2 + 1;triangles[i * 6 + 2] = i * 2 + 2;triangles[i * 6 + 3] = i * 2 + 2;triangles[i * 6 + 4] = i * 2 + 1;triangles[i * 6 + 5] = i * 2 + 3;}// Assign to mesh    mesh.vertices = vertices;mesh.colors = colors;mesh.uv = uv;mesh.triangles = triangles;//// Tween to the desired time//if (time > desiredTime){time -= deltaTime*timeTransitionSpeed;if(time <= desiredTime) time = desiredTime;} else if (time < desiredTime){time += deltaTime*timeTransitionSpeed;if(time >= desiredTime) time = desiredTime;}}

动作的取样点生成网格效果展示如下所示:

在网格贴上材质后实现的效果如下所示:

拖尾算法实现方式不用曲线插值一样可以实现出来,当然实现插值的方式也是可以实现的。

算法与游戏实战技术之刀光拖尾实现相关推荐

  1. 算法与游戏实战技术-姜雪伟-专题视频课程

    算法与游戏实战技术-5404人已学习 课程介绍         游戏开发者需要具有能解决实际问题的能力也就是算法能力.这需要开发者能将算法与实际项目开发完美的结合起来.算法是支撑项目开发的灵魂,在游戏 ...

  2. Unity 刀光拖尾生成

    在游戏中,我们经常会看到角色挥动武器的时候,拖尾的效果,以及折射扭曲.在Unity开发中大家可以使用RPG Pocket插件或者其他的插件,在这里主要是给大家介绍一下其生成原理. 首先,在舞动刀的时候 ...

  3. UE4学习笔记(三)刀光拖尾的制作

    话不多说,先放成品图 进入正题. 第一步,创建一个材质,我这里名字取的[White]. 首先你得把材质改成面板中的数值改成这样,[半透明]是因为刀光就是比较透明的,不然就会遮挡人物.[无光照],是指由 ...

  4. cocos2d 用MotionStreak给骨骼动画的刀加拖尾(刀光拖尾)

    最近刚去公司工作,没有一点经验,真是苦逼,做一个demo,当骨骼动画(刀这个骨骼砍得时候能够出现拖尾效果,真是想破脑袋),经过不断的尝试,总结出了一个方法: 直接上代码: MotionStreak * ...

  5. [Unity学习笔记:FPS游戏制作(3)]子弹拖尾,碰撞与枪口火焰效果

    往期博客[Unity学习笔记:FPS游戏制作(2)] 发射子弹----(2021.6.20学习笔记) 文章目录 一,实现思路 二,粒子效果的实现 (1)子弹拖尾特效的实现 (2)枪口火焰特效的实现 ( ...

  6. Ogre的WeaponTrail (刀光)

    就是刀光拖尾效果,这个挺有意思,Ogre竟然单写了一个类来实现这个功能.名字叫做RibbonTrail. 不过这个类似乎并不太好用,实现的效果是从手握武器的位置沿相对衬的两个方向延伸出片,这样的话,如 ...

  7. Unity制作《水果忍者》刀光特效

    最近在学习Unity中的LineRenderer组件的时候,突发奇想,想到怎么实现水果忍者的刀光特效 制作起来并没有想象的那么难,只是想让其逼真起来的话需要一张好的材质贴,博主找了一张不是很完美的贴图 ...

  8. 排序算法在游戏中的应用,你确定你了解吗?(详细的图解带你实战)

    排序算法在游戏中的应用,你确定你了解吗?(详细的图解带你实战) 目录 排序算法在游戏中的应用,你确定你了解吗?(详细的图解带你实战) 1. 归并排序 1.1 作为一种典型的分而治之思想的算法应用,归并 ...

  9. swift语言实战晋级-第9章 游戏实战-跑酷熊猫-7-8 移动平台的算法

    原文:swift语言实战晋级-第9章 游戏实战-跑酷熊猫-7-8 移动平台的算法 在上个小节,我们完成了平台的产生.那么我们来实现一下让平台移动.平台的移动,我们只需要在平台工厂类中写好移动的方法,然 ...

最新文章

  1. oracle取本月最后一天是星期几_Oracle取得本月、本年第一天和最后一天
  2. 剑指offer(纪念版)读书笔记【实时更新】
  3. bzoj4773 负环
  4. MySQL优化:数据量很大,分页查询很慢,有什么优化方案?
  5. 51单片机智能小车循迹完整程序_电气与信息工程学院双创协会开展循迹小车培训...
  6. matlab考试试题,matlab-考试试题-
  7. Linux上开启TUN
  8. 笨办法学 Python · 续 练习 9:`sed`
  9. python学习(day1)初识入门
  10. 前端图表生成利器--ECharts推荐
  11. r语言 月度消费频次_R语言基础-数据分析及常见数据分析方法
  12. BAT机器学习面试1000题系列大集合整理(320)
  13. 【运动控制篇】(7)路径跟踪及组合动作方向
  14. 清明节出行客流 人山人海
  15. 汽车零部件行业PLM解决方案
  16. 2019年繁星屠龙1-8窍门_《倚天屠龙记》27年后,赵敏终于在元大都等到了41岁的林峰...
  17. 解决“你没有权限访问,请与网络管理员联系”
  18. 《裂变式创业》读书心得
  19. 我的2018---艰难的一年
  20. 计算机中imb二进制数,计算机基础知识总述.doc

热门文章

  1. 《疯狂的JAVA讲义》笔记-第8章集合
  2. 《廖禹喝形取像图式 》三僚廖瑀寻穴总结 存世孤本 珍稀古籍欣赏
  3. anki用HTML代码批量,使用 JavaScript 操作 HTML 批量制作 Anki 卡片
  4. NCR推出带有二维条码识读功能的ATM机
  5. python学习面向对象Day11(P116~~126)
  6. 微信开放平台之第三方平台代公众号发起网页授权
  7. uImage烧写中出现“Loading: T T T T T T T T T T T T T T T T T T T T”时解决方法
  8. linux的添加网关 查看网关等信息
  9. python编程如何驱动机器人_python编程如何驱动机器人
  10. matlab求解速率方程,关于用Matlab求解3能级系统速率方程的困惑