@quenty/draw 7.8.0 → 7.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,14 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [7.8.1](https://github.com/Quenty/NevermoreEngine/compare/@quenty/draw@7.8.0...@quenty/draw@7.8.1) (2025-03-21)
7
+
8
+ **Note:** Version bump only for package @quenty/draw
9
+
10
+
11
+
12
+
13
+
6
14
  # [7.8.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/draw@7.7.1...@quenty/draw@7.8.0) (2025-02-18)
7
15
 
8
16
  **Note:** Version bump only for package @quenty/draw
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quenty/draw",
3
- "version": "7.8.0",
3
+ "version": "7.8.1",
4
4
  "description": "A utility library to debug things in 3D space for Roblox.",
5
5
  "keywords": [
6
6
  "Roblox",
@@ -32,5 +32,5 @@
32
32
  "@quenty/loader": "^10.8.0",
33
33
  "@quenty/maid": "^3.4.0"
34
34
  },
35
- "gitHead": "184a407d8d7366c39009444c3c9a7023cb176471"
35
+ "gitHead": "6b7c3e15e60cdb185986207b574e2b5591261e7a"
36
36
  }
@@ -37,7 +37,7 @@ Draw._defaultColor = ORIGINAL_DEFAULT_COLOR
37
37
  Sets the Draw's drawing color.
38
38
  @param color Color3 -- The color to set
39
39
  ]=]
40
- function Draw.setColor(color)
40
+ function Draw.setColor(color: Color3)
41
41
  Draw._defaultColor = color
42
42
  end
43
43
 
@@ -52,44 +52,57 @@ end
52
52
  Sets the Draw library to use a random color.
53
53
  ]=]
54
54
  function Draw.setRandomColor()
55
- Draw.setColor(Color3.fromHSV(math.random(), 0.5+0.5*math.random(), 1))
55
+ Draw.setColor(Color3.fromHSV(math.random(), 0.5 + 0.5 * math.random(), 1))
56
56
  end
57
57
 
58
58
  --[=[
59
59
  Draws a line between two points
60
60
 
61
+ ```lua
62
+ Draw.line(Vector3.new(0, 0, 0), Vector3.new(0, 10, 0))
63
+ ```
64
+
61
65
  @param start Vector3
62
66
  @param finish Vector3
63
- @param color Color3 -- Optional
67
+ @param color Color3? -- Optional
64
68
  @param parent Instance? -- Optional
65
- @param diameter number -- Optional
69
+ @param diameter numbe? -- Optional
66
70
  @return Instance
67
71
  ]=]
68
- function Draw.line(start, finish, color, parent, diameter)
72
+ function Draw.line(start: Vector3, finish: Vector3, color: Color3Like?, parent: Instance?, diameter: number?): BasePart
69
73
  start = assert(Draw._toVector3(start), "Bad start")
70
74
  finish = assert(Draw._toVector3(finish), "Bad finish")
71
- color = Draw._toColor3(color)
75
+ color = Draw._toColor3(color) or Draw._defaultColor
72
76
 
73
77
  return Draw.ray(Ray.new(start, finish - start), color, parent, diameter)
74
78
  end
75
79
 
76
80
  --[=[
77
- Draws a line between directions
81
+ Draws a line in a direction
82
+
83
+ ```lua
84
+ Draw.direction(Vector3.new(0, 0, 0), Vector3.new(0, 10, 0))
85
+ ```
78
86
 
79
87
  @param origin Vector3
80
88
  @param direction Vector3
81
89
  @param color Color3 -- Optional
82
90
  @param parent Instance? -- Optional
83
- @param meshDiameter number -- Optional
84
- @param diameter number -- Optional
91
+ @param diameter number? -- Optional
85
92
  @return Instance
86
93
  ]=]
87
- function Draw.direction(origin, direction, color, parent, meshDiameter, diameter)
94
+ function Draw.direction(
95
+ origin: Vector3,
96
+ direction: Vector3,
97
+ color: Color3?,
98
+ parent: Instance?,
99
+ diameter: number?
100
+ ): BasePart
88
101
  origin = assert(Draw._toVector3(origin), "Bad origin")
89
102
  direction = assert(Draw._toVector3(direction), "Bad direction")
90
103
  color = Draw._toColor3(color)
91
104
 
92
- return Draw.ray(Ray.new(origin, direction), color, parent, meshDiameter, diameter)
105
+ return Draw.ray(Ray.new(origin, direction), color, parent, diameter)
93
106
  end
94
107
 
95
108
  --[=[
@@ -100,25 +113,35 @@ end
100
113
  that initially intersect the shape. So this draw doesn't render that initial sphere.
101
114
  :::
102
115
 
116
+ ```lua
117
+ Draw.spherecast(Vector3.new(0, 0, 0), 10, Vector3.new(0, 10, 0))
118
+ ```
119
+
103
120
  @param origin Vector3
104
121
  @param radius number
105
122
  @param direction Vector3
106
- @param color Color3
107
- @param parent Parent
123
+ @param color Color3?:
124
+ @param parent Instance?
108
125
  ]=]
109
- function Draw.spherecast(origin, radius, direction, color, parent)
110
- origin = assert(Draw._toVector3(origin), "Bad cframe")
126
+ function Draw.spherecast(
127
+ origin: Vector3Like,
128
+ radius: number,
129
+ direction: Vector3Like,
130
+ color: Color3Like?,
131
+ parent: Instance?
132
+ ): Folder
111
133
  assert(type(radius) == "number", "Bad radius")
