经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 软件/图像 » unity » 查看文章
unity 如何使用LineRenderer 动态划线
来源:jb51  时间:2021/4/12 15:42:24  对本文有异议

我就废话不多说了,大家还是直接看代码吧~

  1. private LineRenderer line1;
  2. //画线
  3. line1 = this.gameObject.AddComponent<LineRenderer>();
  4. //只有设置了材质 setColor才有作用
  5. line1.material = new Material(Shader.Find("Particles/Additive"));
  6. line1.SetVertexCount(2);//设置两点
  7. line1.SetColors(Color.yellow, Color.red); //设置直线颜色
  8. line1.SetWidth(5f, 10f);//设置直线宽度
  9. //设置指示线的起点和终点
  10. line1.SetPosition(0, A.transform.position);
  11. line1.SetPosition(1, B.transform.position);
  12. Destroy(this.gameObject.GetComponent<LineRenderer>());

补充:Unity LineRenderer绘制物体行走路线

我是用的角色控制器(Character Controller)+LineRenderer做的

下面是代码

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class PlayerTest : MonoBehaviour
  5. {
  6. public GameObject clone;//这是个空物体 只添加了一个LineRenderer组件
  7. public float speed = 5;
  8. public float jumpSpeed = 10f;
  9. public float luodi = 15;
  10. private Vector3 movePos = Vector3.zero;
  11. public CharacterController controller;
  12. private LineRenderer line;
  13. Vector3[] path;
  14. private float time = 0;
  15. List<Vector3> pos=new List<Vector3> ();
  16. void Awake()
  17. {
  18. path = pos.ToArray();//初始化
  19. line = clone.GetComponent<LineRenderer>();//获得该物体上的LineRender组件
  20. line.SetColors(Color.blue, Color.red);//设置颜色
  21. line.SetWidth(0.2f, 0.1f);//设置宽度
  22. }
  23. void Update()
  24. {
  25. time += Time.deltaTime;
  26. if (time>0.1)//每0.1秒绘制一次
  27. {
  28. time = 0;
  29. pos.Add(transform.position);//添加当前坐标进链表
  30. path = pos.ToArray();//转成数组
  31. }
  32. if (controller.isGrounded)//判断人物是否落地
  33. {
  34. movePos = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
  35. movePos = transform.TransformDirection(movePos);
  36. movePos *= speed;
  37. if (Input.GetButton("Jump")) {
  38. movePos.y = jumpSpeed;
  39. }
  40. }
  41. movePos.y -= luodi * Time.deltaTime;
  42. controller.Move(movePos * Time.deltaTime);
  43. if (path.Length!=0)//有数据时候再绘制
  44. {
  45. line.SetVertexCount(path.Length);//设置顶点数
  46. line.SetPositions(path);//设置顶点位置
  47. }
  48. }
  49. }

补充:Unity组件 — LineRenderer动态添加碰撞

基础知识:

选中要添加组件的gameObject,在Inspector面板,点击“Add Component”按钮,选中LineRenderer组件,添加。

cast Shadows : 蒙上阴影

Receive Shadows : 是否接受阴影

Dynamic Occludee : 是否动态遮罩

Materials 中的属性:

size : 材质球的数量

Element : 具体的材质球

Positions 中的属性:

size : 位置的数量

Element : 具体的位置

Use World Space : 是否使用世界坐标系,还是使用相对坐标系

Width : 线条的宽度

Color : 线条的颜色,注:如果没有赋值材质,无论怎样改变Color的值,颜色都不会有改变。

Corner Vertices : 可形成线条的圆角效果

End Cap Vertices : 影响线条的两端的圆角效果。

注:当line Renderer拥有了材质,可以通过修改Color来改变颜色。当时当修改了Color后,line的颜色没有改变,应该是Material和Color属性结合不好。将Material修改为Sprites/Default,Color的颜色就可以成功的显示在line上面了。

