@quenty/draw 4.3.0 → 4.3.1-canary.436.cb76259.0
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 +11 -0
- package/package.json +6 -2
- package/src/Shared/Draw.lua +170 -52
- package/src/Shared/DrawBlockcast.story.lua +53 -0
- package/src/Shared/DrawRay.story.lua +65 -0
- package/src/Shared/DrawSpherecast.story.lua +65 -0
- package/src/node_modules.project.json +7 -0
- package/test/default.project.json +11 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
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
|
+
## [4.3.1-canary.436.cb76259.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/draw@4.3.0...@quenty/draw@4.3.1-canary.436.cb76259.0) (2024-01-08)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* Update draw package ([2b5aeab](https://github.com/Quenty/NevermoreEngine/commit/2b5aeab42ae8861aabacf2f796fba43d1e2e8717))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
# [4.3.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/draw@4.2.0...@quenty/draw@4.3.0) (2023-08-23)
|
|
7
18
|
|
|
8
19
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quenty/draw",
|
|
3
|
-
"version": "4.3.0",
|
|
3
|
+
"version": "4.3.1-canary.436.cb76259.0",
|
|
4
4
|
"description": "A utility library to debug things in 3D space for Roblox.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Roblox",
|
|
@@ -28,5 +28,9 @@
|
|
|
28
28
|
"publishConfig": {
|
|
29
29
|
"access": "public"
|
|
30
30
|
},
|
|
31
|
-
"
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@quenty/loader": "7.1.1-canary.436.cb76259.0",
|
|
33
|
+
"@quenty/maid": "2.6.0"
|
|
34
|
+
},
|
|
35
|
+
"gitHead": "cb7625914c075100546dbd26c7d04eda3c9bd3e4"
|
|
32
36
|
}
|
package/src/Shared/Draw.lua
CHANGED
|
@@ -62,16 +62,15 @@ end
|
|
|
62
62
|
@param finish Vector3
|
|
63
63
|
@param color Color3 -- Optional
|
|
64
64
|
@param parent Instance? -- Optional
|
|
65
|
-
@param meshDiameter number -- Optional
|
|
66
65
|
@param diameter number -- Optional
|
|
67
66
|
@return Instance
|
|
68
67
|
]=]
|
|
69
|
-
function Draw.line(start, finish, color, parent,
|
|
68
|
+
function Draw.line(start, finish, color, parent, diameter)
|
|
70
69
|
start = assert(Draw._toVector3(start), "Bad start")
|
|
71
70
|
finish = assert(Draw._toVector3(finish), "Bad finish")
|
|
72
71
|
color = Draw._toColor3(color)
|
|
73
72
|
|
|
74
|
-
return Draw.ray(Ray.new(start, finish - start), color, parent,
|
|
73
|
+
return Draw.ray(Ray.new(start, finish - start), color, parent, diameter)
|
|
75
74
|
end
|
|
76
75
|
|
|
77
76
|
--[=[
|
|
@@ -96,18 +95,38 @@ end
|
|
|
96
95
|
--[=[
|
|
97
96
|
Draws a spherecast
|
|
98
97
|
|
|
98
|
+
:::tip
|
|
99
|
+
Unlike WorldRoot:GetPartsInPart(), spherecast does not detect BaseParts
|
|
100
|
+
that initially intersect the shape. So this draw doesn't render that initial sphere.
|
|
101
|
+
:::
|
|
102
|
+
|
|
99
103
|
@param origin Vector3
|
|
100
104
|
@param radius number
|
|
101
105
|
@param direction Vector3
|
|
102
106
|
@param color Color3
|
|
103
107
|
@param parent Parent
|
|
104
108
|
]=]
|
|
105
|
-
function Draw.
|
|
106
|
-
|
|
109
|
+
function Draw.spherecast(origin, radius, direction, color, parent)
|
|
110
|
+
origin = assert(Draw._toVector3(origin), "Bad cframe")
|
|
111
|
+
assert(type(radius) == "number", "Bad radius")
|
|
112
|
+
direction = assert(Draw._toVector3(direction), "Bad direction")
|
|
113
|
+
color = Draw._toColor3(color)
|
|
114
|
+
parent = parent or Draw.getDefaultParent()
|
|
115
|
+
|
|
116
|
+
local folder = Instance.new("Folder")
|
|
117
|
+
folder.Name = "SphereCast"
|
|
118
|
+
folder.Archivable = false
|
|
119
|
+
|
|
120
|
+
Draw.ray(Ray.new(origin, direction), color, folder, 2*radius)
|
|
121
|
+
Draw.sphere(origin + direction, radius, color, folder)
|
|
122
|
+
|
|
123
|
+
folder.Parent = parent
|
|
124
|
+
|
|
125
|
+
return folder
|
|
107
126
|
end
|
|
108
127
|
|
|
109
128
|
--[=[
|
|
110
|
-
Draws a
|
|
129
|
+
Draws a block cast
|
|
111
130
|
|
|
112
131
|
@param cframe CFrame
|
|
113
132
|
@param size Vector3
|
|
@@ -118,6 +137,7 @@ end
|
|
|
118
137
|
function Draw.blockcast(cframe, size, direction, color, parent)
|
|
119
138
|
cframe = assert(Draw._toCFrame(cframe), "Bad cframe")
|
|
120
139
|
size = assert(Draw._toVector3(size), "Bad size")
|
|
140
|
+
direction = assert(Draw._toVector3(direction), "Bad direction")
|
|
121
141
|
color = Draw._toColor3(color)
|
|
122
142
|
parent = parent or Draw.getDefaultParent()
|
|
123
143
|
|
|
@@ -135,6 +155,99 @@ function Draw.blockcast(cframe, size, direction, color, parent)
|
|
|
135
155
|
return folder
|
|
136
156
|
end
|
|
137
157
|
|
|
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")
|
|
162
|
+
color = Draw._toColor3(color) or Draw._defaultColor
|
|
163
|
+
parent = parent or Draw.getDefaultParent()
|
|
164
|
+
|
|
165
|
+
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
|
+
};
|
|
170
|
+
|
|
171
|
+
local edge = edges[1]
|
|
172
|
+
for i = 2, #edges do
|
|
173
|
+
if edges[i].longest.magnitude > edge.longest.magnitude then
|
|
174
|
+
edge = edges[i]
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
local theta = math.acos(edge.longest.unit:Dot(edge.other.unit))
|
|
179
|
+
local w1 = math.cos(theta) * edge.other.magnitude
|
|
180
|
+
local w2 = edge.longest.magnitude - w1
|
|
181
|
+
local h = math.sin(theta) * edge.other.magnitude
|
|
182
|
+
|
|
183
|
+
local p1 = edge.origin + edge.other * 0.5;
|
|
184
|
+
local p2 = edge.origin + edge.longest + (edge.other - edge.longest) * 0.5
|
|
185
|
+
|
|
186
|
+
local right = edge.longest:Cross(edge.other).unit
|
|
187
|
+
local up = right:Cross(edge.longest).unit
|
|
188
|
+
local back = edge.longest.unit
|
|
189
|
+
|
|
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
|
+
);
|
|
196
|
+
|
|
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
|
+
);
|
|
203
|
+
|
|
204
|
+
-- put it all together by creating the wedges
|
|
205
|
+
local triangle = Instance.new("Folder")
|
|
206
|
+
triangle.Name = "Triangle"
|
|
207
|
+
triangle.Archivable = false
|
|
208
|
+
|
|
209
|
+
local wedge1 = Instance.new("WedgePart")
|
|
210
|
+
wedge1.Material = Enum.Material.SmoothPlastic
|
|
211
|
+
wedge1.Transparency = 0
|
|
212
|
+
wedge1.Anchored = true
|
|
213
|
+
wedge1.CanCollide = false
|
|
214
|
+
wedge1.CanQuery = false
|
|
215
|
+
wedge1.CanTouch = false
|
|
216
|
+
wedge1.Archivable = false
|
|
217
|
+
wedge1.CastShadow = false
|
|
218
|
+
wedge1.Size = Vector3.new(0.05, h, w1)
|
|
219
|
+
wedge1.CFrame = cf1
|
|
220
|
+
wedge1.Color = color
|
|
221
|
+
|
|
222
|
+
local mesh1 = Instance.new("SpecialMesh")
|
|
223
|
+
mesh1.MeshType = Enum.MeshType.Wedge
|
|
224
|
+
mesh1.Scale = Vector3.new(0, 1, 1)
|
|
225
|
+
mesh1.Parent = wedge1
|
|
226
|
+
|
|
227
|
+
local wedge2 = Instance.new("WedgePart")
|
|
228
|
+
wedge2.Material = Enum.Material.SmoothPlastic
|
|
229
|
+
wedge2.Transparency = 0
|
|
230
|
+
wedge2.Anchored = true
|
|
231
|
+
wedge2.CanCollide = false
|
|
232
|
+
wedge2.CanQuery = false
|
|
233
|
+
wedge2.CanTouch = false
|
|
234
|
+
wedge2.Archivable = false
|
|
235
|
+
wedge2.CastShadow = false
|
|
236
|
+
wedge2.Size = Vector3.new(0.05, h, w2)
|
|
237
|
+
wedge2.CFrame = cf2
|
|
238
|
+
wedge2.Color = color
|
|
239
|
+
|
|
240
|
+
local mesh2 = Instance.new("SpecialMesh")
|
|
241
|
+
mesh2.MeshType = Enum.MeshType.Wedge
|
|
242
|
+
mesh2.Scale = Vector3.new(0, 1, 1)
|
|
243
|
+
mesh2.Parent = wedge2
|
|
244
|
+
|
|
245
|
+
wedge1.Parent = triangle
|
|
246
|
+
wedge2.Parent = triangle
|
|
247
|
+
|
|
248
|
+
return triangle
|
|
249
|
+
end
|
|
250
|
+
|
|
138
251
|
--[=[
|
|
139
252
|
Draws a raycast for debugging
|
|
140
253
|
|
|
@@ -166,18 +279,17 @@ end
|
|
|
166
279
|
@param color Color3? -- Optional color to draw in
|
|
167
280
|
@param parent Instance? -- Optional parent
|
|
168
281
|
@param diameter number? -- Optional diameter
|
|
169
|
-
@param meshDiameter number? -- Optional mesh diameter
|
|
170
282
|
@return BasePart
|
|
171
283
|
]=]
|
|
172
|
-
function Draw.ray(ray, color, parent,
|
|
284
|
+
function Draw.ray(ray, color, parent, diameter)
|
|
173
285
|
assert(typeof(ray) == "Ray", "Bad typeof(ray) for Ray")
|
|
174
286
|
|
|
175
287
|
color = Draw._toColor3(color) or Draw._defaultColor
|
|
176
288
|
parent = parent or Draw.getDefaultParent()
|
|
177
|
-
meshDiameter = meshDiameter or 0.2
|
|
178
289
|
diameter = diameter or 0.2
|
|
179
290
|
|
|
180
291
|
local rayCenter = ray.Origin + ray.Direction/2
|
|
292
|
+
local distance = ray.Direction.Magnitude
|
|
181
293
|
|
|
182
294
|
local part = Instance.new("Part")
|
|
183
295
|
part.Material = Enum.Material.ForceField
|
|
@@ -187,41 +299,33 @@ function Draw.ray(ray, color, parent, meshDiameter, diameter)
|
|
|
187
299
|
part.CanQuery = false
|
|
188
300
|
part.CanTouch = false
|
|
189
301
|
part.CastShadow = false
|
|
190
|
-
part.CFrame = CFrame.new(rayCenter, ray.Origin + ray.Direction) * CFrame.Angles(math.pi/2, 0
|
|
302
|
+
part.CFrame = CFrame.new(rayCenter, ray.Origin + ray.Direction) * CFrame.Angles(0, math.pi/2, 0)
|
|
191
303
|
part.Color = color
|
|
192
304
|
part.Name = "DebugRay"
|
|
193
305
|
part.Shape = Enum.PartType.Cylinder
|
|
194
|
-
part.Size = Vector3.new(
|
|
306
|
+
part.Size = Vector3.new(distance, diameter, diameter)
|
|
195
307
|
part.TopSurface = Enum.SurfaceType.Smooth
|
|
196
308
|
part.Transparency = 0.5
|
|
197
309
|
|
|
198
|
-
local
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
local
|
|
212
|
-
lineHandleAdornment.Name = "DrawRayLineHandleAdornment"
|
|
213
|
-
lineHandleAdornment.Length = ray.Direction.Magnitude
|
|
214
|
-
lineHandleAdornment.Thickness = 5*diameter
|
|
215
|
-
lineHandleAdornment.ZIndex = 3
|
|
216
|
-
lineHandleAdornment.Color3 = color
|
|
217
|
-
lineHandleAdornment.AlwaysOnTop = true
|
|
218
|
-
lineHandleAdornment.Transparency = 0
|
|
219
|
-
lineHandleAdornment.Adornee = rotatedPart
|
|
220
|
-
lineHandleAdornment.Parent = rotatedPart
|
|
310
|
+
local cylinderHandleAdornment = Instance.new("CylinderHandleAdornment")
|
|
311
|
+
cylinderHandleAdornment.Name = "CylinderHandleAdornment"
|
|
312
|
+
cylinderHandleAdornment.Height = ray.Direction.Magnitude
|
|
313
|
+
cylinderHandleAdornment.InnerRadius = 0
|
|
314
|
+
cylinderHandleAdornment.Radius = diameter/4
|
|
315
|
+
cylinderHandleAdornment.ZIndex = 3
|
|
316
|
+
cylinderHandleAdornment.Color3 = color
|
|
317
|
+
cylinderHandleAdornment.AlwaysOnTop = true
|
|
318
|
+
cylinderHandleAdornment.Transparency = 0.25
|
|
319
|
+
cylinderHandleAdornment.CFrame = CFrame.Angles(0, math.pi/2, 0)
|
|
320
|
+
cylinderHandleAdornment.Adornee = part
|
|
321
|
+
cylinderHandleAdornment.Parent = part
|
|
322
|
+
|
|
323
|
+
local partSize = part.Size
|
|
221
324
|
|
|
222
325
|
local mesh = Instance.new("SpecialMesh")
|
|
326
|
+
mesh.MeshType = Enum.MeshType.Cylinder
|
|
223
327
|
mesh.Name = "DrawRayMesh"
|
|
224
|
-
mesh.Scale = Vector3.new(
|
|
328
|
+
mesh.Scale = Vector3.new(distance/partSize.x, diameter/partSize.y, diameter/partSize.z)
|
|
225
329
|
mesh.Parent = part
|
|
226
330
|
|
|
227
331
|
part.Parent = parent
|
|
@@ -244,31 +348,36 @@ end
|
|
|
244
348
|
end)
|
|
245
349
|
```
|
|
246
350
|
|
|
247
|
-
@param
|
|
248
|
-
@param ray Ray
|
|
249
|
-
@param color Color3
|
|
351
|
+
@param rayPart Instance -- Ray part
|
|
352
|
+
@param ray Ray -- New ray
|
|
353
|
+
@param color Color3 -- New color
|
|
354
|
+
@param diameter number -- Number
|
|
250
355
|
]=]
|
|
251
|
-
function Draw.updateRay(
|
|
252
|
-
|
|
356
|
+
function Draw.updateRay(rayPart, ray, color, diameter)
|
|
357
|
+
assert(typeof(rayPart) == "Instance", "Bad rayPart")
|
|
358
|
+
assert(typeof(ray) == "Ray", "Bad typeof(ray) for Ray")
|
|
359
|
+
color = Draw._toColor3(color) or rayPart.Color
|
|
360
|
+
diameter = diameter or rayPart.Size.x
|
|
253
361
|
|
|
254
|
-
local diameter = part.Size.x
|
|
255
362
|
local rayCenter = ray.Origin + ray.Direction/2
|
|
363
|
+
local distance = ray.Direction.Magnitude
|
|
256
364
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
local rotatedPart = part:FindFirstChild("RotatedPart")
|
|
262
|
-
if rotatedPart then
|
|
263
|
-
rotatedPart.CFrame = CFrame.new(ray.Origin, ray.Origin + ray.Direction)
|
|
264
|
-
end
|
|
365
|
+
rayPart.Color = color
|
|
366
|
+
rayPart.Size = Vector3.new(distance, diameter, diameter)
|
|
367
|
+
rayPart.CFrame = CFrame.new(rayCenter, ray.Origin + ray.Direction) * CFrame.Angles(0, math.pi/2, 0)
|
|
265
368
|
|
|
266
|
-
local lineHandleAdornment =
|
|
369
|
+
local lineHandleAdornment = rayPart:FindFirstChildWhichIsA("CylinderHandleAdornment")
|
|
267
370
|
if lineHandleAdornment then
|
|
268
|
-
lineHandleAdornment.
|
|
269
|
-
lineHandleAdornment.
|
|
371
|
+
lineHandleAdornment.Height = ray.Direction.Magnitude
|
|
372
|
+
lineHandleAdornment.Radius = 5*diameter
|
|
270
373
|
lineHandleAdornment.Color3 = color
|
|
271
374
|
end
|
|
375
|
+
|
|
376
|
+
local partSize = rayPart.Size
|
|
377
|
+
local mesh = rayPart:FindFirstChildWhichIsA("SpecialMesh")
|
|
378
|
+
if mesh then
|
|
379
|
+
mesh.Scale = Vector3.new(distance/partSize.x, diameter/partSize.y, diameter/partSize.z)
|
|
380
|
+
end
|
|
272
381
|
end
|
|
273
382
|
|
|
274
383
|
--[=[
|
|
@@ -435,6 +544,7 @@ function Draw.point(position, color, parent, diameter)
|
|
|
435
544
|
|
|
436
545
|
local sphereHandle = Instance.new("SphereHandleAdornment")
|
|
437
546
|
sphereHandle.Archivable = false
|
|
547
|
+
sphereHandle.Transparency = 0.25
|
|
438
548
|
sphereHandle.Radius = diameter/4
|
|
439
549
|
sphereHandle.Color3 = color
|
|
440
550
|
sphereHandle.AlwaysOnTop = true
|
|
@@ -810,6 +920,10 @@ function Draw._toVector3(position)
|
|
|
810
920
|
else
|
|
811
921
|
return nil
|
|
812
922
|
end
|
|
923
|
+
elseif typeof(position) == "RaycastResult" then
|
|
924
|
+
return position.Position
|
|
925
|
+
elseif typeof(position) == "PathWaypoint" then
|
|
926
|
+
return position.Position
|
|
813
927
|
else
|
|
814
928
|
return nil
|
|
815
929
|
end
|
|
@@ -846,6 +960,10 @@ function Draw._toCFrame(cframe)
|
|
|
846
960
|
else
|
|
847
961
|
return nil
|
|
848
962
|
end
|
|
963
|
+
elseif typeof(cframe) == "RaycastResult" then
|
|
964
|
+
return CFrame.new(cframe.Position, cframe.Normal)
|
|
965
|
+
elseif typeof(cframe) == "PathWaypoint" then
|
|
966
|
+
return CFrame.new(cframe.Position)
|
|
849
967
|
else
|
|
850
968
|
return nil
|
|
851
969
|
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
--[[
|
|
2
|
+
@class Draw.story
|
|
3
|
+
]]
|
|
4
|
+
|
|
5
|
+
local require = require(game:GetService("ServerScriptService"):FindFirstChild("LoaderUtils", true).Parent).load(script)
|
|
6
|
+
|
|
7
|
+
local UserInputService = game:GetService("UserInputService")
|
|
8
|
+
local Workspace = game:GetService("Workspace")
|
|
9
|
+
|
|
10
|
+
local Draw = require("Draw")
|
|
11
|
+
local Maid = require("Maid")
|
|
12
|
+
|
|
13
|
+
return function(_target)
|
|
14
|
+
local topMaid = Maid.new()
|
|
15
|
+
|
|
16
|
+
topMaid:GiveTask(UserInputService.InputBegan:Connect(function(inputObject, gameProcessed)
|
|
17
|
+
if gameProcessed then
|
|
18
|
+
return
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
if inputObject.UserInputType == Enum.UserInputType.MouseButton1 then
|
|
22
|
+
if topMaid._current then
|
|
23
|
+
if not UserInputService:IsKeyDown(Enum.KeyCode.LeftControl) then
|
|
24
|
+
return
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
local maid = Maid.new()
|
|
29
|
+
local camera = Workspace.CurrentCamera
|
|
30
|
+
local position = inputObject.Position
|
|
31
|
+
|
|
32
|
+
local baseRay = camera:ViewportPointToRay(position.x, position.y, 0)
|
|
33
|
+
local ray = Ray.new(baseRay.Origin, baseRay.Direction.unit * 50)
|
|
34
|
+
local cframe = CFrame.new(ray.Origin, ray.Origin + ray.Direction.unit)
|
|
35
|
+
* CFrame.Angles(0, math.pi/4, math.pi/4)
|
|
36
|
+
local size = Vector3.new(4, 4, 4)
|
|
37
|
+
local direction = ray.Direction
|
|
38
|
+
|
|
39
|
+
maid:Add(Draw.blockcast(cframe, size, direction))
|
|
40
|
+
|
|
41
|
+
local raycastResult = Workspace:Blockcast(cframe, size, direction)
|
|
42
|
+
if raycastResult then
|
|
43
|
+
maid:Add(Draw.point(raycastResult.Position, Color3.new(0.25, 1, 0.25), nil, 0.1))
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
topMaid._current = maid
|
|
47
|
+
end
|
|
48
|
+
end))
|
|
49
|
+
|
|
50
|
+
return function()
|
|
51
|
+
topMaid:DoCleaning()
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
--[[
|
|
2
|
+
@class Draw.story
|
|
3
|
+
]]
|
|
4
|
+
|
|
5
|
+
local require = require(game:GetService("ServerScriptService"):FindFirstChild("LoaderUtils", true).Parent).load(script)
|
|
6
|
+
|
|
7
|
+
local UserInputService = game:GetService("UserInputService")
|
|
8
|
+
local Workspace = game:GetService("Workspace")
|
|
9
|
+
|
|
10
|
+
local Draw = require("Draw")
|
|
11
|
+
local Maid = require("Maid")
|
|
12
|
+
|
|
13
|
+
return function(_target)
|
|
14
|
+
local topMaid = Maid.new()
|
|
15
|
+
|
|
16
|
+
local function render(baseRay)
|
|
17
|
+
local maid = Maid.new()
|
|
18
|
+
|
|
19
|
+
local ray = Ray.new(baseRay.Origin, baseRay.Direction.unit * 10000)
|
|
20
|
+
|
|
21
|
+
maid:Add(Draw.ray(ray))
|
|
22
|
+
|
|
23
|
+
local raycastResult = Workspace:Raycast(ray.Origin, ray.Direction)
|
|
24
|
+
if raycastResult then
|
|
25
|
+
maid:Add(Draw.point(raycastResult.Position, Color3.new(0.25, 1, 0.25), nil, 0.1))
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
topMaid._current = maid
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
topMaid:GiveTask(UserInputService.InputBegan:Connect(function(inputObject, gameProcessed)
|
|
32
|
+
if gameProcessed then
|
|
33
|
+
return
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
if inputObject.UserInputType == Enum.UserInputType.MouseButton1 then
|
|
37
|
+
if topMaid._current then
|
|
38
|
+
if not UserInputService:IsKeyDown(Enum.KeyCode.LeftControl) then
|
|
39
|
+
return
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
local camera = Workspace.CurrentCamera
|
|
45
|
+
local position = inputObject.Position
|
|
46
|
+
local baseRay = camera:ViewportPointToRay(position.x, position.y, 0)
|
|
47
|
+
|
|
48
|
+
-- selene: allow(global_usage)
|
|
49
|
+
shared._lastDrawRayInput = baseRay
|
|
50
|
+
|
|
51
|
+
render(baseRay)
|
|
52
|
+
end
|
|
53
|
+
end))
|
|
54
|
+
|
|
55
|
+
task.spawn(function()
|
|
56
|
+
-- selene: allow(global_usage)
|
|
57
|
+
if shared._lastDrawRayInput then
|
|
58
|
+
render(shared._lastDrawRayInput)
|
|
59
|
+
end
|
|
60
|
+
end)
|
|
61
|
+
|
|
62
|
+
return function()
|
|
63
|
+
topMaid:DoCleaning()
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
--[[
|
|
2
|
+
@class Draw.story
|
|
3
|
+
]]
|
|
4
|
+
|
|
5
|
+
local require = require(game:GetService("ServerScriptService"):FindFirstChild("LoaderUtils", true).Parent).load(script)
|
|
6
|
+
|
|
7
|
+
local UserInputService = game:GetService("UserInputService")
|
|
8
|
+
local Workspace = game:GetService("Workspace")
|
|
9
|
+
|
|
10
|
+
local Draw = require("Draw")
|
|
11
|
+
local Maid = require("Maid")
|
|
12
|
+
|
|
13
|
+
return function(_target)
|
|
14
|
+
local topMaid = Maid.new()
|
|
15
|
+
|
|
16
|
+
local function render(baseRay)
|
|
17
|
+
local maid = Maid.new()
|
|
18
|
+
|
|
19
|
+
local ray = Ray.new(baseRay.Origin, baseRay.Direction.unit * 250)
|
|
20
|
+
|
|
21
|
+
maid:Add(Draw.spherecast(ray.Origin, 5, ray.Direction))
|
|
22
|
+
|
|
23
|
+
local raycastResult = Workspace:Raycast(ray.Origin, ray.Direction)
|
|
24
|
+
if raycastResult then
|
|
25
|
+
maid:Add(Draw.point(raycastResult.Position, Color3.new(0.25, 1, 0.25), nil, 0.1))
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
topMaid._current = maid
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
topMaid:GiveTask(UserInputService.InputBegan:Connect(function(inputObject, gameProcessed)
|
|
32
|
+
if gameProcessed then
|
|
33
|
+
return
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
if inputObject.UserInputType == Enum.UserInputType.MouseButton1 then
|
|
37
|
+
if topMaid._current then
|
|
38
|
+
if not UserInputService:IsKeyDown(Enum.KeyCode.LeftControl) then
|
|
39
|
+
return
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
local camera = Workspace.CurrentCamera
|
|
45
|
+
local position = inputObject.Position
|
|
46
|
+
local baseRay = camera:ViewportPointToRay(position.x, position.y, 0)
|
|
47
|
+
|
|
48
|
+
-- selene: allow(global_usage)
|
|
49
|
+
shared._lastDrawRayInput = baseRay
|
|
50
|
+
|
|
51
|
+
render(baseRay)
|
|
52
|
+
end
|
|
53
|
+
end))
|
|
54
|
+
|
|
55
|
+
task.spawn(function()
|
|
56
|
+
-- selene: allow(global_usage)
|
|
57
|
+
if shared._lastDrawRayInput then
|
|
58
|
+
render(shared._lastDrawRayInput)
|
|
59
|
+
end
|
|
60
|
+
end)
|
|
61
|
+
|
|
62
|
+
return function()
|
|
63
|
+
topMaid:DoCleaning()
|
|
64
|
+
end
|
|
65
|
+
end
|