112
- direction = assert(Draw._toVector3(direction), "Bad direction")
113
- color = Draw._toColor3(color)
134
+ local castOrigin = assert(Draw._toVector3(origin), "Bad cframe")
135
+ local castDirection = assert(Draw._toVector3(direction), "Bad direction")
136
+ local castColor = Draw._toColor3(color) or Draw._defaultColor
114
137
  parent = parent or Draw.getDefaultParent()
115
138
 
116
139
  local folder = Instance.new("Folder")
117
140
  folder.Name = "SphereCast"
118
141
  folder.Archivable = false
119
142
 
120
- Draw.ray(Ray.new(origin, direction), color, folder, 2*radius)
121
- Draw.sphere(origin + direction, radius, color, folder)
143
+ Draw.ray(Ray.new(castOrigin, castDirection), color, folder, 2 * radius)
144
+ Draw.sphere(castOrigin + direction, radius, castColor, folder)
122
145
 
123
146
  folder.Parent = parent
124
147
 
@@ -134,11 +157,17 @@ end
134
157
  @param color Color3
135
158
  @param parent Parent
136
159
  ]=]
137
- function Draw.blockcast(cframe, size, direction, color, parent)
138
- cframe = assert(Draw._toCFrame(cframe), "Bad cframe")
139
- size = assert(Draw._toVector3(size), "Bad size")
140
- direction = assert(Draw._toVector3(direction), "Bad direction")
141
- color = Draw._toColor3(color)
160
+ function Draw.blockcast(
161
+ cframe: CFrameLike,
162
+ size: Vector3Like,
163
+ direction: Vector3Like,
164
+ color: Color3Like?,
165
+ parent: Instance?
166
+ ): Folder
167
+ local blockCFrame = assert(Draw._toCFrame(cframe), "Bad cframe")
168
+ local blockSize = assert(Draw._toVector3(size), "Bad size")
169
+ local blockDirection = assert(Draw._toVector3(direction), "Bad direction")
170
+ local blockColor = Draw._toColor3(color)
142
171
  parent = parent or Draw.getDefaultParent()
143
172
 
144
173
  local folder = Instance.new("Folder")
@@ -147,26 +176,42 @@ function Draw.blockcast(cframe, size, direction, color, parent)
147
176
 
148
177
  -- Draw beginning and end for now...
149
178
  -- TODO: Convex hull
150
- Draw.box(cframe, size, color).Parent = folder
151
- Draw.box(cframe + direction, size, color).Parent = folder
179
+ Draw.box(blockCFrame, blockSize, blockColor).Parent = folder
180
+ Draw.box(blockCFrame + blockDirection, blockSize, blockColor).Parent = folder
152
181
 
153
182
  folder.Parent = parent
154
183
 
155
184
  return folder
156
185
  end
157
186
 
158
- function Draw.triangle(a, b, c, color, parent)
159
- a = assert(Draw._toVector3(a), "Bad a")
160
- b = assert(Draw._toVector3(b), "Bad b")
161
- c = assert(Draw._toVector3(c), "Bad c")
187
+ --[=[
188
+ Draws a triangle between 3 points
189
+
190
+ @param pointA Vector3
191
+ @param pointB Vector3
192
+ @param pointC Vector3
193
+ @param color Color3? -- Optional color3
194
+ @param parent Instance? -- Optional parent
195
+ @return Folder
196
+ ]=]
197
+ function Draw.triangle(
198
+ pointA: Vector3Like,
199
+ pointB: Vector3Like,
200
+ pointC: Vector3Like,
201
+ color: Color3Like?,
202
+ parent: Instance?
203
+ ): Folder
204
+ local a = assert(Draw._toVector3(pointA), "Bad a")
205
+ local b = assert(Draw._toVector3(pointB), "Bad b")
206
+ local c = assert(Draw._toVector3(pointC), "Bad c")
162
207
  color = Draw._toColor3(color) or Draw._defaultColor
163
208
  parent = parent or Draw.getDefaultParent()
164
209
 
165
210
  local edges = {
166
- {longest = (c - a), other = (b - a), origin = a},
167
- {longest = (a - b), other = (c - b), origin = b},
168
- {longest = (b - c), other = (a - c), origin = c}
169
- };
211
+ { longest = (c - a), other = (b - a), origin = a },
212
+ { longest = (a - b), other = (c - b), origin = b },
213
+ { longest = (b - c), other = (a - c), origin = c },
214
+ }
170
215
 
171
216
  local edge = edges[1]
172
217
  for i = 2, #edges do
@@ -180,26 +225,16 @@ function Draw.triangle(a, b, c, color, parent)
180
225
  local w2 = edge.longest.magnitude - w1
181
226
  local h = math.sin(theta) * edge.other.magnitude
182
227
 
183
- local p1 = edge.origin + edge.other * 0.5;
228
+ local p1 = edge.origin + edge.other * 0.5
184
229
  local p2 = edge.origin + edge.longest + (edge.other - edge.longest) * 0.5
185
230
 
186
231
  local right = edge.longest:Cross(edge.other).unit
187
232
  local up = right:Cross(edge.longest).unit
188
233
  local back = edge.longest.unit
189
234
 
190
- local cf1 = CFrame.new(
191
- p1.x, p1.y, p1.z,
192
- -right.x, up.x, back.x,
193
- -right.y, up.y, back.y,
194
- -right.z, up.z, back.z
195
- );
235
+ local cf1 = CFrame.new(p1.x, p1.y, p1.z, -right.x, up.x, back.x, -right.y, up.y, back.y, -right.z, up.z, back.z)
196
236
 
