Unity 贝塞尔曲线制作迁徙图

举报
CoderZ1010 发表于 2022/09/25 06:51:16 2022/09/25
【摘要】 效果图:  实现该效果图所需的知识点: 1.贝塞尔曲线 贝塞尔曲线是图形学中非常重要的参数曲线,在此不做详细介绍,这里我们用到的是二次方公式: using UnityEngine;using System.Collections.Generic; namespace SK.Framework{ publi...

效果图:

 实现该效果图所需的知识点:

1.贝塞尔曲线

贝塞尔曲线是图形学中非常重要的参数曲线,在此不做详细介绍,这里我们用到的是二次方公式:


  
  1. using UnityEngine;
  2. using System.Collections.Generic;
  3. namespace SK.Framework
  4. {
  5. public static class Vector3Extension
  6. {
  7. /// <summary>
  8. /// 生成贝塞尔曲线
  9. /// </summary>
  10. /// <param name="self">控制点</param>
  11. /// <param name="startPoint">贝塞尔曲线起点</param>
  12. /// <param name="endPoint">贝塞尔曲线终点</param>
  13. /// <param name="count">贝塞尔曲线点个数</param>
  14. /// <returns>组成贝塞尔曲线的点集合</returns>
  15. public static Vector3[] GenerateBeizer(this Vector3 self, Vector3 startPoint, Vector3 endPoint, int count)
  16. {
  17. Vector3[] retValue = new Vector3[count];
  18. for (int i = 1; i <= count; i++)
  19. {
  20. float t = i / (float)count;
  21. float u = 1 - t;
  22. float tt = Mathf.Pow(t, 2);
  23. float uu = Mathf.Pow(u, 2);
  24. Vector3 point = uu * startPoint;
  25. point += 2 * u * t * self;
  26. point += tt * endPoint;
  27. retValue[i - 1] = point;
  28. }
  29. return retValue;
  30. }
  31. }
  32. }

2.LineRenderer光线渲染器

LineRenderer在Unity中应用于线段的渲染,通过设置线段各个点的位置实现线段的绘制。


  
  1. using UnityEngine;
  2. using SK.Framework;
  3. public class Foo : MonoBehaviour
  4. {
  5. private void Start()
  6. {
  7. //通过起点(0,0,0)、控制点(0,7,5)、终点(0,0,10)生成贝塞尔曲线各点
  8. Vector3[] points = new Vector3(0f, 7f, 5f).GenerateBeizer(Vector3.zero, new Vector3(0f, 0f, 10f), 100);
  9. gameObject.AddComponent<LineRenderer>()
  10. //设置材质
  11. .SetMaterial(Resources.Load<Material>("Arrow"))
  12. //设置线段点个数
  13. .SetPositionCount(points.Length)
  14. //设置线段各点
  15. .SetLinePositions(points)
  16. //设置贴图为平铺模式
  17. .SetTextureMode(LineTextureMode.Tile)
  18. //设置起始宽度
  19. .SetStartWidth(.5f)
  20. //设置结束宽度
  21. .SetEndWidth(.5f);
  22. }
  23. }

上述代码中用到对LineRenderer类的拓展函数


  
  1. using UnityEngine;
  2. namespace SK.Framework
  3. {
  4. /// <summary>
  5. /// 光线渲染器相关拓展
  6. /// </summary>
  7. public static class LineRenderExtension
  8. {
  9. /// <summary>
  10. /// 设置起始宽度
  11. /// </summary>
  12. /// <param name="self">光线渲染器</param>
  13. /// <param name="width">起始宽度</param>
  14. /// <returns>光线渲染器</returns>
  15. public static LineRenderer SetStartWidth(this LineRenderer self, float width)
  16. {
  17. self.startWidth = width;
  18. return self;
  19. }
  20. /// <summary>
  21. /// 设置结束宽度
  22. /// </summary>
  23. /// <param name="self">光线渲染器</param>
  24. /// <param name="width">结束宽度</param>
  25. /// <returns>光线渲染器</returns>
  26. public static LineRenderer SetEndWidth(this LineRenderer self, float width)
  27. {
  28. self.endWidth = width;
  29. return self;
  30. }
  31. /// <summary>
  32. /// 设置起始颜色
  33. /// </summary>
  34. /// <param name="self">光线渲染器</param>
  35. /// <param name="color">起始颜色</param>
  36. /// <returns>光线渲染器</returns>
  37. public static LineRenderer SetStartColor(this LineRenderer self, Color color)
  38. {
  39. self.startColor = color;
  40. return self;
  41. }
  42. /// <summary>
  43. /// 设置结束颜色
  44. /// </summary>
  45. /// <param name="self">光线渲染器</param>
  46. /// <param name="color">结束颜色</param>
  47. /// <returns>光线渲染器</returns>
  48. public static LineRenderer SetEndColor(this LineRenderer self, Color color)
  49. {
  50. self.endColor = color;
  51. return self;
  52. }
  53. /// <summary>
  54. /// 设置点个数
  55. /// </summary>
  56. /// <param name="self">光线渲染器</param>
  57. /// <param name="count">点个数</param>
  58. /// <returns>光线渲染器</returns>
  59. public static LineRenderer SetPositionCount(this LineRenderer self, int count)
  60. {
  61. self.positionCount = count;
  62. return self;
  63. }
  64. /// <summary>
  65. /// 设置点位置
  66. /// </summary>
  67. /// <param name="self">光线渲染器</param>
  68. /// <param name="index">索引</param>
  69. /// <param name="position">位置</param>
  70. /// <returns>光线渲染器</returns>
  71. public static LineRenderer SetLinePosition(this LineRenderer self, int index, Vector3 position)
  72. {
  73. self.SetPosition(index, position);
  74. return self;
  75. }
  76. /// <summary>
  77. /// 设置点位置
  78. /// </summary>
  79. /// <param name="self">光线渲染器</param>
  80. /// <param name="positions">位置数组</param>
  81. /// <returns>光线渲染器</returns>
  82. public static LineRenderer SetLinePositions(this LineRenderer self, Vector3[] positions)
  83. {
  84. for (int i = 0; i < positions.Length; i++)
  85. {
  86. self.SetPosition(i, positions[i]);
  87. }
  88. return self;
  89. }
  90. /// <summary>
  91. /// 设置是否循环(终点是否连接起点)
  92. /// </summary>
  93. /// <param name="self">光线渲染器</param>
  94. /// <param name="loop">是否循环</param>
  95. /// <returns>光线渲染器</returns>
  96. public static LineRenderer SetLoop(this LineRenderer self, bool loop)
  97. {
  98. self.loop = loop;
  99. return self;
  100. }
  101. /// <summary>
  102. /// 设置CornerVertices属性
  103. /// </summary>
  104. /// <param name="self">光线渲染器</param>
  105. /// <param name="cornerVertices">conner vertices</param>
  106. /// <returns>光线渲染器</returns>
  107. public static LineRenderer SetCornerVertices(this LineRenderer self, int cornerVertices)
  108. {
  109. self.numCornerVertices = cornerVertices;
  110. return self;
  111. }
  112. /// <summary>
  113. /// 设置EndCapVertices属性
  114. /// </summary>
  115. /// <param name="self">光线渲染器</param>
  116. /// <param name="endCapVertices">end cap vertices</param>
  117. /// <returns>光线渲染器</returns>
  118. public static LineRenderer SetEndCapVertices(this LineRenderer self, int endCapVertices)
  119. {
  120. self.numCapVertices = endCapVertices;
  121. return self;
  122. }
  123. /// <summary>
  124. /// 设置Alignment属性
  125. /// </summary>
  126. /// <param name="self">光线渲染器</param>
  127. /// <param name="alignment">alignment</param>
  128. /// <returns>光线渲染器</returns>
  129. public static LineRenderer SetAlignment(this LineRenderer self, LineAlignment alignment)
  130. {
  131. self.alignment = alignment;
  132. return self;
  133. }
  134. /// <summary>
  135. /// 设置TextureMode
  136. /// </summary>
  137. /// <param name="self">光线渲染器</param>
  138. /// <param name="textureMode">texture mode</param>
  139. /// <returns>光线渲染器</returns>
  140. public static LineRenderer SetTextureMode(this LineRenderer self, LineTextureMode textureMode)
  141. {
  142. self.textureMode = textureMode;
  143. return self;
  144. }
  145. /// <summary>
  146. /// 设置材质球
  147. /// </summary>
  148. /// <param name="self">光线渲染器</param>
  149. /// <param name="material">材质球</param>
  150. /// <returns>光线渲染器</returns>
  151. public static LineRenderer SetMaterial(this LineRenderer self, Material material)
  152. {
  153. self.material = material;
  154. return self;
  155. }
  156. /// <summary>
  157. /// 烘焙网格
  158. /// </summary>
  159. /// <param name="self">光线渲染器</param>
  160. /// <param name="mesh">网格</param>
  161. /// <returns>光线渲染器</returns>
  162. public static LineRenderer BakeMesh(this LineRenderer self, out Mesh mesh)
  163. {
  164. mesh = new Mesh();
  165. self.BakeMesh(mesh);
  166. return self;
  167. }
  168. }
  169. }

3.UV滚动

通过UV的滚动Shader实现箭头的移动,资源来源于他人博客:https://blog.csdn.net/u013354943/article/details/105414827/


  
  1. Shader "Custom/Arrow"
  2. {
  3. Properties
  4. {
  5. _MainTex ("Texture", 2D) = "white" {}
  6. _MSpeed("MoveSpeed", Range(1, 3)) = 2 //移动速度
  7. }
  8. SubShader
  9. {
  10. //贴图带透明通道 ,半透明效果设置如下:
  11. tags{"Queue" = "Transparent" "RenderType" = "Transparent" "IgnoreProjector" = "True"}
  12. LOD 100
  13. Blend SrcAlpha OneMinusSrcAlpha //Blend选值为: SrcAlpha 和1-SrcAlpha //也可测试为 DstColor SrcColor //one one
  14. Pass
  15. {
  16. Name "Simple"
  17. Cull off //双面
  18. CGPROGRAM
  19. #pragma vertex vert
  20. #pragma fragment frag
  21. // make fog work
  22. #pragma multi_compile_fog
  23. #include "UnityCG.cginc"
  24. struct appdata
  25. {
  26. float4 vertex : POSITION;
  27. float2 uv : TEXCOORD0;
  28. };
  29. struct v2f
  30. {
  31. float2 uv : TEXCOORD0;
  32. UNITY_FOG_COORDS(1)
  33. float4 vertex : SV_POSITION;
  34. };
  35. sampler2D _MainTex;
  36. float4 _MainTex_ST;
  37. float _MSpeed;
  38. v2f vert (appdata v)
  39. {
  40. v2f o;
  41. o.vertex = UnityObjectToClipPos(v.vertex);
  42. o.uv = TRANSFORM_TEX(v.uv, _MainTex);
  43. UNITY_TRANSFER_FOG(o,o.vertex);
  44. return o;
  45. }
  46. half4 frag(v2f i) : SV_Target
  47. {
  48. float2 uv = float2(i.uv.x - _MSpeed * _Time.y,i.uv.y); //箭头移动的计算
  49. // sample the texture
  50. fixed4 col = tex2D(_MainTex, uv);
  51. // apply fog
  52. UNITY_APPLY_FOG(i.fogCoord, col);
  53. return col;
  54. }
  55. ENDCG
  56. }
  57. }
  58. }

最后通过该Shader创建材质Arrow放于Resources文件夹,创建物体挂载Foo脚本运行即可。

文章来源: coderz.blog.csdn.net,作者:CoderZ1010,版权归原作者所有,如需转载,请联系作者。

原文链接:coderz.blog.csdn.net/article/details/120482944

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。