当前位置:   article > 正文

Unity 中画线

Unity 中画线

前言:
 

  在Unity项目中,调试和可视化是开发过程中不可或缺的部分。其中,绘制线条是一种常见的手段,可以用于在Scene场景和Game视图中进行调试和展示。本篇博客将为你介绍多种不同的绘制线条方法,帮助你轻松应对各种调试和可视化需求。

一、Debug.DrawLine

Debug.DrawLine 是 Unity 提供的一种用于在 Scene 视图中绘制调试线条的方法。

start世界空间中线条起始点的位置。
end在世界空间中指向线条的终点。
color线条的颜色。
duration线条的可见长度。

在 Update/FixedUpdate/LateUpdate 中调用:

这个方法通常用于游戏运行时进行更新,在这些方法中调用 Debug.DrawLine 来在不同帧更新时绘制线条。

只在 Scene 窗口里显示:

Debug.DrawLine 绘制的线条只能在 Scene 窗口中显示。这限制了在 Game 窗口中实时查看线条。

不能设置材质:

使用 Debug.DrawLine 绘制的线条无法更改或设置材质,因为它们主要用于调试和临时可视化,不提供材质设置的选项。

1、绘制正方体

  1. [ExecuteInEditMode]
  2. public class MyComponent1 : MonoBehaviour
  3. {
  4. public float size = 1; // 正方体的大小
  5. private Vector3[] vertices = new Vector3[8]
  6. {
  7. new Vector3(-1, -1, -1),
  8. new Vector3(1, -1, -1),
  9. new Vector3(1, -1, 1),
  10. new Vector3(-1, -1, 1),
  11. new Vector3(-1, 1, -1),
  12. new Vector3(1, 1, -1),
  13. new Vector3(1, 1, 1),
  14. new Vector3(-1, 1, 1),
  15. };
  16. private void Update()
  17. {
  18. for (int i = 0; i < 4; i++)
  19. {
  20. int next = (i < 3) ? (i + 1) : 0;
  21. // 底部边框线
  22. Debug.DrawLine(vertices[i] * size * 0.5f, vertices[next] * size * 0.5f, Color.green);
  23. // 顶部边框线
  24. Debug.DrawLine(vertices[i + 4] * size * 0.5f, vertices[next + 4] * size * 0.5f, Color.green);
  25. // 垂直边框线
  26. Debug.DrawLine(vertices[i] * size * 0.5f, vertices[i + 4] * size * 0.5f, Color.green);
  27. }
  28. }
  29. }

要使用 Debug.DrawLine 绘制一个正方体,需要考虑其边界上的顶点和线条之间的关系。下面是一个示例代码,用于在场景中绘制一个简单的正方体:

2、绘制网格

  1. using UnityEngine;
  2. public class DrawGrid : MonoBehaviour
  3. {
  4. public float gridSize = 1.0f; // 网格单元的大小
  5. public int gridSizeX = 10; // 网格的列数
  6. public int gridSizeY = 10; // 网格的行数
  7. void OnDrawGizmos()
  8. {
  9. // 绘制水平方向的线条
  10. for (int i = 0; i <= gridSizeX; i++)
  11. {
  12. Vector3 start = Vector3.right * i * gridSize;
  13. Vector3 end = start + Vector3.forward * gridSize * gridSizeY;
  14. Debug.DrawLine(start, end, Color.white);
  15. }
  16. // 绘制垂直方向的线条
  17. for (int i = 0; i <= gridSizeY; i++)
  18. {
  19. Vector3 start = Vector3.forward * i * gridSize;
  20. Vector3 end = start + Vector3.right * gridSize * gridSizeX;
  21. Debug.DrawLine(start, end, Color.white);
  22. }
  23. }
  24. }

使用 Debug.DrawLine 绘制一个 10x10 的网格。将这个脚本附加到一个空 GameObject 上。gridSize 变量表示网格的单元大小,gridSizeX 和 gridSizeY 分别表示网格的列数和行数。在 Scene 视图中,可以看到一个由绿色线条组成的网格。这些线条只是用于调试和可视化,不会在游戏中显示。

二、Gizmos.DrawLine