197
- local cf2 = CFrame.new(
198
- p2.x, p2.y, p2.z,
199
- right.x, up.x, -back.x,
200
- right.y, up.y, -back.y,
201
- right.z, up.z, -back.z
202
- );
237
+ local cf2 = CFrame.new(p2.x, p2.y, p2.z, right.x, up.x, -back.x, right.y, up.y, -back.y, right.z, up.z, -back.z)
203
238
 
204
239
  -- put it all together by creating the wedges
205
240
  local triangle = Instance.new("Folder")
@@ -259,12 +294,17 @@ end
259
294
  @param direction Vector3
260
295
  @param color Color3 -- Optional
261
296
  @param parent Instance? -- Optional
262
- @param meshDiameter number -- Optional
263
- @param diameter number -- Optional
297
+ @param diameter number? -- Optional
264
298
  @return Instance
265
299
  ]=]
266
- function Draw.raycast(origin, direction, color, parent, meshDiameter, diameter)
267
- return Draw.direction(origin, direction, color, parent, meshDiameter, diameter)
300
+ function Draw.raycast(
301
+ origin: Vector3,
302
+ direction: Vector3,
303
+ color: Color3?,
304
+ parent: Instance?,
305
+ diameter: number?
306
+ ): BasePart
307
+ return Draw.direction(origin, direction, color, parent, diameter)
268
308
  end
269
309
 
270
310
  --[=[
@@ -281,14 +321,14 @@ end
281
321
  @param diameter number? -- Optional diameter
282
322
  @return BasePart
283
323
  ]=]
284
- function Draw.ray(ray, color, parent, diameter)
324
+ function Draw.ray(ray: Ray, color: Color3Like?, parent: Instance?, diameter: number?): BasePart
285
325
  assert(typeof(ray) == "Ray", "Bad typeof(ray) for Ray")
286
326
 
287
- color = Draw._toColor3(color) or Draw._defaultColor
288
- parent = parent or Draw.getDefaultParent()
289
- diameter = diameter or 0.2
327
+ local rayColor = Draw._toColor3(color) or Draw._defaultColor
328
+ local rayParent = parent or Draw.getDefaultParent()
329
+ local rayDiameter = diameter or 0.2
290
330
 
291
- local rayCenter = ray.Origin + ray.Direction/2
331
+ local rayCenter = ray.Origin + ray.Direction / 2
292
332
  local distance = ray.Direction.Magnitude
293
333
 
294
334
  local part = Instance.new("Part")
@@ -299,11 +339,11 @@ function Draw.ray(ray, color, parent, diameter)
299
339
  part.CanQuery = false
300
340
  part.CanTouch = false
301
341
  part.CastShadow = false
302
- part.CFrame = CFrame.new(rayCenter, ray.Origin + ray.Direction) * CFrame.Angles(0, math.pi/2, 0)
303
- part.Color = color
342
+ part.CFrame = CFrame.new(rayCenter, ray.Origin + ray.Direction) * CFrame.Angles(0, math.pi / 2, 0)
343
+ part.Color = rayColor
304
344
  part.Name = "DebugRay"
305
345
  part.Shape = Enum.PartType.Cylinder
306
- part.Size = Vector3.new(distance, diameter, diameter)
346
+ part.Size = Vector3.new(distance, rayDiameter, rayDiameter)
307
347
  part.TopSurface = Enum.SurfaceType.Smooth
308
348
  part.Transparency = 0.5
309
349
 
@@ -311,12 +351,12 @@ function Draw.ray(ray, color, parent, diameter)
311
351
  cylinderHandleAdornment.Name = "CylinderHandleAdornment"
312
352
  cylinderHandleAdornment.Height = ray.Direction.Magnitude
313
353
  cylinderHandleAdornment.InnerRadius = 0
314
- cylinderHandleAdornment.Radius = diameter/4
354
+ cylinderHandleAdornment.Radius = rayDiameter / 4
315
355
  cylinderHandleAdornment.ZIndex = 3
316
- cylinderHandleAdornment.Color3 = color
356
+ cylinderHandleAdornment.Color3 = rayColor
317
357
  cylinderHandleAdornment.AlwaysOnTop = true
318
358
  cylinderHandleAdornment.Transparency = 0.25
319
- cylinderHandleAdornment.CFrame = CFrame.Angles(0, math.pi/2, 0)
359
+ cylinderHandleAdornment.CFrame = CFrame.Angles(0, math.pi / 2, 0)
320
360
  cylinderHandleAdornment.Adornee = part
321
361
  cylinderHandleAdornment.Parent = part
322
362
 
@@ -325,10 +365,10 @@ function Draw.ray(ray, color, parent, diameter)
325
365
  local mesh = Instance.new("SpecialMesh")
326
366
  mesh.MeshType = Enum.MeshType.Cylinder
327
367
  mesh.Name = "DrawRayMesh"
328
- mesh.Scale = Vector3.new(distance/partSize.x, diameter/partSize.y, diameter/partSize.z)
368
+ mesh.Scale = Vector3.new(distance / partSize.x, rayDiameter / partSize.y, rayDiameter / partSize.z)
329
369
  mesh.Parent = part
330
370
 
331
- part.Parent = parent
371
+ part.Parent = rayParent
332
372
 
333
373
  return part
334
374
  end
@@ -350,33 +390,33 @@ end
350
390
 
351
391
  @param rayPart Instance -- Ray part
352
392
  @param ray Ray -- New ray
353
- @param color Color3 -- New color
354
- @param diameter number -- Number
393
+ @param color Color3? -- New color
394
+ @param diameter number? -- Number
355
395
  ]=]
