ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

算法与游戏实战技术之刀光拖尾实现

2021-07-10 16:36:55  阅读:345  来源: 互联网

标签:Count 刀光 transform 算法 triangles time position sections 拖尾


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

算法与游戏实战技术之刀光拖尾实现

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

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

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

算法与游戏实战技术之刀光拖尾实现

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

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

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

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

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

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

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

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

[html] view plain copy

  1. public void Itterate(float itterateTime)

[html] view plain copy

  1. {

  2. position = transform.position;

  3. now = itterateTime;

  4. // Add a new trail section

  5. if (sections.Count == 0 || (sections[0].point - position).sqrMagnitude > minDistance * minDistance) {

  6. TronTrailSection section = new TronTrailSection();

  7. section.point = position;

  8. if (alwaysUp)

  9. section.upDir = Vector3.up;

  10. else

  11. section.upDir = transform.TransformDirection(Vector3.up);

  12. section.time = now;

  13. sections.Insert(0, section);

  14. }

  15. }

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

[html] view plain copy

  1. <spanstyle="white-space:pre"></span>void RunAnimations ()

  2. {

  3. //

  4. if (t > 0) {

  5. eulerAngles = transform.eulerAngles;

  6. position = transform.position;

  7. while (tempT < t) {

  8. tempT += animationIncrement;

  9. for (int i = 0; i <fadingStates.Count; i++) {

  10. if (FadeOutAnimation (fadingStates[i], animationIncrement)) {

  11. fadingStates.RemoveAt (i);

  12. i--;

  13. }

  14. }

  15. if (currentState != null)

  16. FadeInCurrentState (animationIncrement);

  17. //

  18. m = tempT / t;

  19. 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));

  20. transform.position = Vector3.Lerp(lastPosition, position, m);

  21. //

  22. // ** Samples the animation at that moment

  23. //

  24. animation.Sample ();

  25. //

  26. // ** Adds the information to the WeaponTrail

  27. //

  28. for (int j = 0; j <trails.Count; j++) {

  29. if (trails[j].time > 0) {

  30. trails[j].Itterate (Time.time - t + tempT);

  31. } else {

  32. trails[j].ClearTrail ();

  33. }

  34. }

  35. }

  36. //

  37. // ** End of loop

  38. //

  39. tempT -= t;

  40. //

  41. // ** Sets the position and rotation to what they were originally

  42. transform.position = position;

  43. transform.eulerAngles = eulerAngles;

  44. lastPosition = position;

  45. lastEulerAngles = eulerAngles;

  46. //

  47. // ** Finally creates the meshes for the WeaponTrails (one per frame)

  48. //

  49. for (int j = 0; j <trails.Count; j++) {

  50. if (trails[j].time > 0) {

  51. trails[j].UpdateTrail (Time.time, t);

  52. }

  53. }

  54. }

  55. }

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

[csharp] view plain copy

  1. publicvoid UpdateTrail(float currentTime, float deltaTime)

[csharp] view plain copy

  1. {

[csharp] view plain copy

  1. <span style="white-space:pre"> </span>// ** call once a frame **

  2. // Rebuild the mesh

  3. mesh.Clear();

  4. //

  5. // Remove old sections

  6. while (sections.Count > 0 && currentTime > sections[sections.Count - 1].time + time) {

  7. sections.RemoveAt(sections.Count - 1);

  8. }

  9. // We need at least 2 sections to create the line

  10. if (sections.Count < 2)

  11. return;

  12. //

  13. vertices = new Vector3[sections.Count * 2];

  14. colors = new Color[sections.Count * 2];

  15. uv = new Vector2[sections.Count * 2];

  16. //

  17. currentSection = sections[0];

  18. //

  19. // Use matrix instead of transform.TransformPoint for performance reasons

  20. localSpaceTransform = transform.worldToLocalMatrix;

  21. // Generate vertex, uv and colors

  22. for (var i = 0; i < sections.Count; i++) {

  23. //

  24. currentSection = sections[i];

  25. // Calculate u for texture uv and color interpolation

  26. float u = 0.0f;

  27. if (i != 0)

  28. u = Mathf.Clamp01((currentTime - currentSection.time) / time);

  29. //

  30. // Calculate upwards direction

  31. Vector3 upDir = currentSection.upDir;

  32. // Generate vertices

  33. vertices[i * 2 + 0] = localSpaceTransform.MultiplyPoint(currentSection.point);

  34. vertices[i * 2 + 1] = localSpaceTransform.MultiplyPoint(currentSection.point + upDir * height);

  35. uv[i * 2 + 0] = new Vector2(u, 0);

  36. uv[i * 2 + 1] = new Vector2(u, 1);

  37. // fade colors out over time

  38. Color interpolatedColor = Color.Lerp(startColor, endColor, u);

  39. colors[i * 2 + 0] = interpolatedColor;

  40. colors[i * 2 + 1] = interpolatedColor;

  41. }

  42. // Generate triangles indices

  43. int[] triangles = newint[(sections.Count - 1) * 2 * 3];

  44. for (int i = 0; i < triangles.Length / 6; i++) {

  45. triangles[i * 6 + 0] = i * 2;

  46. triangles[i * 6 + 1] = i * 2 + 1;

  47. triangles[i * 6 + 2] = i * 2 + 2;

  48. triangles[i * 6 + 3] = i * 2 + 2;

  49. triangles[i * 6 + 4] = i * 2 + 1;

  50. triangles[i * 6 + 5] = i * 2 + 3;

  51. }

  52. // Assign to mesh

  53. mesh.vertices = vertices;

  54. mesh.colors = colors;

  55. mesh.uv = uv;

  56. mesh.triangles = triangles;

  57. //

  58. // Tween to the desired time

  59. //

  60. if (time > desiredTime){

  61. time -= deltaTime*timeTransitionSpeed;

  62. if(time <= desiredTime) time = desiredTime;

  63. } elseif (time < desiredTime){

  64. time += deltaTime*timeTransitionSpeed;

  65. if(time >= desiredTime) time = desiredTime;

  66. }

  67. }

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

算法与游戏实战技术之刀光拖尾实现

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

算法与游戏实战技术之刀光拖尾实现

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

标签:Count,刀光,transform,算法,triangles,time,position,sections,拖尾
来源: https://www.cnblogs.com/booth666/p/14994050.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有