Gizmos.DrawLine 是 Unity 提供的一个用于在 Scene 窗口中绘制线条的函数。它可以在 OnDrawGizmos 和 OnDrawGizmosSelected 方法中使用。

from世界空间中线条起始点的位置。
to在世界空间中指向线条的终点。

调用方式:

适合在 OnDrawGizmos 和 OnDrawGizmosSelected 这两个 Unity 生命周期方法中调用。这些方法是专门用于在 Scene 窗口中绘制 Gizmo 的。

显示范围:

所绘制的线条只会在 Scene 窗口中显示,而不会出现在游戏运行中。这有助于在编辑器中进行调试和可视化,但不会影响游戏性能或最终的构建。

材质设置:

Gizmos 提供的绘制方法通常不能设置材质、颜色等属性。Gizmos.DrawLine 绘制的线条颜色和材质是固定的,无法调整其粗细、透明度或使用自定义材质。

1、绘制网格

  1. using UnityEngine;
  2. public class DrawGrid : MonoBehaviour
  3. {
  4. public float gridSize = 1.0f; // 网格单元的大小
  5. public int gridSizeX = 10; // 网格的列数
  6. public int gridSizeY = 10; // 网格的行数
  7. void OnDrawGizmos()
  8. {
  9. Gizmos.color = Color.red;
  10. // 绘制水平方向的线条
  11. for (int i = 0; i <= gridSizeX; i++)
  12. {
  13. Vector3 start = Vector3.right * i * gridSize;
  14. Vector3 end = start + Vector3.forward * gridSize * gridSizeY;
  15. Gizmos.DrawLine(start, end);
  16. }
  17. // 绘制垂直方向的线条
  18. for (int i = 0; i <= gridSizeY; i++)
  19. {
  20. Vector3 start = Vector3.forward * i * gridSize;
  21. Vector3 end = start + Vector3.right * gridSize * gridSizeX;
  22. Gizmos.DrawLine(start, end);
  23. }
  24. }
  25. }

在 OnDrawGizmos 方法中使用 Gizmos.DrawLine 绘制一个 10x10 的网格。这些线条只在 Scene 窗口中显示,并且不能设置材质。要注意的是,Gizmos 类用于在 Scene 窗口中绘制 Gizmo,但不会在游戏运行时显示。

三、Mesh

在Unity中,Mesh(网格)是一种用于表示3D模型的数据结构。它定义了一个网格模型的顶点、三角形(或其他多边形)、UV(纹理坐标)、法线(法线方向)等数据。Mesh是用于构建3D模型的基本组成部分之一。

Mesh是Unity中许多3D对象(如MeshFilter、MeshRenderer等)的基础,通过MeshFilter组件将Mesh应用到GameObject上,并使用MeshRenderer来渲染对象。通常,开发者使用Mesh来创建静态或动态的3D模型,并在游戏场景中呈现出来。

vertices表示网格的顶点数组。
triangles表示定义三角形的索引数组。
normals表示法线数组,用于指定网格每个顶点的法线方向。
uv表示纹理坐标数组。
colors表示网格的顶点颜色。
SetIndicesSetIndices 是 Mesh 类中用于设置网格顶点索引的方法。它允许您指定用于连接顶点以形成三角形或其他多边形的索引数组。
MarkDynamicMarkDynamic 方法用于标记网格为动态网格。它是一个性能优化方法,用于告诉引擎此网格将频繁地更新。当您有一个需要在每帧或频繁时间间隔内更新的网格时,可以使用 MarkDynamic 方法。