356
- function Draw.updateRay(rayPart, ray, color, diameter)
396
+ function Draw.updateRay(rayPart: BasePart, ray: Ray, color: Color3?, diameter: number?)
357
397
  assert(typeof(rayPart) == "Instance", "Bad rayPart")
358
398
  assert(typeof(ray) == "Ray", "Bad typeof(ray) for Ray")
359
- color = Draw._toColor3(color) or rayPart.Color
360
- diameter = diameter or rayPart.Size.z
399
+ local rayColor = Draw._toColor3(color) or rayPart.Color
400
+ local rayDiameter = diameter or rayPart.Size.Z
361
401
 
362
- local rayCenter = ray.Origin + ray.Direction/2
402
+ local rayCenter = ray.Origin + ray.Direction / 2
363
403
  local distance = ray.Direction.Magnitude
364
404
 
365
- rayPart.Color = color
405
+ rayPart.Color = rayColor
366
406
  rayPart.Size = Vector3.new(distance, diameter, diameter)
367
- rayPart.CFrame = CFrame.new(rayCenter, ray.Origin + ray.Direction) * CFrame.Angles(0, math.pi/2, 0)
407
+ rayPart.CFrame = CFrame.new(rayCenter, ray.Origin + ray.Direction) * CFrame.Angles(0, math.pi / 2, 0)
368
408
 
369
409
  local cylinderHandleAdornment = rayPart:FindFirstChildWhichIsA("CylinderHandleAdornment")
370
410
  if cylinderHandleAdornment then
371
411
  cylinderHandleAdornment.Height = ray.Direction.Magnitude
372
- cylinderHandleAdornment.Radius = diameter/4
373
- cylinderHandleAdornment.Color3 = color
412
+ cylinderHandleAdornment.Radius = rayDiameter / 4
413
+ cylinderHandleAdornment.Color3 = rayColor
374
414
  end
375
415
 
376
416
  local partSize = rayPart.Size
377
417
  local mesh = rayPart:FindFirstChildWhichIsA("SpecialMesh")
378
418
  if mesh then
379
- mesh.Scale = Vector3.new(distance/partSize.x, diameter/partSize.y, diameter/partSize.z)
419
+ mesh.Scale = Vector3.new(distance / partSize.x, rayDiameter / partSize.y, rayDiameter / partSize.z)
380
420
  end
381
421
  end
382
422
 
@@ -393,8 +433,8 @@ end
393
433
  @param color Color3? -- Optional color to render
394
434
  @return Instance
395
435
  ]=]
396
- function Draw.text(adornee, text, color)
397
- color = Draw._toColor3(color)
436
+ function Draw.text(adornee: Instance | Vector3, text: string, color: Color3Like?): Instance
437
+ local textColor = Draw._toColor3(color) or Draw._defaultColor
398
438
 
399
439
  if typeof(adornee) == "Vector3" then
400
440
  local attachment = Instance.new("Attachment")
@@ -402,23 +442,23 @@ function Draw.text(adornee, text, color)
402
442
  attachment.Parent = Terrain
403
443
  attachment.Name = "DebugTextAttachment"
404
444
 
405
- Draw._textOnAdornee(attachment, text, color)
445
+ Draw._textOnAdornee(attachment, text, textColor)
406
446
 
407
447
  return attachment
408
448
  elseif typeof(adornee) == "Instance" then
409
- return Draw._textOnAdornee(adornee, text, color)
449
+ return Draw._textOnAdornee(adornee, text, textColor)
410
450
  else
411
451
  error("Bad adornee")
412
452
  end
413
453
  end
414
454
 
415
- function Draw._textOnAdornee(adornee, text, color)
455
+ function Draw._textOnAdornee(adornee: Instance, text: string, color: Color3): BillboardGui
416
456
  local TEXT_HEIGHT_STUDS = 2
417
457
  local PADDING_PERCENT_OF_LINE_HEIGHT = 0.5
418
458
 
419
459
  local billboardGui = Instance.new("BillboardGui")
420
460
  billboardGui.Name = "DebugBillboardGui"
421
- billboardGui.SizeOffset = Vector2.new(0, 0.5)
461
+ billboardGui.SizeOffset = Vector2.new(0, 0.5)
422
462
  billboardGui.ExtentsOffset = Vector3.new(0, 1, 0)
423
463
  billboardGui.AlwaysOnTop = true
424
464
  billboardGui.Adornee = adornee
@@ -431,7 +471,7 @@ function Draw._textOnAdornee(adornee, text, color)
431
471
  background.AnchorPoint = Vector2.new(0.5, 1)
432
472
  background.BackgroundTransparency = 0.3
433
473
  background.BorderSizePixel = 0
434
- background.BackgroundColor3 = color or Draw._defaultColor
474
+ background.BackgroundColor3 = color
435
475
  background.Parent = billboardGui
436
476
 
437
477
  local textLabel = Instance.new("TextLabel")
@@ -450,37 +490,33 @@ function Draw._textOnAdornee(adornee, text, color)
450
490
  textLabel.Font = Enum.Font.GothamMedium
451
491
  end
452
492
 
453
- local textSize = TextService:GetTextSize(
454
- textLabel.Text,
455
- textLabel.TextSize,
456
- textLabel.Font,
457
- Vector2.new(1024, 1e6))
493
+ local textSize = TextService:GetTextSize(textLabel.Text, textLabel.TextSize, textLabel.Font, Vector2.new(1024, 1e6))
458
494
 
459
- local lines = textSize.y/textLabel.TextSize
495
+ local lines = textSize.y / textLabel.TextSize
460
496
 
