@rbxts/sound-manager 2.0.1 → 2.1.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/README.md CHANGED
@@ -25,5 +25,43 @@ Sounds.preloadAll();
25
25
  Sounds.play("SCP096");
26
26
  ```
27
27
 
28
+ ## Roadmap
29
+
30
+ ### Core API
31
+ - [x] load
32
+ - [x] play
33
+ - [x] stop / stopAll
34
+ - [x] preload / preloadAll
35
+ - [x] fadeIn / fadeOut
36
+ - [x] reset / resetAll
37
+ - [x] setTimePosition
38
+ - [x] setVolume / setGlobalVolume
39
+ - [x] onEnd
40
+ - [x] isPlaying
41
+
42
+ ### Development Utilities
43
+ - [ ] Total Sound Count function
44
+ - [ ] Currently Playing Sounds function
45
+ - [ ] Sound Instance Getter function
46
+ - [ ] Sound Properties Getter function
47
+
48
+ ### Category API
49
+ - [x] playCategory
50
+ - [x] stopCategory / stopAllCategories
51
+ - [x] setCategoryVolume / setGlobalCategoryVolume
52
+ - [x] fadeInCategory / fadeOutCategory
53
+ - [x] preloadCategory / preloadAllCategories
54
+ - [x] isCategoryPlaying
55
+ - [x] onCategoryEnd
56
+ - [x] resetCategory / resetAllCategories
57
+ - [x] playSoundFromCategory
58
+
59
+ ### Features
60
+ - [x] Sound Autocompletion
61
+ - [ ] Sound Categories
62
+ - [ ] Sound Creation functions
63
+ - [ ] Sound Priority
64
+
65
+
28
66
  For more Details:
29
67
  https://dev-lukas0.github.io/Sound-Manager-Docs/
@@ -6,4 +6,17 @@ import { CategoryOptions } from "./options";
6
6
  export declare function createSoundCategoryRegistry<T extends Record<string, CategoryOptions>>(definitions: T): {
7
7
  loadCategory: (name: keyof T) => void;
8
8
  playCategory: <C extends keyof T>(name: C) => void;
9
+ stopCategory: <C extends keyof T>(name: C) => void;
10
+ stopAllCategories: () => void;
11
+ setCategoryVolume: <C extends keyof T>(category: C, volume: number) => void;
12
+ setGlobalCategoryVolume: (volume: number) => void;
13
+ isCategoryPlaying: <C extends keyof T>(category: C) => boolean;
14
+ playSoundFromCategory: <C extends keyof T, S extends keyof T[C]["sounds"]>(category: C, sound: S) => void;
15
+ resetCategory: <C extends keyof T>(category: C) => void;
16
+ resetAllCategories: <C extends keyof T>(category: C) => void;
17
+ preloadAllCategories: () => void;
18
+ preloadCategory: <C extends keyof T>(category: C) => void;
19
+ fadeInCategory: <C extends keyof T>(category: C, duration: number, volume: number) => void;
20
+ fadeOutCategory: <C extends keyof T>(category: C, duration: number, targetVolume?: number) => void;
21
+ onCategoryEnd: <C extends keyof T>(category: C, callback: () => void) => void;
9
22
  };
@@ -79,9 +79,392 @@ local function createSoundCategoryRegistry(definitions)
79
79
  end
80
80
  end
81
81
  end
82
+ --[[
83
+ *
84
+ * Stop every Sound from a Sound Category
85
+ * @param name Sound Category
86
+
87
+ ]]
88
+ local function stopCategory(name)
89
+ local config = definitions[name]
90
+ local ReplicatedStorage = game:GetService("ReplicatedStorage")
91
+ local soundsFolder = ReplicatedStorage:FindFirstChild("Sounds")
92
+ if not soundsFolder then
93
+ return nil
94
+ end
95
+ local categoryFolder = soundsFolder:FindFirstChild(config.category)
96
+ if not categoryFolder then
97
+ return nil
98
+ end
99
+ for sound in pairs(config.sounds) do
100
+ local _sound = categoryFolder:FindFirstChild(sound)
101
+ if not _sound then
102
+ continue
103
+ end
104
+ local _result = _sound
105
+ if _result ~= nil then
106
+ _result = _result:IsA("Sound")
107
+ end
108
+ if _result then
109
+ _sound:Stop()
110
+ end
111
+ end
112
+ end
113
+ --[[
114
+ *
115
+ * Stops every Sound from every Sound Category
116
+
117
+ ]]
118
+ local function stopAllCategories()
119
+ local ReplicatedStorage = game:GetService("ReplicatedStorage")
120
+ local soundsFolder = ReplicatedStorage:FindFirstChild("Sounds")
121
+ if not soundsFolder then
122
+ return nil
123
+ end
124
+ for _, category in soundsFolder:GetChildren() do
125
+ if not category:IsA("Folder") then
126
+ continue
127
+ end
128
+ for _1, sound in category:GetChildren() do
129
+ if not sound:IsA("Sound") then
130
+ continue
131
+ end
132
+ sound:Stop()
133
+ end
134
+ end
135
+ end
136
+ --[[
137
+ *
138
+ * Set the Volume of a Sound Category
139
+ * @param category Sound Category
140
+ * @param volume Volume
141
+
142
+ ]]
143
+ local function setCategoryVolume(category, volume)
144
+ local config = definitions[category]
145
+ local ReplicatedStorage = game:GetService("ReplicatedStorage")
146
+ local soundsFolder = ReplicatedStorage:FindFirstChild("Sounds")
147
+ if not soundsFolder then
148
+ return nil
149
+ end
150
+ local categoryFolder = soundsFolder:FindFirstChild(config.category)
151
+ if not categoryFolder then
152
+ return nil
153
+ end
154
+ for _, sound in categoryFolder:GetChildren() do
155
+ if not sound:IsA("Sound") then
156
+ continue
157
+ end
158
+ sound.Volume = volume
159
+ end
160
+ end
161
+ --[[
162
+ *
163
+ * Set the Global Volume of every Sound Category
164
+ * @param volume Volume
165
+
166
+ ]]
167
+ local function setGlobalCategoryVolume(volume)
168
+ local ReplicatedStorage = game:GetService("ReplicatedStorage")
169
+ local soundsFolder = ReplicatedStorage:FindFirstChild("Sounds")
170
+ if not soundsFolder then
171
+ return nil
172
+ end
173
+ for _, category in soundsFolder:GetChildren() do
174
+ if not category:IsA("Folder") then
175
+ continue
176
+ end
177
+ for _1, sound in category:GetChildren() do
178
+ if not sound:IsA("Sound") then
179
+ continue
180
+ end
181
+ sound.Volume = volume
182
+ end
183
+ end
184
+ end
185
+ --[[
186
+ *
187
+ * Whether a Category is playing or not
188
+ * @param category Sound Category
189
+ * @returns Whether a Category is playing or not
190
+
191
+ ]]
192
+ local function isCategoryPlaying(category)
193
+ local config = definitions[category]
194
+ local ReplicatedStorage = game:GetService("ReplicatedStorage")
195
+ local soundsFolder = ReplicatedStorage:FindFirstChild("Sounds")
196
+ if not soundsFolder then
197
+ return false
198
+ end
199
+ local categoryFolder = soundsFolder:FindFirstChild(config.category)
200
+ if not categoryFolder then
201
+ return false
202
+ end
203
+ local _exp = categoryFolder:GetChildren()
204
+ -- ▼ ReadonlyArray.filter ▼
205
+ local _newValue = {}
206
+ local _callback = function(sound)
207
+ return sound:IsA("Sound")
208
+ end
209
+ local _length = 0
210
+ for _k, _v in _exp do
211
+ if _callback(_v, _k - 1, _exp) == true then
212
+ _length += 1
213
+ _newValue[_length] = _v
214
+ end
215
+ end
216
+ -- ▲ ReadonlyArray.filter ▲
217
+ local sounds = _newValue
218
+ if #sounds == 0 then
219
+ return false
220
+ end
221
+ for _, sound in sounds do
222
+ if not sound.IsPlaying then
223
+ return false
224
+ end
225
+ end
226
+ return true
227
+ end
228
+ --[[
229
+ *
230
+ * Play a Sound from a Category
231
+ * @param category Sound Category
232
+ * @param sound Sound Instance
233
+
234
+ ]]
235
+ local function playSoundFromCategory(category, sound)
236
+ loadCategory(category)
237
+ local config = definitions[category]
238
+ local ReplicatedStorage = game:GetService("ReplicatedStorage")
239
+ local soundsFolder = ReplicatedStorage:FindFirstChild("Sounds")
240
+ if not soundsFolder then
241
+ return nil
242
+ end
243
+ local categoryFolder = soundsFolder:FindFirstChild(config.category)
244
+ if not categoryFolder then
245
+ return nil
246
+ end
247
+ local soundInstance = categoryFolder:FindFirstChild(sound)
248
+ local _result = soundInstance
249
+ if _result ~= nil then
250
+ _result = _result:IsA("Sound")
251
+ end
252
+ if _result then
253
+ soundInstance:Play()
254
+ end
255
+ end
256
+ --[[
257
+ *
258
+ * Reset a Sound Category Timeposition to 0
259
+ * @param category Sound Category
260
+
261
+ ]]
262
+ local function resetCategory(category)
263
+ local config = definitions[category]
264
+ local ReplicatedStorage = game:GetService("ReplicatedStorage")
265
+ local soundsFolder = ReplicatedStorage:FindFirstChild("Sounds")
266
+ if not soundsFolder then
267
+ return nil
268
+ end
269
+ local categoryFolder = soundsFolder:FindFirstChild(config.category)
270
+ if not categoryFolder then
271
+ return nil
272
+ end
273
+ for _, sound in categoryFolder:GetChildren() do
274
+ if not sound:IsA("Sound") then
275
+ continue
276
+ end
277
+ sound.TimePosition = 0
278
+ end
279
+ end
280
+ --[[
281
+ *
282
+ * Resets every Sound from every Sound Category
283
+ * @param category Sound Category
284
+
285
+ ]]
286
+ local function resetAllCategories(category)
287
+ local config = definitions[category]
288
+ local ReplicatedStorage = game:GetService("ReplicatedStorage")
289
+ local soundsFolder = ReplicatedStorage:FindFirstChild("Sounds")
290
+ if not soundsFolder then
291
+ return nil
292
+ end
293
+ for _, folder in soundsFolder:GetChildren() do
294
+ if not folder:IsA("Folder") then
295
+ continue
296
+ end
297
+ for _1, sound in folder:GetChildren() do
298
+ if not sound:IsA("Sound") then
299
+ continue
300
+ end
301
+ sound.TimePosition = 0
302
+ end
303
+ end
304
+ end
305
+ --[[
306
+ *
307
+ * Preloads a Sound Category
308
+ * @param category Sound Category
309
+
310
+ ]]
311
+ local function preloadCategory(category)
312
+ loadCategory(category)
313
+ end
314
+ --[[
315
+ *
316
+ * Preloads every Sound Category
317
+
318
+ ]]
319
+ local function preloadAllCategories()
320
+ for category in pairs(definitions) do
321
+ loadCategory(category)
322
+ end
323
+ end
324
+ --[[
325
+ *
326
+ * Smoothly fade in a Sound Category
327
+ * @param category Sound Category
328
+ * @param duration Duration
329
+ * @param volume Volume
330
+
331
+ ]]
332
+ local function fadeInCategory(category, duration, volume)
333
+ local config = definitions[category]
334
+ local ReplicatedStorage = game:GetService("ReplicatedStorage")
335
+ local soundsFolder = ReplicatedStorage:FindFirstChild("Sounds")
336
+ if not soundsFolder then
337
+ return nil
338
+ end
339
+ local categoryFolder = soundsFolder:FindFirstChild(config.category)
340
+ if not categoryFolder then
341
+ return nil
342
+ end
343
+ for _, sound in categoryFolder:GetChildren() do
344
+ if not sound:IsA("Sound") then
345
+ continue
346
+ end
347
+ sound.Volume = 0
348
+ sound:Play()
349
+ local step = 0.05
350
+ local interval = duration * step
351
+ task.spawn(function()
352
+ local vol = 0
353
+ while vol < volume do
354
+ vol += step
355
+ sound.Volume = math.clamp(vol, 0, volume)
356
+ task.wait(interval)
357
+ end
358
+ end)
359
+ end
360
+ end
361
+ --[[
362
+ *
363
+ * Smoothly fade out a Sound Category
364
+ * @param category Sound Category
365
+ * @param duration Duration
366
+ * @param targetVolume Target Volume
367
+
368
+ ]]
369
+ local function fadeOutCategory(category, duration, targetVolume)
370
+ local config = definitions[category]
371
+ local ReplicatedStorage = game:GetService("ReplicatedStorage")
372
+ local soundsFolder = ReplicatedStorage:FindFirstChild("Sounds")
373
+ if not soundsFolder then
374
+ return nil
375
+ end
376
+ local categoryFolder = soundsFolder:FindFirstChild(config.category)
377
+ if not categoryFolder then
378
+ return nil
379
+ end
380
+ for _, sound in categoryFolder:GetChildren() do
381
+ if not sound:IsA("Sound") then
382
+ continue
383
+ end
384
+ local startVolume = sound.Volume
385
+ local _condition = targetVolume
386
+ if _condition == nil then
387
+ _condition = 0
388
+ end
389
+ local endVolume = _condition
390
+ local step = 0.05
391
+ local interval = duration * step
392
+ task.spawn(function()
393
+ local vol = startVolume
394
+ while vol > endVolume do
395
+ vol = math.clamp(vol - step, endVolume, startVolume)
396
+ sound.Volume = vol
397
+ task.wait(interval)
398
+ end
399
+ sound.Volume = endVolume
400
+ if endVolume == 0 then
401
+ sound:Stop()
402
+ end
403
+ end)
404
+ end
405
+ end
406
+ --[[
407
+ *
408
+ * Does something on Category end
409
+ * @param category Sound Category
410
+ * @param callback Callback
411
+
412
+ ]]
413
+ local function onCategoryEnd(category, callback)
414
+ local config = definitions[category]
415
+ local ReplicatedStorage = game:GetService("ReplicatedStorage")
416
+ local soundsFolder = ReplicatedStorage:FindFirstChild("Sounds")
417
+ if not soundsFolder then
418
+ return nil
419
+ end
420
+ local categoryFolder = soundsFolder:FindFirstChild(config.category)
421
+ if not categoryFolder then
422
+ return nil
423
+ end
424
+ local _exp = categoryFolder:GetChildren()
425
+ -- ▼ ReadonlyArray.filter ▼
426
+ local _newValue = {}
427
+ local _callback = function(s)
428
+ return s:IsA("Sound")
429
+ end
430
+ local _length = 0
431
+ for _k, _v in _exp do
432
+ if _callback(_v, _k - 1, _exp) == true then
433
+ _length += 1
434
+ _newValue[_length] = _v
435
+ end
436
+ end
437
+ -- ▲ ReadonlyArray.filter ▲
438
+ local sounds = _newValue
439
+ if #sounds == 0 then
440
+ return nil
441
+ end
442
+ local remaining = #sounds
443
+ for _, sound in sounds do
444
+ sound.Ended:Connect(function()
445
+ remaining -= 1
446
+ if remaining <= 0 then
447
+ callback()
448
+ end
449
+ end)
450
+ end
451
+ end
82
452
  return {
83
453
  loadCategory = loadCategory,
84
454
  playCategory = playCategory,
455
+ stopCategory = stopCategory,
456
+ stopAllCategories = stopAllCategories,
457
+ setCategoryVolume = setCategoryVolume,
458
+ setGlobalCategoryVolume = setGlobalCategoryVolume,
459
+ isCategoryPlaying = isCategoryPlaying,
460
+ playSoundFromCategory = playSoundFromCategory,
461
+ resetCategory = resetCategory,
462
+ resetAllCategories = resetAllCategories,
463
+ preloadAllCategories = preloadAllCategories,
464
+ preloadCategory = preloadCategory,
465
+ fadeInCategory = fadeInCategory,
466
+ fadeOutCategory = fadeOutCategory,
467
+ onCategoryEnd = onCategoryEnd,
85
468
  }
86
469
  end
87
470
  return {
@@ -18,4 +18,5 @@ export declare function createSoundRegistry<T extends Record<string, SoundOption
18
18
  setVolume: (sound: keyof T, volume: number) => void;
19
19
  resetAll: (sound: keyof T) => void;
20
20
  onEnd: (sound: keyof T, callback: () => void) => void;
21
+ isPlaying: (sound: keyof T) => boolean;
21
22
  };
@@ -222,7 +222,7 @@ local function createSoundRegistry(definitions)
222
222
  end
223
223
  --[[
224
224
  *
225
- * Plays Sound on Event Callback
225
+ * Does something on Sound end
226
226
  * @param name Sound Name
227
227
  * @param callback Callback
228
228
 
@@ -243,6 +243,21 @@ local function createSoundRegistry(definitions)
243
243
  local function preload(sound)
244
244
  load(sound)
245
245
  end
246
+ --[[
247
+ *
248
+ * Check whether a Sound is playing
249
+ * @param sound Sound Instance
250
+ * @returns Boolean
251
+
252
+ ]]
253
+ local function isPlaying(sound)
254
+ local _sound = folder:WaitForChild(sound)
255
+ if _sound.IsPlaying == true then
256
+ return true
257
+ else
258
+ return false
259
+ end
260
+ end
246
261
  return {
247
262
  play = play,
248
263
  stop = stop,
@@ -258,6 +273,7 @@ local function createSoundRegistry(definitions)
258
273
  setVolume = setVolume,
259
274
  resetAll = resetAll,
260
275
  onEnd = onEnd,
276
+ isPlaying = isPlaying,
261
277
  }
262
278
  end
263
279
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rbxts/sound-manager",
3
- "version": "2.0.1",
3
+ "version": "2.1.0",
4
4
  "description": "A sound manager for Roblox-Typescript projects.",
5
5
  "main": "out/init.lua",
6
6
  "scripts": {