动态添加碰撞器(Polygon Collider2D)

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class MouseTrack : MonoBehaviour
  5. {
  6. /// <summary>
  7. /// 获取LineRenderer组件
  8. /// </summary>
  9. [Header("获得LineRenderer组件")]
  10. public LineRenderer lineRenderer;
  11. //获得鼠标跟踪位置
  12. private Vector3[] mouseTrackPositions = new Vector3[20];
  13. private Vector3 headPosition; //头位置
  14. private Vector3 lastPosition; //尾位置
  15. private int positionCount = 0; //位置计数
  16. [Header("设置多远距离记录一个位置")]
  17. public float distanceOfPositions = 0.01f;
  18. private bool firstMouseDown = false; //第一次鼠标点击
  19. private bool mouseDown = false; //鼠标点击
  20. PolygonCollider2D polygonCollider; //添加多边形碰撞
  21. void Start()
  22. {
  23. polygonCollider = gameObject.GetComponent<PolygonCollider2D>();
  24. }
  25. void Update()
  26. {
  27. //鼠标点击的时候
  28. if (Input.GetMouseButtonDown(0))
  29. {
  30. polygonCollider.enabled = true;
  31. lineRenderer.positionCount = 20;
  32. firstMouseDown = true;
  33. mouseDown = true;
  34. }
  35. if (Input.GetMouseButtonUp(0))
  36. {
  37. mouseDown = false;
  38. //ClearColliderAndLineRenderer();
  39. }
  40. OnDrawLine();
  41. firstMouseDown = false;
  42. }
  43. //画线
  44. private void OnDrawLine()
  45. {
  46. if (firstMouseDown == true)
  47. {
  48. positionCount = 0;
  49. //头坐标
  50. headPosition = Camera.main.ScreenToViewportPoint(Input.mousePosition + new Vector3(0, 0, 11));
  51. lastPosition = headPosition;
  52. }
  53. if (mouseDown == true)
  54. {
  55. headPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition + new Vector3(0, 0, 11));
  56. //判断头坐标到尾坐标的距离是否大于记录点位
  57. if (Vector3.Distance(headPosition, lastPosition) > distanceOfPositions)
  58. {
  59. //用于保存位置
  60. SavePosition(headPosition);
  61. positionCount++;
  62. }
  63. lastPosition = headPosition;
  64. }
  65. //设置线性渲染器的位置
  66. SetLineRendererPosition(mouseTrackPositions);
  67. }
  68. //保存位置
  69. private void SavePosition(Vector3 pos)
  70. {
  71. pos.z = 0;
  72. if (positionCount <= 19)
  73. {
  74. for (int i = positionCount; i < 20; i++)
  75. {
  76. mouseTrackPositions[i] = pos;
  77. }
  78. }
  79. else
  80. {
  81. for (int i = 0; i < 19; i++)
  82. {
  83. mouseTrackPositions[i] = mouseTrackPositions[i + 1];
  84. }
  85. }
  86. mouseTrackPositions[19] = pos;
  87. //创建碰撞路径
  88. List<Vector2> colliderPath = GetColliderPath(mouseTrackPositions);
  89. polygonCollider.SetPath(0, colliderPath.ToArray());
  90. }
  91. //计算碰撞体轮廓
  92. float colliderWidth;
  93. List<Vector2> pointList2 = new List<Vector2>();
  94. List<Vector2> GetColliderPath(Vector3[] pointList3)
  95. {
  96. //碰撞体宽度
  97. colliderWidth = lineRenderer.startWidth;
  98. //Vector3转Vector2
  99. pointList2.Clear();
  100. for (int i = 0; i < pointList3.Length; i++)
  101. {
  102. pointList2.Add(pointList3[i]);
  103. }
  104. //碰撞体轮廓点位
  105. List<Vector2> edgePointList = new List<Vector2>();
  106. //以LineRenderer的点位为中心, 沿法线方向与法线反方向各偏移一定距离, 形成一个闭合且不交叉的折线
  107. for (int j = 1; j < pointList2.Count; j++)
  108. {
  109. //当前点指向前一点的向量
  110. Vector2 distanceVector = pointList2[j - 1] - pointList2[j];
  111. //法线向量
  112. Vector3 crossVector = Vector3.Cross(distanceVector, Vector3.forward);
  113. //标准化, 单位向量
  114. Vector2 offectVector = crossVector.normalized;
  115. //沿法线方向与法线反方向各偏移一定距离
  116. Vector2 up = pointList2[j - 1] + 0.5f * colliderWidth * offectVector;
  117. Vector2 down = pointList2[j - 1] - 0.5f * colliderWidth * offectVector;
  118. //分别加到List的首位和末尾, 保证List中的点位可以围成一个闭合且不交叉的折线
  119. edgePointList.Insert(0, down);
  120. edgePointList.Add(up);
  121. //加入最后一点
  122. if (j == pointList2.Count - 1)
  123. {
  124. up = pointList2[j] + 0.5f * colliderWidth * offectVector;
  125. down = pointList2[j] - 0.5f * colliderWidth * offectVector;
  126. edgePointList.Insert(0, down);
  127. edgePointList.Add(up);
  128. }
  129. }
  130. //返回点位
  131. return edgePointList;
  132. }
  133. //设置线条渲染器位置
  134. private void SetLineRendererPosition(Vector3[] position)
  135. {
  136. lineRenderer.SetPositions(position);
  137. }
  138. //用于清除碰撞和线性渲染
  139. void ClearColliderAndLineRenderer()
  140. {
  141. if (polygonCollider)
  142. {
  143. polygonCollider.enabled = false;
  144. }
  145. lineRenderer.positionCount = 0;
  146. }
  147. }

效果图:

以上为个人经验,希望能给大家一个参考,也希望大家多多支持w3xue。如有错误或未考虑完全的地方,望不吝赐教。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号