461
- local paddingOffset = textLabel.TextSize*PADDING_PERCENT_OF_LINE_HEIGHT
462
- local paddedHeight = textSize.y + 2*paddingOffset
463
- local paddedWidth = textSize.x + 2*paddingOffset
464
- local aspectRatio = paddedWidth/paddedHeight
497
+ local paddingOffset = textLabel.TextSize * PADDING_PERCENT_OF_LINE_HEIGHT
498
+ local paddedHeight = textSize.y + 2 * paddingOffset
499
+ local paddedWidth = textSize.x + 2 * paddingOffset
500
+ local aspectRatio = paddedWidth / paddedHeight
465
501
 
466
502
  local uiAspectRatio = Instance.new("UIAspectRatioConstraint")
467
503
  uiAspectRatio.AspectRatio = aspectRatio
468
504
  uiAspectRatio.Parent = background
469
505
 
470
506
  local uiPadding = Instance.new("UIPadding")
471
- uiPadding.PaddingBottom = UDim.new(paddingOffset/paddedHeight, 0)
472
- uiPadding.PaddingTop = UDim.new(paddingOffset/paddedHeight, 0)
473
- uiPadding.PaddingLeft = UDim.new(paddingOffset/paddedWidth, 0)
474
- uiPadding.PaddingRight = UDim.new(paddingOffset/paddedWidth, 0)
507
+ uiPadding.PaddingBottom = UDim.new(paddingOffset / paddedHeight, 0)
508
+ uiPadding.PaddingTop = UDim.new(paddingOffset / paddedHeight, 0)
509
+ uiPadding.PaddingLeft = UDim.new(paddingOffset / paddedWidth, 0)
510
+ uiPadding.PaddingRight = UDim.new(paddingOffset / paddedWidth, 0)
475
511
  uiPadding.Parent = background
476
512
 
477
513
  local uiCorner = Instance.new("UICorner")
478
- uiCorner.CornerRadius = UDim.new(paddingOffset/paddedHeight/2, 0)
514
+ uiCorner.CornerRadius = UDim.new(paddingOffset / paddedHeight / 2, 0)
479
515
  uiCorner.Parent = background
480
516
 
481
- local height = lines*TEXT_HEIGHT_STUDS * TEXT_HEIGHT_STUDS*PADDING_PERCENT_OF_LINE_HEIGHT
517
+ local height = lines * TEXT_HEIGHT_STUDS * TEXT_HEIGHT_STUDS * PADDING_PERCENT_OF_LINE_HEIGHT
482
518
 
483
- billboardGui.Size = UDim2.new(height*aspectRatio, 0, height, 0)
519
+ billboardGui.Size = UDim2.new(height * aspectRatio, 0, height, 0)
484
520
  billboardGui.Parent = adornee
485
521
 
486
522
  return billboardGui
@@ -501,8 +537,8 @@ end
501
537
  @param parent Instance? -- Optional parent
502
538
  @return BasePart
503
539
  ]=]
504
- function Draw.sphere(position, radius, color, parent)
505
- return Draw.point(position, color, parent, radius*2)
540
+ function Draw.sphere(position: Vector3Like, radius: number, color: Color3?, parent: Instance)
541
+ return Draw.point(position, color, parent, radius * 2)
506
542
  end
507
543
 
508
544
  --[=[
@@ -518,12 +554,11 @@ end
518
554
  @param diameter number? -- Optional diameter
519
555
  @return BasePart
520
556
  ]=]
521
- function Draw.point(position, color, parent, diameter)
522
- position = assert(Draw._toVector3(position), "Bad position")
523
- color = Draw._toColor3(color) or Draw._defaultColor
524
-
525
- parent = parent or Draw.getDefaultParent()
526
- diameter = diameter or 1
557
+ function Draw.point(position: Vector3Like, color: Color3Like?, parent: Instance?, diameter: number?): BasePart
558
+ local pointPosition = assert(Draw._toVector3(position), "Bad position")
559
+ local pointColor = Draw._toColor3(color) or Draw._defaultColor
560
+ local pointParent = parent or Draw.getDefaultParent()
561
+ local pointDiameter = diameter or 1
527
562
 
528
563
  local part = Instance.new("Part")
529
564
  part.Material = Enum.Material.ForceField
@@ -534,25 +569,25 @@ function Draw.point(position, color, parent, diameter)
534
569
  part.CanQuery = false
535
570
  part.CanTouch = false
536
571
  part.CastShadow = false
537
- part.CFrame = CFrame.new(position)
538
- part.Color = color
572
+ part.CFrame = CFrame.new(pointPosition)
573
+ part.Color = pointColor
539
574
  part.Name = "DebugPoint"
540
575
  part.Shape = Enum.PartType.Ball
541
- part.Size = Vector3.new(diameter, diameter, diameter)
576
+ part.Size = Vector3.new(pointDiameter, pointDiameter, pointDiameter)
542
577
  part.TopSurface = Enum.SurfaceType.Smooth
543
578
  part.Transparency = 0.5
544
579
 
545
580
  local sphereHandle = Instance.new("SphereHandleAdornment")
546
581
  sphereHandle.Archivable = false
547
582
  sphereHandle.Transparency = 0.25
548
- sphereHandle.Radius = diameter/4
549
- sphereHandle.Color3 = color
583
+ sphereHandle.Radius = pointDiameter / 4
584
+ sphereHandle.Color3 = pointColor
550
585
  sphereHandle.AlwaysOnTop = true
551
586
  sphereHandle.Adornee = part
552
587
  sphereHandle.ZIndex = 2
553
588
  sphereHandle.Parent = part
554
589
 
555
- part.Parent = parent
590
+ part.Parent = pointParent
556
591
 