1、绘制正方体线框

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.UI;
  5. [RequireComponent(typeof(MeshFilter))]
  6. [RequireComponent(typeof(MeshRenderer))]
  7. public class DrawCube : MonoBehaviour
  8. {
  9. private Mesh mesh;
  10. private MeshFilter meshFilter;
  11. private MeshRenderer meshRenderer;
  12. // 创建一个立方体的 Mesh
  13. private Mesh CreateCubeMesh()
  14. {
  15. Mesh mesh = new Mesh();
  16. mesh.vertices = new Vector3[]
  17. {
  18. new Vector3(-1, -1, -1), // 0
  19. new Vector3(1, -1, -1), // 1
  20. new Vector3(1, 1, -1), // 2
  21. new Vector3(-1, 1, -1), // 3
  22. new Vector3(-1, -1, 1), // 4
  23. new Vector3(1, -1, 1), // 5
  24. new Vector3(1, 1, 1), // 6
  25. new Vector3(-1, 1, 1) // 7
  26. };
  27. mesh.SetIndices(new int[]
  28. {
  29. 0, 1, 1, 2, 2, 3, 3, 0, // 前面四条边
  30. 4, 5, 5, 6, 6, 7, 7, 4, // 后面四条边
  31. 0, 4, 1, 5, 2, 6, 3, 7 // 连接前后两个面的四条边
  32. }, MeshTopology.Lines, 0);
  33. return mesh;
  34. }
  35. private void Start()
  36. {
  37. meshFilter = GetComponent<MeshFilter>();
  38. meshRenderer = GetComponent<MeshRenderer>();
  39. mesh = CreateCubeMesh();
  40. meshFilter.mesh = mesh;
  41. var material = new Material(Shader.Find("Unlit/Color"));
  42. material.color = Color.green;
  43. meshRenderer.material = material;
  44. }
  45. }

这里是通过创建一个正方体的Mesh,然后通过MeshFilter组件将Mesh应用到GameObject上,并使用MeshRenderer来渲染该正方体线框。

四、GL

OpenGL(Open Graphics Library)是一个用于渲染 2D 和 3D 图形的跨平台图形库。它提供了一系列函数和指令,允许开发者通过编程来操作图形硬件,实现图形渲染和交互式图形应用程序的开发。

在Unity中,GL(Graphics Library)是一个底层的图形渲染接口,用于执行低级图形绘制操作。GL允许开发者以非常灵活的方式直接控制图形渲染,使开发者可以绘制各种形状、线条、文本和纹理,实现各种自定义的绘图需求。

调用方式:

OnPostRender(): 用于在完成渲染场景之后立即调用,适合进行屏幕后处理或绘制Overlay UI。
OnRenderObject(): 在渲染对象时调用。允许手动渲染对象并覆盖其默认渲染。用于自定义渲染对象或其他特殊渲染需求。

显示范围:

LoadOrtho(): 用于设置绘制范围为屏幕坐标系,绘制在整个屏幕上。在OnPostRender()中调用,以便以屏幕为基础绘制2D图形。

材质设置:

GL允许使用材质,但与在Unity中常规渲染管道中的应用方式有所不同。
在GL中,使用材质时,需要在GL代码中直接调用SetPass()来设置所需的材质属性。这将设置着色器状态,让GL能够使用该材质来渲染几何图元。
若要控制颜色,需要使用GL.Color()方法设置颜色。
若要控制透明度,可以通过设置颜色的Alpha值来实现半透明效果。

