@quenty/particleengine 13.18.0 → 13.18.1-canary.545.2374fb2.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
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
|
+
## [13.18.1-canary.545.2374fb2.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/particleengine@13.18.0...@quenty/particleengine@13.18.1-canary.545.2374fb2.0) (2025-04-05)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* Add types to packages ([2374fb2](https://github.com/Quenty/NevermoreEngine/commit/2374fb2b043cfbe0e9b507b3316eec46a4e353a0))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
# [13.18.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/particleengine@13.17.2...@quenty/particleengine@13.18.0) (2025-04-02)
|
|
7
18
|
|
|
8
19
|
**Note:** Version bump only for package @quenty/particleengine
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quenty/particleengine",
|
|
3
|
-
"version": "13.18.0",
|
|
3
|
+
"version": "13.18.1-canary.545.2374fb2.0",
|
|
4
4
|
"description": "Adds GUI based particle engine to Roblox",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Roblox",
|
|
@@ -26,12 +26,12 @@
|
|
|
26
26
|
"AxisAngles"
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@quenty/loader": "
|
|
30
|
-
"@quenty/remoting": "
|
|
31
|
-
"@quenty/table": "
|
|
29
|
+
"@quenty/loader": "10.8.1-canary.545.2374fb2.0",
|
|
30
|
+
"@quenty/remoting": "12.18.1-canary.545.2374fb2.0",
|
|
31
|
+
"@quenty/table": "3.7.2-canary.545.2374fb2.0"
|
|
32
32
|
},
|
|
33
33
|
"publishConfig": {
|
|
34
34
|
"access": "public"
|
|
35
35
|
},
|
|
36
|
-
"gitHead": "
|
|
36
|
+
"gitHead": "2374fb2b043cfbe0e9b507b3316eec46a4e353a0"
|
|
37
37
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!nocheck
|
|
1
2
|
--[=[
|
|
2
3
|
Legacy code written by AxisAngles to simulate particles with Guis
|
|
3
4
|
|
|
@@ -13,6 +14,7 @@ local RunService = game:GetService("RunService")
|
|
|
13
14
|
|
|
14
15
|
local PromiseGetRemoteEvent = require("PromiseGetRemoteEvent")
|
|
15
16
|
local ParticleEngineConstants = require("ParticleEngineConstants")
|
|
17
|
+
local _ServiceBag = require("ServiceBag")
|
|
16
18
|
|
|
17
19
|
local ParticleEngineClient = {}
|
|
18
20
|
ParticleEngineClient.ServiceName = "ParticleEngineClient"
|
|
@@ -23,7 +25,7 @@ ParticleEngineClient._maxParticles = 400
|
|
|
23
25
|
-- Speed of wind to simulate
|
|
24
26
|
ParticleEngineClient._windSpeed = 10
|
|
25
27
|
|
|
26
|
-
local function newFrame(name)
|
|
28
|
+
local function newFrame(name: string): Frame
|
|
27
29
|
local frame = Instance.new("Frame")
|
|
28
30
|
frame.BorderSizePixel = 0
|
|
29
31
|
frame.Name = name
|
|
@@ -31,10 +33,11 @@ local function newFrame(name)
|
|
|
31
33
|
return frame
|
|
32
34
|
end
|
|
33
35
|
|
|
34
|
-
function ParticleEngineClient:Init(serviceBag)
|
|
36
|
+
function ParticleEngineClient:Init(serviceBag: _ServiceBag.ServiceBag)
|
|
35
37
|
self._serviceBag = assert(serviceBag, "No serviceBag")
|
|
38
|
+
self._screen = nil :: ScreenGui?
|
|
36
39
|
|
|
37
|
-
PromiseGetRemoteEvent(ParticleEngineConstants.REMOTE_EVENT_NAME):Then(function(remoteEvent)
|
|
40
|
+
PromiseGetRemoteEvent(ParticleEngineConstants.REMOTE_EVENT_NAME):Then(function(remoteEvent: RemoteEvent)
|
|
38
41
|
self._remoteEvent = remoteEvent
|
|
39
42
|
|
|
40
43
|
self._remoteEvent.OnClientEvent:Connect(function(...)
|
|
@@ -46,10 +49,10 @@ function ParticleEngineClient:Init(serviceBag)
|
|
|
46
49
|
|
|
47
50
|
self._lastUpdateTime = tick()
|
|
48
51
|
self._particleCount = 0
|
|
49
|
-
self._particles = {}
|
|
50
|
-
self._particleFrames = {}
|
|
52
|
+
self._particles = {} :: { Particle }
|
|
53
|
+
self._particleFrames = {} :: { Frame }
|
|
51
54
|
|
|
52
|
-
for i=1, self._maxParticles do
|
|
55
|
+
for i = 1, self._maxParticles do
|
|
53
56
|
self._particleFrames[i] = newFrame("_particle")
|
|
54
57
|
end
|
|
55
58
|
|
|
@@ -60,15 +63,15 @@ function ParticleEngineClient:Init(serviceBag)
|
|
|
60
63
|
end)
|
|
61
64
|
end
|
|
62
65
|
|
|
63
|
-
function ParticleEngineClient:SetScreenGui(screenGui)
|
|
66
|
+
function ParticleEngineClient:SetScreenGui(screenGui: ScreenGui)
|
|
64
67
|
self._screen = screenGui
|
|
65
68
|
end
|
|
66
69
|
|
|
67
70
|
-- Removes a particle
|
|
68
|
-
function ParticleEngineClient:Remove(p)
|
|
71
|
+
function ParticleEngineClient:Remove(p: Particle)
|
|
69
72
|
if self._particles[p] then
|
|
70
73
|
self._particles[p] = nil
|
|
71
|
-
self._particleCount
|
|
74
|
+
self._particleCount -= 1
|
|
72
75
|
end
|
|
73
76
|
end
|
|
74
77
|
|
|
@@ -93,17 +96,34 @@ end
|
|
|
93
96
|
Function = function(Table ParticleProperties, Number dt, Number t)
|
|
94
97
|
}
|
|
95
98
|
--]]
|
|
96
|
-
|
|
99
|
+
export type Particle = {
|
|
100
|
+
Position: Vector3,
|
|
101
|
+
Global: boolean,
|
|
102
|
+
Velocity: Vector3,
|
|
103
|
+
Gravity: Vector3,
|
|
104
|
+
WindResistance: number,
|
|
105
|
+
LifeTime: number,
|
|
106
|
+
Size: Vector2,
|
|
107
|
+
Bloom: Vector2,
|
|
108
|
+
Transparency: number,
|
|
109
|
+
Color: Color3,
|
|
110
|
+
Occlusion: boolean?,
|
|
111
|
+
RemoveOnCollision: ((BasePart, Vector3) -> boolean)?,
|
|
112
|
+
Function: ((Particle, number, number) -> ())?,
|
|
113
|
+
_lastScreenPosition: Vector2?,
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function ParticleEngineClient:Add(p: Particle)
|
|
97
117
|
if self._particles[p] then
|
|
98
118
|
return
|
|
99
119
|
end
|
|
100
120
|
|
|
101
121
|
p.Position = p.Position or Vector3.zero
|
|
102
122
|
p.Velocity = p.Velocity or Vector3.zero
|
|
103
|
-
p.Size = p.Size or Vector2.new(0.2,0.2)
|
|
123
|
+
p.Size = p.Size or Vector2.new(0.2, 0.2)
|
|
104
124
|
p.Bloom = p.Bloom or Vector2.zero
|
|
105
125
|
p.Gravity = p.Gravity or Vector3.zero
|
|
106
|
-
p.Color = p.Color or Color3.new(1,1,1)
|
|
126
|
+
p.Color = p.Color or Color3.new(1, 1, 1)
|
|
107
127
|
p.Transparency = p.Transparency or 0.5
|
|
108
128
|
|
|
109
129
|
if p.Global then
|
|
@@ -123,7 +143,7 @@ function ParticleEngineClient:Add(p)
|
|
|
123
143
|
p.RemoveOnCollision = removeOnCollision
|
|
124
144
|
end
|
|
125
145
|
|
|
126
|
-
p.LifeTime = p.LifeTime and p.LifeTime+tick()
|
|
146
|
+
p.LifeTime = p.LifeTime and p.LifeTime + tick()
|
|
127
147
|
|
|
128
148
|
if self._particleCount > self._maxParticles then
|
|
129
149
|
self._particles[next(self._particles)] = nil
|
|
@@ -135,33 +155,33 @@ function ParticleEngineClient:Add(p)
|
|
|
135
155
|
end
|
|
136
156
|
|
|
137
157
|
-- @param p Position
|
|
138
|
-
local function particleWind(t, p)
|
|
139
|
-
local xy,yz,zx=p.
|
|
158
|
+
local function particleWind(t: number, p: Vector3): Vector3
|
|
159
|
+
local xy: number, yz: number, zx: number = p.X + p.Y, p.Y + p.Z, p.Z + p.X
|
|
140
160
|
return Vector3.new(
|
|
141
|
-
(math.sin(yz+t*2)+math.sin(yz+t))/2+math.sin((yz+t)/10)/2,
|
|
142
|
-
(math.sin(zx+t*2)+math.sin(zx+t))/2+math.sin((zx+t)/10)/2,
|
|
143
|
-
(math.sin(xy+t*2)+math.sin(xy+t))/2+math.sin((xy+t)/10)/2
|
|
161
|
+
(math.sin(yz + t * 2) + math.sin(yz + t)) / 2 + math.sin((yz + t) / 10) / 2,
|
|
162
|
+
(math.sin(zx + t * 2) + math.sin(zx + t)) / 2 + math.sin((zx + t) / 10) / 2,
|
|
163
|
+
(math.sin(xy + t * 2) + math.sin(xy + t)) / 2 + math.sin((xy + t) / 10) / 2
|
|
144
164
|
)
|
|
145
165
|
end
|
|
146
166
|
|
|
147
167
|
-- @param p ParticleProperties
|
|
148
168
|
-- @param dt ChangeInTime
|
|
149
|
-
function ParticleEngineClient:_updatePosVel(p, dt, t)
|
|
150
|
-
p.Position = p.Position + p.Velocity*dt
|
|
169
|
+
function ParticleEngineClient:_updatePosVel(p: Particle, dt: number, t: number)
|
|
170
|
+
p.Position = p.Position + p.Velocity * dt
|
|
151
171
|
|
|
152
172
|
local wind
|
|
153
173
|
if p.WindResistance then
|
|
154
|
-
wind = (particleWind(t, p.Position)*self._windSpeed - p.Velocity)*p.WindResistance
|
|
174
|
+
wind = (particleWind(t, p.Position) * self._windSpeed - p.Velocity) * p.WindResistance
|
|
155
175
|
else
|
|
156
176
|
wind = Vector3.zero
|
|
157
177
|
end
|
|
158
178
|
|
|
159
|
-
p.Velocity = p.Velocity + (p.Gravity + wind)*dt
|
|
179
|
+
p.Velocity = p.Velocity + (p.Gravity + wind) * dt
|
|
160
180
|
end
|
|
161
181
|
|
|
162
182
|
-- Handles both priority and regular particles
|
|
163
183
|
-- @return boolean alive, true if still fine
|
|
164
|
-
function ParticleEngineClient:_updateParticle(particle, t, dt)
|
|
184
|
+
function ParticleEngineClient:_updateParticle(particle: Particle, t: number, dt: number)
|
|
165
185
|
if particle.LifeTime - t <= 0 then
|
|
166
186
|
return false
|
|
167
187
|
end
|
|
@@ -181,7 +201,7 @@ function ParticleEngineClient:_updateParticle(particle, t, dt)
|
|
|
181
201
|
local displacement = particle.Position - lastPos
|
|
182
202
|
local distance = displacement.Magnitude
|
|
183
203
|
if distance > 999 then
|
|
184
|
-
displacement = displacement * (999/distance)
|
|
204
|
+
displacement = displacement * (999 / distance)
|
|
185
205
|
end
|
|
186
206
|
|
|
187
207
|
local ray = Ray.new(lastPos, displacement)
|
|
@@ -225,10 +245,10 @@ function ParticleEngineClient:_update()
|
|
|
225
245
|
end
|
|
226
246
|
|
|
227
247
|
function ParticleEngineClient:_updateRender()
|
|
228
|
-
local camera = Workspace.CurrentCamera
|
|
248
|
+
local camera: Camera = Workspace.CurrentCamera
|
|
229
249
|
self:_updateScreenInfo(camera)
|
|
230
250
|
|
|
231
|
-
local cameraInverse = camera.CFrame:
|
|
251
|
+
local cameraInverse = camera.CFrame:Inverse()
|
|
232
252
|
local cameraPosition = camera.CFrame.Position
|
|
233
253
|
|
|
234
254
|
local frameIndex, frame = next(self._particleFrames)
|
|
@@ -248,39 +268,40 @@ end
|
|
|
248
268
|
|
|
249
269
|
-- @param f frame
|
|
250
270
|
-- @param cameraInverse The inverse camera cframe
|
|
251
|
-
function ParticleEngineClient:_particleRender(cameraPosition, cameraInverse, frame, particle)
|
|
252
|
-
local rp = cameraInverse*particle.Position
|
|
253
|
-
local lsp = particle._lastScreenPosition
|
|
271
|
+
function ParticleEngineClient:_particleRender(cameraPosition: Vector3, cameraInverse: CFrame, frame: Frame, particle: Particle)
|
|
272
|
+
local rp: Vector3 = cameraInverse * particle.Position
|
|
273
|
+
local lsp: Vector2? = particle._lastScreenPosition
|
|
254
274
|
|
|
255
|
-
if not (rp.
|
|
256
|
-
if rp.
|
|
275
|
+
if not (rp.Z < -1 and lsp) then
|
|
276
|
+
if rp.Z > 0 then
|
|
257
277
|
particle._lastScreenPosition = nil
|
|
258
278
|
else
|
|
259
|
-
local sp = rp/rp.
|
|
279
|
+
local sp = rp / rp.Z
|
|
260
280
|
particle._lastScreenPosition = Vector2.new(
|
|
261
|
-
(0.5-sp.
|
|
262
|
-
(0.5+sp.
|
|
281
|
+
(0.5 - sp.X / self._planeSizeX) * self._screenSizeX,
|
|
282
|
+
(0.5 + sp.Y / self._planeSizeY) * self._screenSizeY
|
|
283
|
+
)
|
|
263
284
|
end
|
|
264
285
|
|
|
265
286
|
return false
|
|
266
287
|
end
|
|
267
288
|
|
|
268
|
-
local sp = rp/rp.
|
|
269
|
-
local b = particle.Bloom
|
|
270
|
-
local bgt = particle.Transparency
|
|
271
|
-
local px = (0.5-sp.
|
|
272
|
-
local py = (0.5+sp.
|
|
273
|
-
local preSizeY = -particle.Size.
|
|
274
|
-
local sx = -particle.Size.
|
|
275
|
-
local rppx,rppy = px-lsp.x,py-lsp.y
|
|
276
|
-
local sy = preSizeY+math.sqrt(rppx*rppx+rppy*rppy) + b.y
|
|
289
|
+
local sp = rp / rp.Z
|
|
290
|
+
local b: Vector2 = particle.Bloom
|
|
291
|
+
local bgt: number = particle.Transparency
|
|
292
|
+
local px: number = (0.5 - sp.X / self._planeSizeX) * self._screenSizeX
|
|
293
|
+
local py: number = (0.5 + sp.Y / self._planeSizeY) * self._screenSizeY
|
|
294
|
+
local preSizeY = -particle.Size.Y / rp.z * self._screenSizeY / self._planeSizeY
|
|
295
|
+
local sx: number = -particle.Size.X / rp.z * self._screenSizeY / self._planeSizeY + b.X
|
|
296
|
+
local rppx, rppy = px - lsp.x, py - lsp.y
|
|
297
|
+
local sy = preSizeY + math.sqrt(rppx * rppx + rppy * rppy) + b.y
|
|
277
298
|
particle._lastScreenPosition = Vector2.new(px, py)
|
|
278
299
|
|
|
279
300
|
if particle.Occlusion then
|
|
280
|
-
local vec = particle.Position-cameraPosition
|
|
301
|
+
local vec = particle.Position - cameraPosition
|
|
281
302
|
local mag = vec.Magnitude
|
|
282
303
|
if mag > 999 then
|
|
283
|
-
vec = vec * (999/mag)
|
|
304
|
+
vec = vec * (999 / mag)
|
|
284
305
|
end
|
|
285
306
|
|
|
286
307
|
if Workspace:FindPartOnRay(Ray.new(cameraPosition, vec), self._player.Character, true) then
|
|
@@ -288,7 +309,7 @@ function ParticleEngineClient:_particleRender(cameraPosition, cameraInverse, fra
|
|
|
288
309
|
end
|
|
289
310
|
end
|
|
290
311
|
|
|
291
|
-
frame.Position = UDim2.new(0, (px+lsp.
|
|
312
|
+
frame.Position = UDim2.new(0, (px + lsp.X - sx) / 2, 0, (py + lsp.Y - sy) / 2)
|
|
292
313
|
frame.Size = UDim2.new(0, sx, 0,sy)
|
|
293
314
|
frame.Rotation = 90+math.atan2(rppy,rppx)*57.295779513082
|
|
294
315
|
frame.BackgroundColor3 = particle.Color
|
|
@@ -297,7 +318,7 @@ function ParticleEngineClient:_particleRender(cameraPosition, cameraInverse, fra
|
|
|
297
318
|
return true
|
|
298
319
|
end
|
|
299
320
|
|
|
300
|
-
function ParticleEngineClient:_updateScreenInfo(camera)
|
|
321
|
+
function ParticleEngineClient:_updateScreenInfo(camera: Camera)
|
|
301
322
|
self._screenSizeX = self._screen.AbsoluteSize.x
|
|
302
323
|
self._screenSizeY = self._screen.AbsoluteSize.y
|
|
303
324
|
self._planeSizeY = 2*math.tan(camera.FieldOfView*0.0087266462599716)
|
|
@@ -28,7 +28,7 @@ end
|
|
|
28
28
|
function ParticleEngineServer:_replicate(player, particle)
|
|
29
29
|
particle.Global = nil
|
|
30
30
|
|
|
31
|
-
for _, otherPlayer in
|
|
31
|
+
for _, otherPlayer in Players:GetPlayers() do
|
|
32
32
|
if otherPlayer ~= player then
|
|
33
33
|
self._remoteEvent:FireClient(otherPlayer, particle)
|
|
34
34
|
end
|
|
@@ -44,7 +44,7 @@ function ParticleEngineServer:ParticleNew(p)
|
|
|
44
44
|
p.Size = p.Size or Vector2.new(0.2,0.2)
|
|
45
45
|
p.Bloom = p.Bloom or Vector2.new(0,0)
|
|
46
46
|
p.Gravity = p.Gravity or Vector3.zero
|
|
47
|
-
p.LifeTime = p.LifeTime
|
|
47
|
+
p.LifeTime = p.LifeTime
|
|
48
48
|
p.Color = p.Color or Color3.new(1,1,1)
|
|
49
49
|
p.Transparency = p.Transparency or 0.5
|
|
50
50
|
|