557
592
  return part
558
593
  end
@@ -570,7 +605,7 @@ end
570
605
  @param parent Instance? -- Optional parent
571
606
  @return BasePart
572
607
  ]=]
573
- function Draw.labelledPoint(position, label, color, parent)
608
+ function Draw.labelledPoint(position: Vector3Like, label: string, color: Color3Like?, parent: Instance?): BasePart
574
609
  position = assert(Draw._toVector3(position), "Bad position")
575
610
  color = Draw._toColor3(color)
576
611
 
@@ -591,31 +626,22 @@ end
591
626
  @param cframe CFrame
592
627
  @return Model
593
628
  ]=]
594
- function Draw.cframe(cframe)
595
- cframe = assert(Draw._toCFrame(cframe), "Bad cframe")
629
+ function Draw.cframe(cframe: CFrameLike): Model
630
+ local drawCFrame = assert(Draw._toCFrame(cframe), "Bad cframe")
596
631
 
597
632
  local model = Instance.new("Model")
598
633
  model.Name = "DebugCFrame"
599
634
 
600
- local position = cframe.Position
635
+ local position = drawCFrame.Position
601
636
  Draw.point(position, nil, model, 0.1)
602
637
 
603
- local xRay = Draw.ray(Ray.new(
604
- position,
605
- cframe.XVector
606
- ), Color3.new(0.75, 0.25, 0.25), model, 0.1)
638
+ local xRay = Draw.ray(Ray.new(position, drawCFrame.XVector), Color3.new(0.75, 0.25, 0.25), model, 0.1)
607
639
  xRay.Name = "XVector"
608
640
 
609
- local yRay = Draw.ray(Ray.new(
610
- position,
611
- cframe.YVector
612
- ), Color3.new(0.25, 0.75, 0.25), model, 0.1)
641
+ local yRay = Draw.ray(Ray.new(position, drawCFrame.YVector), Color3.new(0.25, 0.75, 0.25), model, 0.1)
613
642
  yRay.Name = "YVector"
614
643
 
615
- local zRay = Draw.ray(Ray.new(
616
- position,
617
- cframe.ZVector
618
- ), Color3.new(0.25, 0.25, 0.75), model, 0.1)
644
+ local zRay = Draw.ray(Ray.new(position, drawCFrame.ZVector), Color3.new(0.25, 0.25, 0.75), model, 0.1)
619
645
  zRay.Name = "ZVector"
620
646
 
621
647
  model.Parent = Draw.getDefaultParent()
@@ -633,13 +659,14 @@ end
633
659
  @param template BasePart
634
660
  @param cframe CFrame
635
661
  @param color Color3?
636
- @param transparency number
662
+ @param transparency number?
637
663
  @return BasePart
638
664
  ]=]
639
- function Draw.part(template, cframe, color, transparency)
665
+ function Draw.part(template: BasePart, cframe: CFrameLike?, color: Color3Like?, transparency: number?): BasePart
640
666
  assert(typeof(template) == "Instance" and template:IsA("BasePart"), "Bad template")
641
- cframe = Draw._toCFrame(cframe)
642
- color = Draw._toColor3(color)
667
+
668
+ local partCFrame = Draw._toCFrame(cframe)
669
+ local partColor = Draw._toColor3(color) or Draw._defaultColor
643
670
 
644
671
  local part = template:Clone()
645
672
  for _, child in pairs(part:GetChildren()) do
@@ -651,7 +678,7 @@ function Draw.part(template, cframe, color, transparency)
651
678
  end
652
679
  end
653
680
 
654
- part.Color = color or Draw._defaultColor
681
+ part.Color = partColor
655
682
  part.Material = Enum.Material.ForceField
656
683
  part.Transparency = transparency or 0.75
657
684
  part.Name = "Debug" .. template.Name
@@ -662,8 +689,8 @@ function Draw.part(template, cframe, color, transparency)
662
689
  part.CastShadow = false
663
690
  part.Archivable = false
664
691
 
665
- if cframe then
666
- part.CFrame = cframe
692
+ if partCFrame then
693
+ part.CFrame = partCFrame
667
694
  end
668
695
 
669
696
  Draw._sanitize(part)
@@ -673,12 +700,12 @@ function Draw.part(template, cframe, color, transparency)
673
700
  return part
674
701
  end
675
702
 
676
- function Draw._sanitize(inst)
677
- for key, _ in pairs(inst:GetAttributes()) do
703
+ function Draw._sanitize(inst: Instance)
704
+ for key, _ in inst:GetAttributes() do
678
705
  inst:SetAttribute(key, nil)
679
706
  end
680
707
 
681
- for _, tag in pairs(CollectionService:GetTags(inst)) do
708
+ for _, tag in CollectionService:GetTags(inst) do
682
709
  CollectionService:RemoveTag(inst, tag)
683
710
  end
684
711
  end
@@ -692,21 +719,16 @@ end
692
719
 
693
720
  @param cframe CFrame | Vector3 -- CFrame of the box
694
721
  @param size Vector3 -- Size of the box
695
- @param color Color3 -- Optional Color3
722
+ @param color Color3? -- Optional Color3
696
723
  @return BasePart
697
724
  ]=]
698
- function Draw.box(cframe, size, color)
725
+ function Draw.box(cframe: CFrameLike, size: Vector3Like, color: Color3Like?): BasePart
699
726
  cframe = assert(Draw._toCFrame(cframe), "Bad cframe")
700
727
  size = assert(Draw._toVector3(size), "Bad size")