1、绘制3D网格和屏幕网格

  1. using UnityEngine;
  2. public class DrawGrid : MonoBehaviour
  3. {
  4. public float gridSize = 1.0f; // 网格单元的大小
  5. public int gridSizeX = 10; // 网格的列数
  6. public int gridSizeY = 10; // 网格的行数
  7. private Material lineMaterial;
  8. void CreateLineMaterial()
  9. {
  10. if (!lineMaterial)
  11. {
  12. // Unity has a built-in shader that is useful for drawing
  13. // simple colored things.
  14. Shader shader = Shader.Find("Hidden/Internal-Colored");
  15. lineMaterial = new Material(shader);
  16. lineMaterial.hideFlags = HideFlags.HideAndDontSave;
  17. // Turn on alpha blending
  18. lineMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
  19. lineMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
  20. // Turn backface culling off
  21. lineMaterial.SetInt("_Cull", (int)UnityEngine.Rendering.CullMode.Off);
  22. // Turn off depth writes
  23. lineMaterial.SetInt("_ZWrite", 0);
  24. }
  25. }
  26. // Will be called after all regular rendering is done
  27. public void OnRenderObject()
  28. {
  29. CreateLineMaterial();
  30. lineMaterial.SetPass(0); //刷新当前材质
  31. //Draw3DGrid();
  32. DrawScreenGrid();
  33. }
  34. /// <summary>
  35. /// 在三维场景中绘制网格
  36. /// </summary>
  37. void Draw3DGrid()
  38. {
  39. GL.PushMatrix();
  40. GL.MultMatrix(transform.localToWorldMatrix);
  41. GL.Begin(GL.LINES);
  42. float startX = -(gridSize * gridSizeX) / 2;
  43. float startZ = -(gridSize * gridSizeY) / 2;
  44. // 绘制垂直方向的线条
  45. for (int i = 0; i <= gridSizeX; i++)
  46. {
  47. GL.Color(Color.red);
  48. float xPos = startX + i * gridSize;
  49. GL.Vertex3(xPos, 0, startZ);
  50. GL.Vertex3(xPos, 0, -startZ);
  51. }
  52. // 绘制水平方向的线条
  53. for (int i = 0; i <= gridSizeY; i++)
  54. {
  55. GL.Color(Color.green);
  56. float zPos = startZ + i * gridSize;
  57. GL.Vertex3(startX, 0, zPos);
  58. GL.Vertex3(-startX, 0, zPos);
  59. }
  60. GL.End();
  61. GL.PopMatrix();
  62. }
  63. /// <summary>
  64. /// 在屏幕上绘制网格
  65. /// </summary>
  66. void DrawScreenGrid()
  67. {
  68. GL.PushMatrix(); //保存当前Matirx
  69. GL.LoadPixelMatrix(); //设置pixelMatrix
  70. GL.Begin(GL.LINES);
  71. // 绘制水平方向的线条
  72. for (int i = 0; i <= gridSizeX; i++)
  73. {
  74. GL.Color(Color.green);
  75. float xPos = i * gridSize;
  76. GL.Vertex3(xPos, 0, 0);
  77. GL.Vertex3(xPos, gridSize * gridSizeY, 0);
  78. }
  79. // 绘制垂直方向的线条
  80. for (int i = 0; i <= gridSizeY; i++)
  81. {
  82. GL.Color(Color.green);
  83. float zPos = i * gridSize;
  84. GL.Vertex3(0, zPos, 0);
  85. GL.Vertex3(gridSize * gridSizeX, zPos, 0);
  86. }
  87. GL.End();
  88. GL.PopMatrix();//读取之前的Matrix
  89. }
  90. }

2、实现屏幕框选

  1. public class BoxSelection: MonoBehaviour
  2. {
  3. public Material boxMaterial;
  4. public Material lineMaterial;
  5. private Vector3 startPoint;
  6. private bool isSelecting = false;
  7. private void Update()
  8. {
  9. if (Input.GetMouseButtonDown(0))
  10. {
  11. startPoint = Input.mousePosition;
  12. isSelecting = true;
  13. }
  14. else if (Input.GetMouseButtonUp(0))
  15. {
  16. isSelecting = false;
  17. SelectObjects();
  18. }
  19. }
  20. private void OnPostRender()
  21. {
  22. if (!boxMaterial || !lineMaterial)
  23. {
  24. Debug.LogError("Please assign materials on the inspector!");
  25. return;
  26. }
  27. if (isSelecting)
  28. {
  29. GL.PushMatrix();
  30. boxMaterial.SetPass(0);
  31. GL.LoadPixelMatrix();
  32. GL.Begin(GL.QUADS);
  33. boxMaterial.color = new Color(1f, 1f, 1f, 0.2f);
  34. Vector3 endPos = Input.mousePosition;
  35. GL.Vertex3(startPoint.x, startPoint.y, 0);
  36. GL.Vertex3(endPos.x, startPoint.y, 0);
  37. GL.Vertex3(endPos.x, endPos.y, 0);
  38. GL.Vertex3(startPoint.x, endPos.y, 0);
  39. GL.End();
  40. GL.PopMatrix();
  41. GL.PushMatrix();
  42. lineMaterial.SetPass(0);
  43. GL.LoadPixelMatrix();
  44. GL.Begin(GL.LINES);
  45. lineMaterial.color = Color.green;
  46. GL.Vertex3(startPoint.x, startPoint.y, 0);
  47. GL.Vertex3(endPos.x, startPoint.y, 0);
  48. GL.Vertex3(endPos.x, startPoint.y, 0);
  49. GL.Vertex3(endPos.x, endPos.y, 0);
  50. GL.Vertex3(endPos.x, endPos.y, 0);
  51. GL.Vertex3(startPoint.x, endPos.y, 0);
  52. GL.Vertex3(startPoint.x, endPos.y, 0);
  53. GL.Vertex3(startPoint.x, startPoint.y, 0);
  54. GL.End();
  55. GL.PopMatrix();
  56. }
  57. }
  58. private void SelectObjects()
  59. {
  60. Vector3 mouseStartPos = startPoint;
  61. Vector3 mouseEndPos = Input.mousePosition;
  62. Vector3 min = Vector3.Min(mouseStartPos, mouseEndPos);
  63. Vector3 max = Vector3.Max(mouseStartPos, mouseEndPos);
  64. Rect selectRect = new Rect(min.x, Screen.height - max.y, max.x - min.x, max.y - min.y);
  65. foreach (GameObject obj in FindObjectsOfType<GameObject>())
  66. {
  67. Vector3 screenPos = Camera.main.WorldToScreenPoint(obj.transform.position);
  68. if (selectRect.Contains(screenPos))
  69. {
  70. Debug.Log("Selected object: " + obj.name);
  71. // 在这里可以添加选中对象的操作逻辑
  72. }
  73. }
  74. }
  75. }

