A game about forced loneliness, made by TACStudios
1using System;
2using System.Collections.Generic;
3using UnityEditor;
4using UnityEngine;
5using UnityEngine.Tilemaps;
6using Event = UnityEngine.Event;
7
8namespace UnityEditor.Tilemaps
9{
10 internal static class GridEditorUtility
11 {
12 private const int k_GridGizmoVertexCount = 32000;
13 private const float k_GridGizmoDistanceFalloff = 50f;
14
15 public static Vector3Int ClampToGrid(Vector3Int p, Vector2Int origin, Vector2Int gridSize)
16 {
17 return new Vector3Int(
18 Math.Max(Math.Min(p.x, origin.x + gridSize.x - 1), origin.x),
19 Math.Max(Math.Min(p.y, origin.y + gridSize.y - 1), origin.y),
20 p.z
21 );
22 }
23
24 public static Vector3 ScreenToLocal(Transform transform, Vector2 screenPosition)
25 {
26 return ScreenToLocal(transform, screenPosition, new Plane(transform.forward * -1f, transform.position));
27 }
28
29 public static Vector3 ScreenToLocal(Transform transform, Vector2 screenPosition, Plane plane)
30 {
31 Ray ray;
32 if (Camera.current.orthographic)
33 {
34 Vector2 screen = EditorGUIUtility.PointsToPixels(GUIClip.Unclip(screenPosition));
35 screen.y = Camera.current.pixelHeight - screen.y;
36 Vector3 cameraWorldPoint = Camera.current.ScreenToWorldPoint(screen);
37 ray = new Ray(cameraWorldPoint, Camera.current.transform.forward);
38 }
39 else
40 {
41 ray = HandleUtility.GUIPointToWorldRay(screenPosition);
42 }
43
44 float result;
45 plane.Raycast(ray, out result);
46 Vector3 world = ray.GetPoint(result);
47 return transform.InverseTransformPoint(world);
48 }
49
50 public static RectInt GetMarqueeRect(Vector2Int p1, Vector2Int p2)
51 {
52 return new RectInt(
53 Math.Min(p1.x, p2.x),
54 Math.Min(p1.y, p2.y),
55 Math.Abs(p2.x - p1.x) + 1,
56 Math.Abs(p2.y - p1.y) + 1
57 );
58 }
59
60 public static BoundsInt GetMarqueeBounds(Vector3Int p1, Vector3Int p2)
61 {
62 return new BoundsInt(
63 Math.Min(p1.x, p2.x),
64 Math.Min(p1.y, p2.y),
65 Math.Min(p1.z, p2.z),
66 Math.Abs(p2.x - p1.x) + 1,
67 Math.Abs(p2.y - p1.y) + 1,
68 Math.Abs(p2.z - p1.z) + 1
69 );
70 }
71
72 // http://ericw.ca/notes/bresenhams-line-algorithm-in-csharp.html
73 public static IEnumerable<Vector2Int> GetPointsOnLine(Vector2Int p1, Vector2Int p2)
74 {
75 int x0 = p1.x;
76 int y0 = p1.y;
77 int x1 = p2.x;
78 int y1 = p2.y;
79
80 bool steep = Math.Abs(y1 - y0) > Math.Abs(x1 - x0);
81 if (steep)
82 {
83 int t;
84 t = x0; // swap x0 and y0
85 x0 = y0;
86 y0 = t;
87 t = x1; // swap x1 and y1
88 x1 = y1;
89 y1 = t;
90 }
91 if (x0 > x1)
92 {
93 int t;
94 t = x0; // swap x0 and x1
95 x0 = x1;
96 x1 = t;
97 t = y0; // swap y0 and y1
98 y0 = y1;
99 y1 = t;
100 }
101 int dx = x1 - x0;
102 int dy = Math.Abs(y1 - y0);
103 int error = dx / 2;
104 int ystep = (y0 < y1) ? 1 : -1;
105 int y = y0;
106 for (int x = x0; x <= x1; x++)
107 {
108 yield return new Vector2Int((steep ? y : x), (steep ? x : y));
109 error = error - dy;
110 if (error < 0)
111 {
112 y += ystep;
113 error += dx;
114 }
115 }
116 }
117
118 public static void DrawBatchedHorizontalLine(float x1, float x2, float y)
119 {
120 GL.Vertex3(x1, y, 0f);
121 GL.Vertex3(x2, y, 0f);
122 GL.Vertex3(x2, y + 1, 0f);
123 GL.Vertex3(x1, y + 1, 0f);
124 }
125
126 public static void DrawBatchedVerticalLine(float y1, float y2, float x)
127 {
128 GL.Vertex3(x, y1, 0f);
129 GL.Vertex3(x, y2, 0f);
130 GL.Vertex3(x + 1, y2, 0f);
131 GL.Vertex3(x + 1, y1, 0f);
132 }
133
134 public static void DrawBatchedLine(Vector3 p1, Vector3 p2)
135 {
136 GL.Vertex3(p1.x, p1.y, p1.z);
137 GL.Vertex3(p2.x, p2.y, p2.z);
138 }
139
140 public static void DrawLine(Vector2 p1, Vector2 p2, Color color)
141 {
142 if (Event.current.type != EventType.Repaint)
143 return;
144
145 HandleUtility.ApplyWireMaterial();
146 GL.PushMatrix();
147 GL.MultMatrix(GUI.matrix);
148 GL.Begin(GL.LINES);
149 GL.Color(color);
150 DrawBatchedLine(p1, p2);
151 GL.End();
152 GL.PopMatrix();
153 }
154
155 public static void DrawBox(Rect r, Color color)
156 {
157 if (Event.current.type != EventType.Repaint)
158 return;
159
160 HandleUtility.ApplyWireMaterial();
161 GL.PushMatrix();
162 GL.MultMatrix(GUI.matrix);
163 GL.Begin(GL.LINES);
164 GL.Color(color);
165 DrawBatchedLine(new Vector3(r.xMin, r.yMin, 0f), new Vector3(r.xMax, r.yMin, 0f));
166 DrawBatchedLine(new Vector3(r.xMax, r.yMin, 0f), new Vector3(r.xMax, r.yMax, 0f));
167 DrawBatchedLine(new Vector3(r.xMax, r.yMax, 0f), new Vector3(r.xMin, r.yMax, 0f));
168 DrawBatchedLine(new Vector3(r.xMin, r.yMax, 0f), new Vector3(r.xMin, r.yMin, 0f));
169 GL.End();
170 GL.PopMatrix();
171 }
172
173 public static void DrawFilledBox(Rect r, Color color)
174 {
175 if (Event.current.type != EventType.Repaint)
176 return;
177
178 HandleUtility.ApplyWireMaterial();
179 GL.PushMatrix();
180 GL.MultMatrix(GUI.matrix);
181 GL.Begin(GL.QUADS);
182 GL.Color(color);
183 GL.Vertex3(r.xMin, r.yMin, 0f);
184 GL.Vertex3(r.xMax, r.yMin, 0f);
185 GL.Vertex3(r.xMax, r.yMax, 0f);
186 GL.Vertex3(r.xMin, r.yMax, 0f);
187 GL.End();
188 GL.PopMatrix();
189 }
190
191 public static void DrawGridMarquee(GridLayout gridLayout, BoundsInt area, Color color)
192 {
193 if (gridLayout == null)
194 return;
195
196 switch (gridLayout.cellLayout)
197 {
198 case GridLayout.CellLayout.Hexagon:
199 DrawSelectedHexGridArea(gridLayout, area, color);
200 break;
201 case GridLayout.CellLayout.Isometric:
202 case GridLayout.CellLayout.IsometricZAsY:
203 case GridLayout.CellLayout.Rectangle:
204 var cellStride = gridLayout.cellSize + gridLayout.cellGap;
205 var cellGap = Vector3.one;
206 if (!Mathf.Approximately(cellStride.x, 0f))
207 {
208 cellGap.x = gridLayout.cellSize.x / cellStride.x;
209 }
210 if (!Mathf.Approximately(cellStride.y, 0f))
211 {
212 cellGap.y = gridLayout.cellSize.y / cellStride.y;
213 }
214
215 Vector3[] cellLocals =
216 {
217 gridLayout.CellToLocal(new Vector3Int(area.xMin, area.yMin, area.zMin)),
218 gridLayout.CellToLocalInterpolated(new Vector3(area.xMax - 1 + cellGap.x, area.yMin, area.zMin)),
219 gridLayout.CellToLocalInterpolated(new Vector3(area.xMax - 1 + cellGap.x, area.yMax - 1 + cellGap.y, area.zMin)),
220 gridLayout.CellToLocalInterpolated(new Vector3(area.xMin, area.yMax - 1 + cellGap.y, area.zMin))
221 };
222
223 HandleUtility.ApplyWireMaterial();
224 GL.PushMatrix();
225 GL.MultMatrix(gridLayout.transform.localToWorldMatrix);
226 GL.Begin(GL.LINES);
227 GL.Color(color);
228 int i = 0;
229
230 for (int j = cellLocals.Length - 1; i < cellLocals.Length; j = i++)
231 DrawBatchedLine(cellLocals[j], cellLocals[i]);
232
233 GL.End();
234 GL.PopMatrix();
235 break;
236 }
237 }
238
239 public static void DrawSelectedHexGridArea(GridLayout gridLayout, BoundsInt area, Color color)
240 {
241 int requiredVertices = 4 * (area.size.x + area.size.y) - 2;
242 if (requiredVertices < 0)
243 return;
244 Vector3[] cellLocals = new Vector3[requiredVertices];
245 int horizontalCount = area.size.x * 2;
246 int verticalCount = area.size.y * 2 - 1;
247 int bottom = 0;
248 int top = horizontalCount + verticalCount + horizontalCount - 1;
249 int left = requiredVertices - 1;
250 int right = horizontalCount;
251 Vector3[] cellOffset =
252 {
253 Grid.Swizzle(gridLayout.cellSwizzle, new Vector3(0, gridLayout.cellSize.y / 2, 0)),
254 Grid.Swizzle(gridLayout.cellSwizzle, new Vector3(gridLayout.cellSize.x / 2, gridLayout.cellSize.y / 4, 0)),
255 Grid.Swizzle(gridLayout.cellSwizzle, new Vector3(gridLayout.cellSize.x / 2, -gridLayout.cellSize.y / 4, 0)),
256 Grid.Swizzle(gridLayout.cellSwizzle, new Vector3(0, -gridLayout.cellSize.y / 2, 0)),
257 Grid.Swizzle(gridLayout.cellSwizzle, new Vector3(-gridLayout.cellSize.x / 2, -gridLayout.cellSize.y / 4, 0)),
258 Grid.Swizzle(gridLayout.cellSwizzle, new Vector3(-gridLayout.cellSize.x / 2, gridLayout.cellSize.y / 4, 0))
259 };
260 // Fill Top and Bottom Vertices
261 for (int x = area.min.x; x < area.max.x; x++)
262 {
263 cellLocals[bottom++] = gridLayout.CellToLocal(new Vector3Int(x, area.min.y, area.zMin)) + cellOffset[4];
264 cellLocals[bottom++] = gridLayout.CellToLocal(new Vector3Int(x, area.min.y, area.zMin)) + cellOffset[3];
265 cellLocals[top--] = gridLayout.CellToLocal(new Vector3Int(x, area.max.y - 1, area.zMin)) + cellOffset[0];
266 cellLocals[top--] = gridLayout.CellToLocal(new Vector3Int(x, area.max.y - 1, area.zMin)) + cellOffset[1];
267 }
268 // Fill first Left and Right Vertices
269 cellLocals[left--] = gridLayout.CellToLocal(new Vector3Int(area.min.x, area.min.y, area.zMin)) + cellOffset[5];
270 cellLocals[top--] = gridLayout.CellToLocal(new Vector3Int(area.max.x - 1, area.max.y - 1, area.zMin)) + cellOffset[2];
271 // Fill Left and Right Vertices
272 for (int y = area.min.y + 1; y < area.max.y; y++)
273 {
274 cellLocals[left--] = gridLayout.CellToLocal(new Vector3Int(area.min.x, y, area.zMin)) + cellOffset[4];
275 cellLocals[left--] = gridLayout.CellToLocal(new Vector3Int(area.min.x, y, area.zMin)) + cellOffset[5];
276 }
277 for (int y = area.min.y; y < (area.max.y - 1); y++)
278 {
279 cellLocals[right++] = gridLayout.CellToLocal(new Vector3Int(area.max.x - 1, y, area.zMin)) + cellOffset[2];
280 cellLocals[right++] = gridLayout.CellToLocal(new Vector3Int(area.max.x - 1, y, area.zMin)) + cellOffset[1];
281 }
282 HandleUtility.ApplyWireMaterial();
283 GL.PushMatrix();
284 GL.MultMatrix(gridLayout.transform.localToWorldMatrix);
285 GL.Begin(GL.LINES);
286 GL.Color(color);
287 int i = 0;
288 for (int j = cellLocals.Length - 1; i < cellLocals.Length; j = i++)
289 {
290 DrawBatchedLine(cellLocals[j], cellLocals[i]);
291 }
292 GL.End();
293 GL.PopMatrix();
294 }
295
296 public static void DrawGridGizmo(GridLayout gridLayout, Transform transform, Color color, ref Mesh gridMesh, ref Material gridMaterial)
297 {
298 // TODO: Hook this up with DrawGrid
299 if (Event.current.type != EventType.Repaint)
300 return;
301
302 if (gridMesh == null)
303 gridMesh = GenerateCachedGridMesh(gridLayout, color);
304
305 if (gridMaterial == null)
306 {
307 gridMaterial = (Material)EditorGUIUtility.LoadRequired("SceneView/GridGap.mat");
308 }
309
310 if (gridLayout.cellLayout == GridLayout.CellLayout.Hexagon)
311 {
312 gridMaterial.SetVector("_Gap", new Vector4(1f, 1f / 3f, 1f, 1f));
313 gridMaterial.SetVector("_Stride", new Vector4(1f, 1f, 1f, 1f));
314 }
315 else
316 {
317 gridMaterial.SetVector("_Gap", gridLayout.cellSize);
318 gridMaterial.SetVector("_Stride", gridLayout.cellGap + gridLayout.cellSize);
319 }
320
321 gridMaterial.SetPass(0);
322 GL.PushMatrix();
323 if (gridMesh.GetTopology(0) == MeshTopology.Lines)
324 GL.Begin(GL.LINES);
325 else
326 GL.Begin(GL.QUADS);
327
328 Graphics.DrawMeshNow(gridMesh, transform.localToWorldMatrix);
329 GL.End();
330 GL.PopMatrix();
331 }
332
333 public static Vector3 GetSpriteWorldSize(Sprite sprite)
334 {
335 if (sprite != null && sprite.rect.size.magnitude > 0f)
336 {
337 return new Vector3(
338 sprite.rect.size.x / sprite.pixelsPerUnit,
339 sprite.rect.size.y / sprite.pixelsPerUnit,
340 1f
341 );
342 }
343 return Vector3.one;
344 }
345
346 private static Mesh GenerateCachedGridMesh(GridLayout gridLayout, Color color)
347 {
348 switch (gridLayout.cellLayout)
349 {
350 case GridLayout.CellLayout.Hexagon:
351 return GenerateCachedHexagonalGridMesh(gridLayout, color);
352 case GridLayout.CellLayout.Isometric:
353 case GridLayout.CellLayout.IsometricZAsY:
354 case GridLayout.CellLayout.Rectangle:
355 var min = k_GridGizmoVertexCount / -32;
356 var max = min * -1;
357 var numCells = max - min;
358 var bounds = new RectInt(min, min, numCells, numCells);
359
360 return GenerateCachedGridMesh(gridLayout, color, 0f, bounds, MeshTopology.Lines);
361 }
362 return null;
363 }
364
365 public static Mesh GenerateCachedGridMesh(GridLayout gridLayout, Color color, float screenPixelSize, RectInt bounds, MeshTopology topology)
366 {
367 Mesh mesh = new Mesh();
368 mesh.hideFlags = HideFlags.HideAndDontSave;
369
370 int vertex = 0;
371
372 int totalVertices = topology == MeshTopology.Quads ?
373 8 * (bounds.size.x + bounds.size.y) :
374 4 * (bounds.size.x + bounds.size.y);
375
376 Vector3 horizontalPixelOffset = new Vector3(screenPixelSize, 0f, 0f);
377 Vector3 verticalPixelOffset = new Vector3(0f, screenPixelSize, 0f);
378
379 Vector3[] vertices = new Vector3[totalVertices];
380 Vector2[] uvs2 = new Vector2[totalVertices];
381
382 Vector3 cellStride = gridLayout.cellSize + gridLayout.cellGap;
383 Vector3Int minPosition = new Vector3Int(0, bounds.min.y, 0);
384 Vector3Int maxPosition = new Vector3Int(0, bounds.max.y, 0);
385
386 Vector3 cellGap = Vector3.zero;
387 if (!Mathf.Approximately(cellStride.x, 0f))
388 {
389 cellGap.x = gridLayout.cellSize.x / cellStride.x;
390 }
391
392 for (int x = bounds.min.x; x < bounds.max.x; x++)
393 {
394 minPosition.x = x;
395 maxPosition.x = x;
396
397 vertices[vertex + 0] = gridLayout.CellToLocal(minPosition);
398 vertices[vertex + 1] = gridLayout.CellToLocal(maxPosition);
399 uvs2[vertex + 0] = Vector2.zero;
400 uvs2[vertex + 1] = new Vector2(0f, cellStride.y * bounds.size.y);
401 if (topology == MeshTopology.Quads)
402 {
403 vertices[vertex + 2] = gridLayout.CellToLocal(maxPosition) + horizontalPixelOffset;
404 vertices[vertex + 3] = gridLayout.CellToLocal(minPosition) + horizontalPixelOffset;
405 uvs2[vertex + 2] = new Vector2(0f, cellStride.y * bounds.size.y);
406 uvs2[vertex + 3] = Vector2.zero;
407 }
408 vertex += topology == MeshTopology.Quads ? 4 : 2;
409
410 vertices[vertex + 0] = gridLayout.CellToLocalInterpolated(minPosition + cellGap);
411 vertices[vertex + 1] = gridLayout.CellToLocalInterpolated(maxPosition + cellGap);
412 uvs2[vertex + 0] = Vector2.zero;
413 uvs2[vertex + 1] = new Vector2(0f, cellStride.y * bounds.size.y);
414 if (topology == MeshTopology.Quads)
415 {
416 vertices[vertex + 2] = gridLayout.CellToLocalInterpolated(maxPosition + cellGap) + horizontalPixelOffset;
417 vertices[vertex + 3] = gridLayout.CellToLocalInterpolated(minPosition + cellGap) + horizontalPixelOffset;
418 uvs2[vertex + 2] = new Vector2(0f, cellStride.y * bounds.size.y);
419 uvs2[vertex + 3] = Vector2.zero;
420 }
421 vertex += topology == MeshTopology.Quads ? 4 : 2;
422 }
423
424 minPosition = new Vector3Int(bounds.min.x, 0, 0);
425 maxPosition = new Vector3Int(bounds.max.x, 0, 0);
426 cellGap = Vector3.zero;
427 if (!Mathf.Approximately(cellStride.y, 0f))
428 {
429 cellGap.y = gridLayout.cellSize.y / cellStride.y;
430 }
431
432 for (int y = bounds.min.y; y < bounds.max.y; y++)
433 {
434 minPosition.y = y;
435 maxPosition.y = y;
436
437 vertices[vertex + 0] = gridLayout.CellToLocal(minPosition);
438 vertices[vertex + 1] = gridLayout.CellToLocal(maxPosition);
439 uvs2[vertex + 0] = Vector2.zero;
440 uvs2[vertex + 1] = new Vector2(cellStride.x * bounds.size.x, 0f);
441 if (topology == MeshTopology.Quads)
442 {
443 vertices[vertex + 2] = gridLayout.CellToLocal(maxPosition) + verticalPixelOffset;
444 vertices[vertex + 3] = gridLayout.CellToLocal(minPosition) + verticalPixelOffset;
445 uvs2[vertex + 2] = new Vector2(cellStride.x * bounds.size.x, 0f);
446 uvs2[vertex + 3] = Vector2.zero;
447 }
448 vertex += topology == MeshTopology.Quads ? 4 : 2;
449
450 vertices[vertex + 0] = gridLayout.CellToLocalInterpolated(minPosition + cellGap);
451 vertices[vertex + 1] = gridLayout.CellToLocalInterpolated(maxPosition + cellGap);
452 uvs2[vertex + 0] = Vector2.zero;
453 uvs2[vertex + 1] = new Vector2(cellStride.x * bounds.size.x, 0f);
454 if (topology == MeshTopology.Quads)
455 {
456 vertices[vertex + 2] = gridLayout.CellToLocalInterpolated(maxPosition + cellGap) + verticalPixelOffset;
457 vertices[vertex + 3] = gridLayout.CellToLocalInterpolated(minPosition + cellGap) + verticalPixelOffset;
458 uvs2[vertex + 2] = new Vector2(cellStride.x * bounds.size.x, 0f);
459 uvs2[vertex + 3] = Vector2.zero;
460 }
461 vertex += topology == MeshTopology.Quads ? 4 : 2;
462 }
463
464 var uv0 = new Vector2(k_GridGizmoDistanceFalloff, 0f);
465 var uvs = new Vector2[vertex];
466 var indices = new int[vertex];
467 var colors = new Color[vertex];
468 var normals = new Vector3[totalVertices]; // Normal channel stores the position of the other end point of the line.
469 var uvs3 = new Vector2[totalVertices]; // UV3 channel stores the UV2 value of the other end point of the line.
470
471 for (int i = 0; i < vertex; i++)
472 {
473 uvs[i] = uv0;
474 indices[i] = i;
475 colors[i] = color;
476 var alternate = i + ((i % 2) == 0 ? 1 : -1);
477 normals[i] = vertices[alternate];
478 uvs3[i] = uvs2[alternate];
479 }
480
481 mesh.vertices = vertices;
482 mesh.uv = uvs;
483 mesh.uv2 = uvs2;
484 mesh.uv3 = uvs3;
485 mesh.colors = colors;
486 mesh.normals = normals;
487 mesh.SetIndices(indices, topology, 0);
488
489 return mesh;
490 }
491
492 private static Mesh GenerateCachedHexagonalGridMesh(GridLayout gridLayout, Color color)
493 {
494 Mesh mesh = new Mesh();
495 mesh.hideFlags = HideFlags.HideAndDontSave;
496 int vertex = 0;
497 int max = k_GridGizmoVertexCount / (2 * (6 * 2));
498 max = (max / 4) * 4;
499 int min = -max;
500 float numVerticalCells = 6 * (max / 4);
501 int totalVertices = max * 2 * 6 * 2;
502 var cellStrideY = gridLayout.cellGap.y + gridLayout.cellSize.y;
503 var cellOffsetY = gridLayout.cellSize.y / 2;
504 var hexOffset = (1.0f / 3.0f);
505 var drawTotal = numVerticalCells * 2.0f * hexOffset;
506 var drawDiagTotal = 2 * drawTotal;
507 Vector3[] vertices = new Vector3[totalVertices];
508 Vector2[] uvs2 = new Vector2[totalVertices];
509 // Draw Vertical Lines
510 for (int x = min; x < max; x++)
511 {
512 vertices[vertex] = gridLayout.CellToLocal(new Vector3Int(x, min, 0));
513 vertices[vertex + 1] = gridLayout.CellToLocal(new Vector3Int(x, max, 0));
514 uvs2[vertex] = new Vector2(0f, 2 * hexOffset);
515 uvs2[vertex + 1] = new Vector2(0f, 2 * hexOffset + drawTotal);
516 vertex += 2;
517 // Alternate Row Offset
518 vertices[vertex] = gridLayout.CellToLocal(new Vector3Int(x, min - 1, 0));
519 vertices[vertex + 1] = gridLayout.CellToLocal(new Vector3Int(x, max - 1, 0));
520 uvs2[vertex] = new Vector2(0f, 2 * hexOffset);
521 uvs2[vertex + 1] = new Vector2(0f, 2 * hexOffset + drawTotal);
522 vertex += 2;
523 }
524 // Draw Diagonals
525 for (int y = min; y < max; y++)
526 {
527 float drawDiagOffset = ((y + 1) % 3) * hexOffset;
528 var cellOffSet = Grid.Swizzle(gridLayout.cellSwizzle, new Vector3(0f, y * cellStrideY + cellOffsetY, 0.0f));
529 // Slope Up
530 vertices[vertex] = gridLayout.CellToLocal(new Vector3Int(Mathf.RoundToInt(1.5f * min), min, 0)) + cellOffSet;
531 vertices[vertex + 1] = gridLayout.CellToLocal(new Vector3Int(Mathf.RoundToInt(1.5f * max), max, 0)) + cellOffSet;
532 uvs2[vertex] = new Vector2(0f, drawDiagOffset);
533 uvs2[vertex + 1] = new Vector2(0f, drawDiagOffset + drawDiagTotal);
534 vertex += 2;
535 // Slope Down
536 vertices[vertex] = gridLayout.CellToLocal(new Vector3Int(Mathf.RoundToInt(1.5f * max), min, 0)) + cellOffSet;
537 vertices[vertex + 1] = gridLayout.CellToLocal(new Vector3Int(Mathf.RoundToInt(1.5f * min), max, 0)) + cellOffSet;
538 uvs2[vertex] = new Vector2(0f, drawDiagOffset);
539 uvs2[vertex + 1] = new Vector2(0f, drawDiagOffset + drawDiagTotal);
540 vertex += 2;
541 // Alternate Row Offset
542 vertices[vertex] = gridLayout.CellToLocal(new Vector3Int(Mathf.RoundToInt(1.5f * min) + 1, min, 0)) + cellOffSet;
543 vertices[vertex + 1] = gridLayout.CellToLocal(new Vector3Int(Mathf.RoundToInt(1.5f * max) + 1, max, 0)) + cellOffSet;
544 uvs2[vertex] = new Vector2(0f, drawDiagOffset);
545 uvs2[vertex + 1] = new Vector2(0f, drawDiagOffset + drawDiagTotal);
546 vertex += 2;
547 vertices[vertex] = gridLayout.CellToLocal(new Vector3Int(Mathf.RoundToInt(1.5f * max) + 1, min, 0)) + cellOffSet;
548 vertices[vertex + 1] = gridLayout.CellToLocal(new Vector3Int(Mathf.RoundToInt(1.5f * min) + 1, max, 0)) + cellOffSet;
549 uvs2[vertex] = new Vector2(0f, drawDiagOffset);
550 uvs2[vertex + 1] = new Vector2(0f, drawDiagOffset + drawDiagTotal);
551 vertex += 2;
552 }
553 var uv0 = new Vector2(k_GridGizmoDistanceFalloff, 0f);
554 var indices = new int[totalVertices];
555 var uvs = new Vector2[totalVertices];
556 var colors = new Color[totalVertices];
557 var normals = new Vector3[totalVertices]; // Normal channel stores the position of the other end point of the line.
558 var uvs3 = new Vector2[totalVertices]; // UV3 channel stores the UV2 value of the other end point of the line.
559
560 for (int i = 0; i < totalVertices; i++)
561 {
562 uvs[i] = uv0;
563 indices[i] = i;
564 colors[i] = color;
565 var alternate = i + ((i % 2) == 0 ? 1 : -1);
566 normals[i] = vertices[alternate];
567 uvs3[i] = uvs2[alternate];
568 }
569
570 mesh.vertices = vertices;
571 mesh.uv = uvs;
572 mesh.uv2 = uvs2;
573 mesh.uv3 = uvs3;
574 mesh.colors = colors;
575 mesh.normals = normals;
576 mesh.SetIndices(indices, MeshTopology.Lines, 0);
577 return mesh;
578 }
579 }
580}