701
- color = Draw._toColor3(color)
702
-
703
- assert(typeof(cframe) == "CFrame", "Bad cframe")
704
- assert(typeof(size) == "Vector3", "Bad size")
705
-
706
- color = color or Draw._defaultColor
728
+ local boxColor = Draw._toColor3(color) or Draw._defaultColor
707
729
 
708
730
  local part = Instance.new("Part")
709
- part.Color = color
731
+ part.Color = boxColor
710
732
  part.Material = Enum.Material.ForceField
711
733
  part.Name = "DebugPart"
712
734
  part.Anchored = true
@@ -724,7 +746,7 @@ function Draw.box(cframe, size, color)
724
746
  local boxHandleAdornment = Instance.new("BoxHandleAdornment")
725
747
  boxHandleAdornment.Adornee = part
726
748
  boxHandleAdornment.Size = size
727
- boxHandleAdornment.Color3 = color
749
+ boxHandleAdornment.Color3 = boxColor
728
750
  boxHandleAdornment.AlwaysOnTop = true
729
751
  boxHandleAdornment.Transparency = 0.75
730
752
  boxHandleAdornment.ZIndex = 1
@@ -746,7 +768,7 @@ end
746
768
  @param color Color3? -- Optional color3
747
769
  @return BasePart
748
770
  ]=]
749
- function Draw.region3(region3, color)
771
+ function Draw.region3(region3: Region3, color: Color3Like?): BasePart
750
772
  color = Draw._toColor3(color)
751
773
 
752
774
  return Draw.box(region3.CFrame, region3.Size, color)
@@ -764,7 +786,7 @@ end
764
786
  @param color Color3? -- Optional color to render
765
787
  @return BasePart
766
788
  ]=]
767
- function Draw.terrainCell(position, color)
789
+ function Draw.terrainCell(position: Vector3Like, color: Color3Like?): BasePart
768
790
  position = assert(Draw._toVector3(position), "Bad position")
769
791
  color = Draw._toColor3(color)
770
792
 
@@ -779,12 +801,14 @@ function Draw.terrainCell(position, color)
779
801
  return part
780
802
  end
781
803
 
782
- function Draw.screenPointLine(a, b, parent, color)
783
- color = Draw._toColor3(color)
804
+ --[=[
805
+ Draws a screen point line
806
+ ]=]
807
+ function Draw.screenPointLine(a: Vector2, b: Vector2, parent: Instance?, color: Color3Like): Frame
808
+ color = Draw._toColor3(color) or Draw._defaultColor
784
809
 
785
810
  local offset = (b - a)
786
- local pos = a + offset/2
787
-
811
+ local pos = a + offset / 2
788
812
 
789
813
  local frame = Instance.new("Frame")
790
814
  frame.Name = "DebugScreenLine"
@@ -805,21 +829,24 @@ function Draw.screenPointLine(a, b, parent, color)
805
829
  local diameter = 3
806
830
  local count = 25
807
831
 
808
- local slope = offset.y/offset.x
832
+ local slope = offset.y / offset.x
809
833
  if slope > 0 then
810
- for i=0, count do
811
- Draw.screenPoint(Vector2.new(i/count, i/count), frame, color, diameter)
834
+ for i = 0, count do
835
+ Draw.screenPoint(Vector2.new(i / count, i / count), frame, color, diameter)
812
836
  end
813
837
  else
814
- for i=0, count do
815
- Draw.screenPoint(Vector2.new(i/count, 1 - i/count), frame, color, diameter)
838
+ for i = 0, count do
839
+ Draw.screenPoint(Vector2.new(i / count, 1 - i / count), frame, color, diameter)
816
840
  end
817
841
  end
818
842
 
819
843
  return frame
820
844
  end
821
845
 
822
- function Draw.screenPoint(position, parent, color, diameter)
846
+ --[=[
847
+ Draws a screen point
848
+ ]=]
849
+ function Draw.screenPoint(position: Vector2, parent: Instance, color: Color3Like?, diameter: number?): Frame
823
850
  color = Draw._toColor3(color)
824
851
 
825
852
  local frame = Instance.new("Frame")
@@ -827,7 +854,7 @@ function Draw.screenPoint(position, parent, color, diameter)
827
854
  frame.Size = UDim2.new(0, diameter, 0, diameter)
828
855
  frame.BackgroundColor3 = color or Color3.new(1, 0.1, 0.1)
829
856
  frame.BackgroundTransparency = 0.5
830
- frame.Position = UDim2.fromScale(position.x, position.y)
857
+ frame.Position = UDim2.fromScale(position.X, position.Y)
831
858
  frame.AnchorPoint = Vector2.new(0.5, 0.5)
832
859
  frame.BorderSizePixel = 0
833
860
  frame.ZIndex = 20000
@@ -854,12 +881,18 @@ end
854
881
  @param meshDiameter number? -- Optional diameter
855
882
  @return BasePart
856
883
  ]=]
857
- function Draw.vector(position, direction, color, parent, meshDiameter)
858
- position = assert(Draw._toVector3(position), "Bad position")
859
- direction = assert(Draw._toVector3(direction), "Bad direction")
860
- color = Draw._toColor3(color)
861
-
862
- return Draw.ray(Ray.new(position, direction), color, parent, meshDiameter)
884
+ function Draw.vector(
885
+ position: Vector3Like,
886
+ direction: Vector3Like,
887
+ color: Color3?,
888
+ parent: Instance?,
889
+ meshDiameter: number?
890
+ )
891
+ local vectorPosition = assert(Draw._toVector3(position), "Bad position")
892
+ local vectorDirection = assert(Draw._toVector3(direction), "Bad direction")
893
+ local vectorColor = Draw._toColor3(color)
894
+
895
+ return Draw.ray(Ray.new(vectorPosition, vectorDirection), vectorColor, parent, meshDiameter)
863
896
  end