五、LineRenderer

LineRenderer 是 Unity 中用于在场景中绘制线条的组件之一。它可以用于创建简单的线段、路径、连线等效果。

1、实现屏幕写字板

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class LineRendererDraw : MonoBehaviour
  5. {
  6. private LineRenderer clone;
  7. public LineRenderer linePre;
  8. private int positionCount;
  9. private Material lineMaterial;
  10. private void Start()
  11. {
  12. lineMaterial = new Material(Shader.Find("Legacy Shaders/Particles/Additive"));
  13. linePre.material = lineMaterial;
  14. }
  15. /// <summary>
  16. /// 创建线条
  17. /// </summary>
  18. /// <returns></returns>
  19. private LineRenderer CreateLine()
  20. {
  21. //实例化对象
  22. LineRenderer line = Instantiate(linePre, linePre.transform.position, Quaternion.identity);
  23. //设置起始和结束的颜色
  24. line.startColor = Color.red;
  25. line.endColor = Color.blue;
  26. //设置起始和结束的宽度
  27. line.startWidth = 0.4f;
  28. line.endWidth = 0.35f;
  29. return line;
  30. }
  31. // Update is called once per frame
  32. void Update()
  33. {
  34. if (Input.GetMouseButtonDown(0))
  35. {
  36. //实例化对象
  37. clone = CreateLine();
  38. //计数
  39. positionCount = 0;
  40. }
  41. if (Input.GetMouseButton(0))
  42. {
  43. //每一帧检测,按下鼠标的时间越长,计数越多
  44. positionCount++;
  45. //设置顶点数
  46. clone.positionCount = positionCount;
  47. //设置顶点位置(顶点的索引,将鼠标点击的屏幕坐标转换为世界坐标)
  48. clone.SetPosition(positionCount - 1, Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 15)));
  49. }
  50. }
  51. }

六、UI画线

这里通过Unity的UGUI来进行画线,主要原理就是使用OnPopulateMesh方法来重构Mesh进行画线。

OnPopulateMesh函数:当一个UI元素生成顶点数据时会调用。

OnPopulateMesh(VertexHelper vh)函数,我们可以在这个函数中修改顶点的数据或者获取顶点的数据。

  1. using System.Collections.Generic;
  2. using UnityEngine;
  3. using UnityEngine.UI;
  4. /// <summary>
  5. /// 绘制的线段结构体
  6. /// </summary>
  7. public struct LineSegment
  8. {
  9. public Vector3 startPoint;
  10. public Vector3 endPoint;
  11. public float lineWidth;
  12. public Vector3 Vector
  13. {
  14. get
  15. {
  16. return endPoint - startPoint;
  17. }
  18. }
  19. public Vector3 Normal
  20. {
  21. get
  22. {
  23. return Vector3.Cross(Vector.normalized, Vector3.forward).normalized;
  24. }
  25. }
  26. public Vector3 StartLeftPoint
  27. {
  28. get
  29. {
  30. return startPoint + Normal * lineWidth;
  31. }
  32. }
  33. public Vector3 StartRightPoint
  34. {
  35. get
  36. {
  37. return startPoint - Normal * lineWidth;
  38. }
  39. }
  40. public Vector3 EndLeftPoint
  41. {
  42. get
  43. {
  44. return endPoint + Normal * lineWidth;
  45. }
  46. }
  47. public Vector3 EndRightPoint
  48. {
  49. get
  50. {
  51. return endPoint - Normal * lineWidth;
  52. }
  53. }
  54. }
  55. public class ImageLine : MaskableGraphic
  56. {
  57. private List<List<UIVertex>> vertexQuadList = new List<List<UIVertex>>();
  58. private LineSegment lineSegment = new LineSegment();
  59. public float lineWidth = 4;
  60. protected override void OnPopulateMesh(VertexHelper vh)
  61. {
  62. vh.Clear();
  63. for (int i = 0; i < vertexQuadList.Count; i++)
  64. {
  65. vh.AddUIVertexQuad(vertexQuadList[i].ToArray());
  66. }
  67. }
  68. // Update is called once per frame
  69. void Update()
  70. {
  71. if (Input.GetMouseButtonDown(0))
  72. {
  73. lineSegment.lineWidth = lineWidth;
  74. lineSegment.startPoint = ScreenPointToLocalPointInRectangle(Input.mousePosition);
  75. }
  76. else if (Input.GetMouseButton(0))
  77. {
  78. lineSegment.endPoint = ScreenPointToLocalPointInRectangle(Input.mousePosition);
  79. //当鼠标不动时不再绘制
  80. if (lineSegment.startPoint == lineSegment.endPoint) return;
  81. //线段过短不进行绘制
  82. if (lineSegment.Vector.magnitude < 5) return;
  83. AddVertexQuad(lineSegment);
  84. lineSegment.startPoint = lineSegment.endPoint;
  85. SetVerticesDirty();
  86. }
  87. if (Input.GetMouseButtonDown(1))
  88. {
  89. vertexQuadList.Clear();
  90. SetVerticesDirty();
  91. }
  92. }
  93. /// <summary>
  94. /// 将线段上顶点添加到UI四边形顶点
  95. /// </summary>
  96. /// <param name="lineSegment"></param>
  97. private void AddVertexQuad(LineSegment lineSegment)
  98. {
  99. List<UIVertex> uIVertices = new List<UIVertex>();
  100. UIVertex uIVertex = new UIVertex();
  101. uIVertex.position = lineSegment.StartLeftPoint;
  102. uIVertex.color = color;
  103. uIVertices.Add(uIVertex);
  104. UIVertex uIVertex1 = new UIVertex();
  105. uIVertex1.position = lineSegment.StartRightPoint;
  106. uIVertex1.color = color;
  107. uIVertices.Add(uIVertex1);
  108. UIVertex uIVertex2 = new UIVertex();
  109. uIVertex2.position = lineSegment.EndRightPoint;
  110. uIVertex2.color = color;
  111. uIVertices.Add(uIVertex2);
  112. UIVertex uIVertex3 = new UIVertex();
  113. uIVertex3.position = lineSegment.EndLeftPoint;
  114. uIVertex3.color = color;
  115. uIVertices.Add(uIVertex3);
  116. vertexQuadList.Add(uIVertices);
  117. }
  118. /// <summary>
  119. /// 屏幕坐标转换为本地坐标
  120. /// </summary>
  121. /// <param name="screenPoint"></param>
  122. /// <returns></returns>
  123. private Vector2 ScreenPointToLocalPointInRectangle(Vector3 screenPoint)
  124. {
  125. RectTransform rectTransform = GetComponent<RectTransform>();
  126. Vector2 localPoint = Vector2.zero;
  127. switch (canvas.renderMode)
  128. {
  129. case RenderMode.ScreenSpaceOverlay:
  130. RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, screenPoint, null, out localPoint);
  131. break;
  132. case RenderMode.ScreenSpaceCamera:
  133. RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, screenPoint, canvas.worldCamera, out localPoint);
  134. break;
  135. case RenderMode.WorldSpace:
  136. RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, screenPoint, canvas.worldCamera, out localPoint);
  137. break;
  138. default:
  139. break;
  140. }
  141. return localPoint;
  142. }
  143. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/544653
推荐阅读
相关标签
  

闽ICP备14008679号