864
897
 
865
898
  --[=[
@@ -869,23 +902,25 @@ end
869
902
  Draw.ring(Vector3.new(0, 0, 0), Vector3.new(0, 1, 0), 10)
870
903
  ```
871
904
 
872
- @param ringPos Vector3 -- Position of the center of the ring
873
- @param ringNorm Vector3 -- Direction of the ring.
874
- @param ringRadius number? -- Optional radius for the ring
905
+ @param position Vector3 -- Position of the center of the ring
906
+ @param normal Vector3 -- Direction of the ring.
907
+ @param radius number? -- Optional radius for the ring
875
908
  @param color Color3? -- Optional color
876
909
  @param parent Instance? -- Optional instance
877
910
  @return BasePart
878
911
  ]=]
879
- function Draw.ring(ringPos, ringNorm, ringRadius, color, parent)
880
- ringPos = assert(Draw._toVector3(ringPos), "Bad ringPos")
881
- ringNorm = assert(Draw._toVector3(ringNorm), "Bad ringNorm")
912
+ function Draw.ring(position: Vector3Like, normal: Vector3Like, radius: number?, color: Color3Like, parent: Instance?)
913
+ local ringPosition = assert(Draw._toVector3(position), "Bad ringPos")
914
+ local ringNormal = assert(Draw._toVector3(normal), "Bad ringNorm")
915
+ local ringRadius = radius or 1
916
+ local ringColor = Draw._toColor3(color) or Draw._defaultColor
882
917
 
883
- local ringCFrame = CFrame.new(ringPos, ringPos + ringNorm)
918
+ local ringCFrame = CFrame.new(ringPosition, ringPosition + ringNormal)
884
919
 
885
920
  local points = {}
886
- for angle = 0, 2*math.pi, math.pi/8 do
887
- local x = math.cos(angle)*ringRadius
888
- local y = math.sin(angle)*ringRadius
921
+ for angle = 0, 2 * math.pi, math.pi / 8 do
922
+ local x = math.cos(angle) * ringRadius
923
+ local y = math.sin(angle) * ringRadius
889
924
  local vector = ringCFrame:pointToWorldSpace(Vector3.new(x, y, 0))
890
925
  table.insert(points, vector)
891
926
  end
@@ -893,11 +928,11 @@ function Draw.ring(ringPos, ringNorm, ringRadius, color, parent)
893
928
  local folder = Instance.new("Folder")
894
929
  folder.Name = "DebugRing"
895
930
 
896
- for i=1, #points do
931
+ for i = 1, #points do
897
932
  local pos = points[i]
898
- local nextPos = points[(i%#points)+1]
899
- local ray = Ray.new(pos, nextPos - pos)
900
- Draw.ray(ray, color, folder)
933
+ local nextPos = points[(i % #points) + 1]
934
+ local ray = Ray.new(pos, nextPos - pos)
935
+ Draw.ray(ray, ringColor, folder)
901
936
  end
902
937
 
903
938
  folder.Parent = parent or Draw.getDefaultParent()
@@ -905,7 +940,9 @@ function Draw.ring(ringPos, ringNorm, ringRadius, color, parent)
905
940
  return folder
906
941
  end
907
942
 
908
- function Draw._toVector3(position)
943
+ export type Vector3Like = Vector3 | CFrame | Attachment | BasePart | Model | RaycastResult | PathWaypoint
944
+
945
+ function Draw._toVector3(position: Vector3Like): Vector3?
909
946
  if typeof(position) == "Vector3" then
910
947
  return position
911
948
  elseif typeof(position) == "CFrame" then
@@ -916,7 +953,7 @@ function Draw._toVector3(position)
916
953
  elseif position:IsA("BasePart") then
917
954
  return position.Position
918
955
  elseif position:IsA("Model") then
919
- return position:GetBoundingBox().p
956
+ return position:GetBoundingBox().Position
920
957
  else
921
958
  return nil
922
959
  end
@@ -929,7 +966,9 @@ function Draw._toVector3(position)
929
966
  end
930
967
  end
931
968
 
932
- function Draw._toColor3(color)
969
+ export type Color3Like = Color3 | BrickColor | BasePart
970
+
971
+ function Draw._toColor3(color: Color3Like?): Color3?
933
972
  if typeof(color) == "Color3" then
934
973
  return color
935
974
  elseif typeof(color) == "BrickColor" then
@@ -945,7 +984,9 @@ function Draw._toColor3(color)
945
984
  end
946
985
  end
947
986
 
948
- function Draw._toCFrame(cframe)
987
+ export type CFrameLike = CFrame | Vector3 | Attachment | BasePart | Model | RaycastResult | PathWaypoint
988
+
989
+ function Draw._toCFrame(cframe: CFrameLike?): CFrame?
949
990
  if typeof(cframe) == "CFrame" then
950
991
  return cframe
951
992
  elseif typeof(cframe) == "Vector3" then
@@ -973,7 +1014,7 @@ end
973
1014
  Retrieves the default parent for the current execution context.
974
1015
  @return Instance
975
1016
  ]=]
976
- function Draw.getDefaultParent()
1017
+ function Draw.getDefaultParent(): Instance?
977
1018
  if not RunService:IsRunning() then
978
1019
  return Workspace.CurrentCamera
979
1020
  end
@@ -985,4 +1026,4 @@ function Draw.getDefaultParent()
985
1026
  end
986
1027
  end
987
1028
 
988
- return Draw
1029
+ return Draw