mirror of
https://github.com/RHeavenStudioPlus/HeavenStudioPlus.git
synced 2024-11-24 18:45:15 +00:00
Bouncy Road improvements (#944)
* Add custom notes to Bouncy Road + fix swing animations * Add simple tap controls to Bouncy Road * Add blank pole sounds + volume panning to Bouncy Road
This commit is contained in:
parent
95e658f31e
commit
049959bed3
4 changed files with 156 additions and 27 deletions
22
Assets/Resources/Sfx/games/bouncyRoad/leftBlank.ogg.meta
Normal file
22
Assets/Resources/Sfx/games/bouncyRoad/leftBlank.ogg.meta
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9b584037609d9084aa8a838607884dcc
|
||||||
|
AudioImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 6
|
||||||
|
defaultSettings:
|
||||||
|
loadType: 0
|
||||||
|
sampleRateSetting: 0
|
||||||
|
sampleRateOverride: 44100
|
||||||
|
compressionFormat: 1
|
||||||
|
quality: 1
|
||||||
|
conversionMode: 0
|
||||||
|
platformSettingOverrides: {}
|
||||||
|
forceToMono: 0
|
||||||
|
normalize: 1
|
||||||
|
preloadAudioData: 1
|
||||||
|
loadInBackground: 0
|
||||||
|
ambisonic: 0
|
||||||
|
3D: 1
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
22
Assets/Resources/Sfx/games/bouncyRoad/rightBlank.ogg.meta
Normal file
22
Assets/Resources/Sfx/games/bouncyRoad/rightBlank.ogg.meta
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c0997440911c8a543b05babc2e2ed806
|
||||||
|
AudioImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 6
|
||||||
|
defaultSettings:
|
||||||
|
loadType: 0
|
||||||
|
sampleRateSetting: 0
|
||||||
|
sampleRateOverride: 44100
|
||||||
|
compressionFormat: 1
|
||||||
|
quality: 1
|
||||||
|
conversionMode: 0
|
||||||
|
platformSettingOverrides: {}
|
||||||
|
forceToMono: 0
|
||||||
|
normalize: 1
|
||||||
|
preloadAudioData: 1
|
||||||
|
loadInBackground: 0
|
||||||
|
ambisonic: 0
|
||||||
|
3D: 1
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -15,6 +15,12 @@ namespace HeavenStudio.Games.Scripts_BouncyRoad
|
||||||
|
|
||||||
public Color color;
|
public Color color;
|
||||||
[System.NonSerialized] public bool goal;
|
[System.NonSerialized] public bool goal;
|
||||||
|
[System.NonSerialized] public bool useCustomNotes;
|
||||||
|
[System.NonSerialized] public int[] bounceNotes;
|
||||||
|
[System.NonSerialized] public int bounceNote;
|
||||||
|
[System.NonSerialized] public int rightNote;
|
||||||
|
[System.NonSerialized] public int leftNote;
|
||||||
|
[System.NonSerialized] public int goalNote;
|
||||||
|
|
||||||
private bool isMiss;
|
private bool isMiss;
|
||||||
|
|
||||||
|
@ -33,9 +39,9 @@ namespace HeavenStudio.Games.Scripts_BouncyRoad
|
||||||
|
|
||||||
if (currentCurve is not null)
|
if (currentCurve is not null)
|
||||||
{
|
{
|
||||||
float curveProg = cond.GetPositionFromBeat(currentBeat, lengthBeat);
|
float curveProg = cond.GetPositionFromBeat(currentBeat, lengthBeat, ignoreSwing: false);
|
||||||
if (isMiss) {
|
if (isMiss) {
|
||||||
curveProg = cond.GetPositionFromBeat(currentBeat, lengthBeat/2);
|
curveProg = cond.GetPositionFromBeat(currentBeat, lengthBeat/2, ignoreSwing: false);
|
||||||
} else {
|
} else {
|
||||||
// curveProg /= (float)(1 + BouncyRoad.ngLateTime);
|
// curveProg /= (float)(1 + BouncyRoad.ngLateTime);
|
||||||
if (curveProg >= 1) curveProg = 1;
|
if (curveProg >= 1) curveProg = 1;
|
||||||
|
@ -44,9 +50,19 @@ namespace HeavenStudio.Games.Scripts_BouncyRoad
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Bounce()
|
private void Bounce() {
|
||||||
{
|
float[] pitches = null;
|
||||||
game.PlayBounceSound(startBeat, lengthBeat);
|
if (bounceNotes != null)
|
||||||
|
{
|
||||||
|
pitches = new float[12];
|
||||||
|
for (int i = 0; i < 12; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
pitches[i] = GetPitch(bounceNotes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
game.PlayBounceSound(startBeat, lengthBeat, pitches, GetPitch(bounceNote));
|
||||||
|
|
||||||
var actions = new List<BeatAction.Action>();
|
var actions = new List<BeatAction.Action>();
|
||||||
|
|
||||||
|
@ -70,7 +86,7 @@ namespace HeavenStudio.Games.Scripts_BouncyRoad
|
||||||
|
|
||||||
public void RightSuccess(PlayerActionEvent caller, float state)
|
public void RightSuccess(PlayerActionEvent caller, float state)
|
||||||
{
|
{
|
||||||
SoundByte.PlayOneShotGame("bouncyRoad/ballRight");
|
SoundByte.PlayOneShotGame("bouncyRoad/ballRight", pitch: GetPitch(rightNote));
|
||||||
game.ThingsAnim[12].Play("podium", 0, 0);
|
game.ThingsAnim[12].Play("podium", 0, 0);
|
||||||
currentCurve = curve[1+12];
|
currentCurve = curve[1+12];
|
||||||
currentBeat = startBeat + 12 * lengthBeat;
|
currentBeat = startBeat + 12 * lengthBeat;
|
||||||
|
@ -80,7 +96,7 @@ namespace HeavenStudio.Games.Scripts_BouncyRoad
|
||||||
|
|
||||||
public void RightMiss(PlayerActionEvent caller)
|
public void RightMiss(PlayerActionEvent caller)
|
||||||
{
|
{
|
||||||
SoundByte.PlayOneShotGame("bouncyRoad/ballBounce");
|
SoundByte.PlayOneShotGame("bouncyRoad/ballBounce", pitch: GetPitch(bounceNote));
|
||||||
currentCurve = curve[^2];
|
currentCurve = curve[^2];
|
||||||
currentBeat = Conductor.instance.songPositionInBeats;
|
currentBeat = Conductor.instance.songPositionInBeats;
|
||||||
isMiss = true;
|
isMiss = true;
|
||||||
|
@ -95,12 +111,12 @@ namespace HeavenStudio.Games.Scripts_BouncyRoad
|
||||||
|
|
||||||
public void LeftSuccess(PlayerActionEvent caller, float state)
|
public void LeftSuccess(PlayerActionEvent caller, float state)
|
||||||
{
|
{
|
||||||
SoundByte.PlayOneShotGame("bouncyRoad/ballLeft");
|
SoundByte.PlayOneShotGame("bouncyRoad/ballLeft", pitch: GetPitch(leftNote));
|
||||||
game.ThingsAnim[13].Play("podium", 0, 0);
|
game.ThingsAnim[13].Play("podium", 0, 0);
|
||||||
currentCurve = curve[1+13];
|
currentCurve = curve[1+13];
|
||||||
currentBeat = startBeat + 13 * lengthBeat;
|
currentBeat = startBeat + 13 * lengthBeat;
|
||||||
|
|
||||||
if (goal) SoundByte.PlayOneShotGame("bouncyRoad/goal", startBeat + 14 * lengthBeat);
|
if (goal) SoundByte.PlayOneShotGame("bouncyRoad/goal", startBeat + 14 * lengthBeat, pitch: GetPitch(goalNote));
|
||||||
BeatAction.New(game, new List<BeatAction.Action>()
|
BeatAction.New(game, new List<BeatAction.Action>()
|
||||||
{
|
{
|
||||||
new BeatAction.Action(startBeat + 14 * lengthBeat, delegate
|
new BeatAction.Action(startBeat + 14 * lengthBeat, delegate
|
||||||
|
@ -118,7 +134,7 @@ namespace HeavenStudio.Games.Scripts_BouncyRoad
|
||||||
|
|
||||||
public void LeftMiss(PlayerActionEvent caller)
|
public void LeftMiss(PlayerActionEvent caller)
|
||||||
{
|
{
|
||||||
SoundByte.PlayOneShotGame("bouncyRoad/ballBounce");
|
SoundByte.PlayOneShotGame("bouncyRoad/ballBounce", pitch: GetPitch(bounceNote));
|
||||||
currentCurve = curve[^1];
|
currentCurve = curve[^1];
|
||||||
currentBeat = Conductor.instance.songPositionInBeats;
|
currentBeat = Conductor.instance.songPositionInBeats;
|
||||||
isMiss = true;
|
isMiss = true;
|
||||||
|
@ -132,5 +148,10 @@ namespace HeavenStudio.Games.Scripts_BouncyRoad
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Empty(PlayerActionEvent caller) { }
|
public void Empty(PlayerActionEvent caller) { }
|
||||||
|
|
||||||
|
private float GetPitch(int semitones)
|
||||||
|
{
|
||||||
|
return useCustomNotes ? SoundByte.GetPitchFromSemiTones(semitones, true) : 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -24,6 +24,29 @@ namespace HeavenStudio.Games.Loaders
|
||||||
{
|
{
|
||||||
new Param("goal", true, "Play Goal Sound"),
|
new Param("goal", true, "Play Goal Sound"),
|
||||||
new Param("color", Color.white, "Color", "Choose the color of the ball."),
|
new Param("color", Color.white, "Color", "Choose the color of the ball."),
|
||||||
|
new Param("useCustomNotes", false, "Custom Notes", "Toggle if the ball should use custom notes.", new List<Param.CollapseParam>()
|
||||||
|
{
|
||||||
|
new Param.CollapseParam((x, _) => (bool)x, new string[] { "bounceNote", "rightNote", "leftNote", "goalNote", "separateBounceNotes"})
|
||||||
|
}),
|
||||||
|
new Param("separateBounceNotes", false, "Separate Bounce Notes", "Toggle if the ball should use separate notes for the each of the first 12 poles.", new List<Param.CollapseParam>()
|
||||||
|
{
|
||||||
|
new Param.CollapseParam((x, _) => (bool)x, new string[] { "bounceNote2", "bounceNote3", "bounceNote4", "bounceNote5", "bounceNote6", "bounceNote7", "bounceNote8", "bounceNote9", "bounceNote10", "bounceNote11", "bounceNote12" })
|
||||||
|
}),
|
||||||
|
new Param("bounceNote", new EntityTypes.Note(0, 7, 4, "bouncyRoad/ballBounce"), "Bounce Note", "Choose the note the ball plays when bouncing on the first 12 poles or the first pole if using custom notes."),
|
||||||
|
new Param("bounceNote2", new EntityTypes.Note(0, 7, 4, "bouncyRoad/ballBounce"), "Bounce Note 2", "Choose the note the ball plays when bouncing on the second pole."),
|
||||||
|
new Param("bounceNote3", new EntityTypes.Note(0, 7, 4, "bouncyRoad/ballBounce"), "Bounce Note 3", "Choose the note the ball plays when bouncing on the third pole."),
|
||||||
|
new Param("bounceNote4", new EntityTypes.Note(0, 7, 4, "bouncyRoad/ballBounce"), "Bounce Note 4", "Choose the note the ball plays when bouncing on the fourth pole."),
|
||||||
|
new Param("bounceNote5", new EntityTypes.Note(0, 7, 4, "bouncyRoad/ballBounce"), "Bounce Note 5", "Choose the note the ball plays when bouncing on the fifth pole."),
|
||||||
|
new Param("bounceNote6", new EntityTypes.Note(0, 7, 4, "bouncyRoad/ballBounce"), "Bounce Note 6", "Choose the note the ball plays when bouncing on the sixth pole."),
|
||||||
|
new Param("bounceNote7", new EntityTypes.Note(0, 7, 4, "bouncyRoad/ballBounce"), "Bounce Note 7", "Choose the note the ball plays when bouncing on the seventh pole."),
|
||||||
|
new Param("bounceNote8", new EntityTypes.Note(0, 7, 4, "bouncyRoad/ballBounce"), "Bounce Note 8", "Choose the note the ball plays when bouncing on the eighth pole."),
|
||||||
|
new Param("bounceNote9", new EntityTypes.Note(0, 7, 4, "bouncyRoad/ballBounce"), "Bounce Note 9", "Choose the note the ball plays when bouncing on the ninth pole."),
|
||||||
|
new Param("bounceNote10", new EntityTypes.Note(0, 7, 4, "bouncyRoad/ballBounce"), "Bounce Note 10", "Choose the note the ball plays when bouncing on the tenth pole."),
|
||||||
|
new Param("bounceNote11", new EntityTypes.Note(0, 7, 4, "bouncyRoad/ballBounce"), "Bounce Note 11", "Choose the note the ball plays when bouncing on the eleventh pole."),
|
||||||
|
new Param("bounceNote12", new EntityTypes.Note(0, 7, 4, "bouncyRoad/ballBounce"), "Bounce Note 12", "Choose the note the ball plays when bouncing on the twelfth pole."),
|
||||||
|
new Param("rightNote", new EntityTypes.Note(0, 3, 4, "bouncyRoad/ballRight"), "A Note", "Choose the note the ball plays when it bounces on the A pole."),
|
||||||
|
new Param("leftNote", new EntityTypes.Note(0, 10, 4, "bouncyRoad/ballLeft"), "+ Note", "Choose the note the ball plays when it bounces on the + pole."),
|
||||||
|
new Param("goalNote", new EntityTypes.Note(0, 3, 5, "bouncyRoad/goal"), "Goal Note", "Choose the note the ball plays when it bounces on the last pole."),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new GameAction("background appearance", "Background Appearance")
|
new GameAction("background appearance", "Background Appearance")
|
||||||
|
@ -87,12 +110,20 @@ namespace HeavenStudio.Games
|
||||||
private ColorEase[] colorEases = new ColorEase[2];
|
private ColorEase[] colorEases = new ColorEase[2];
|
||||||
|
|
||||||
const double BALL_SEEK_TIME = 1.0;
|
const double BALL_SEEK_TIME = 1.0;
|
||||||
private struct ScheduledBall
|
|
||||||
|
public struct ScheduledBall
|
||||||
{
|
{
|
||||||
public double beat;
|
public double beat;
|
||||||
public double length;
|
public double length;
|
||||||
public bool goal;
|
public bool goal;
|
||||||
public Color color;
|
public Color color;
|
||||||
|
public bool useCustomNotes;
|
||||||
|
public bool seperateBounceNotes;
|
||||||
|
public int[] bounceNotes;
|
||||||
|
public int bounceNote;
|
||||||
|
public int rightNote;
|
||||||
|
public int leftNote;
|
||||||
|
public int goalNote;
|
||||||
}
|
}
|
||||||
List<ScheduledBall> scheduledBalls = new();
|
List<ScheduledBall> scheduledBalls = new();
|
||||||
int ballIndex;
|
int ballIndex;
|
||||||
|
@ -111,16 +142,18 @@ namespace HeavenStudio.Games
|
||||||
}
|
}
|
||||||
protected static bool IA_TouchLeft(out double dt)
|
protected static bool IA_TouchLeft(out double dt)
|
||||||
{
|
{
|
||||||
return PlayerInput.GetTouchDown(InputController.ActionsTouch.Left, out dt);
|
return PlayerInput.GetTouchDown(InputController.ActionsTouch.Tap, out dt) && instance.IsExpectingInputNow(InputAction_Left);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static bool IA_PadRight(out double dt)
|
protected static bool IA_PadRight(out double dt)
|
||||||
{
|
{
|
||||||
return PlayerInput.GetPadDown(InputController.ActionsPad.East, out dt);
|
return PlayerInput.GetPadDown(InputController.ActionsPad.East, out dt);
|
||||||
}
|
}
|
||||||
protected static bool IA_TouchRight(out double dt)
|
protected static bool IA_TouchRight(out double dt) {
|
||||||
{
|
return PlayerInput.GetTouchDown(InputController.ActionsTouch.Tap, out dt)
|
||||||
return PlayerInput.GetTouchDown(InputController.ActionsTouch.Right, out dt);
|
&& (instance.IsExpectingInputNow(InputAction_Right)
|
||||||
|
|| (!instance.IsExpectingInputNow(InputAction_Left) && !instance.IsExpectingInputNow(InputAction_Right)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PlayerInput.InputAction InputAction_Left =
|
public static PlayerInput.InputAction InputAction_Left =
|
||||||
|
@ -204,12 +237,30 @@ namespace HeavenStudio.Games
|
||||||
foreach (var e in events)
|
foreach (var e in events)
|
||||||
{
|
{
|
||||||
if (e.length == 0) continue;
|
if (e.length == 0) continue;
|
||||||
|
|
||||||
|
int[] bounceNotes = null;
|
||||||
|
if (e["separateBounceNotes"]) {
|
||||||
|
bounceNotes = new int[12];
|
||||||
|
bounceNotes[0] = e["bounceNote"];
|
||||||
|
for (int i = 1; i < 12; i++)
|
||||||
|
{
|
||||||
|
bounceNotes[i] = e[$"bounceNote{i+1}"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var ball = new ScheduledBall
|
var ball = new ScheduledBall
|
||||||
{
|
{
|
||||||
beat = e.beat,
|
beat = e.beat,
|
||||||
length = e.length,
|
length = e.length,
|
||||||
goal = e["goal"],
|
goal = e["goal"],
|
||||||
color = e["color"],
|
color = e["color"],
|
||||||
|
useCustomNotes = e["useCustomNotes"],
|
||||||
|
seperateBounceNotes = e["separateBounceNotes"],
|
||||||
|
bounceNotes = bounceNotes,
|
||||||
|
bounceNote = e["bounceNote"],
|
||||||
|
rightNote = e["rightNote"],
|
||||||
|
leftNote = e["leftNote"],
|
||||||
|
goalNote = e["goalNote"],
|
||||||
};
|
};
|
||||||
scheduledBalls.Add(ball);
|
scheduledBalls.Add(ball);
|
||||||
}
|
}
|
||||||
|
@ -228,10 +279,12 @@ namespace HeavenStudio.Games
|
||||||
if (PlayerInput.GetIsAction(InputAction_Right) && !IsExpectingInputNow(InputAction_Right))
|
if (PlayerInput.GetIsAction(InputAction_Right) && !IsExpectingInputNow(InputAction_Right))
|
||||||
{
|
{
|
||||||
ThingsAnim[12].Play("podium", 0, 0);
|
ThingsAnim[12].Play("podium", 0, 0);
|
||||||
|
SoundByte.PlayOneShotGame("bouncyRoad/rightBlank", volume: .5f);
|
||||||
}
|
}
|
||||||
if (PlayerInput.GetIsAction(InputAction_Left) && !IsExpectingInputNow(InputAction_Left))
|
if (PlayerInput.GetIsAction(InputAction_Left) && !IsExpectingInputNow(InputAction_Left))
|
||||||
{
|
{
|
||||||
ThingsAnim[13].Play("podium", 0, 0);
|
ThingsAnim[13].Play("podium", 0, 0);
|
||||||
|
SoundByte.PlayOneShotGame("bouncyRoad/leftBlank", volume: .5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateBalls();
|
UpdateBalls();
|
||||||
|
@ -246,7 +299,7 @@ namespace HeavenStudio.Games
|
||||||
var ball = scheduledBalls[ballIndex];
|
var ball = scheduledBalls[ballIndex];
|
||||||
if (ball.beat - ball.length < beat + BALL_SEEK_TIME)
|
if (ball.beat - ball.length < beat + BALL_SEEK_TIME)
|
||||||
{
|
{
|
||||||
SpawnBall(ball.beat, ball.length, ball.goal, ball.color);
|
SpawnBall(ball);
|
||||||
ballIndex++;
|
ballIndex++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -256,20 +309,26 @@ namespace HeavenStudio.Games
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SpawnBall(double beat, double length, bool goal, Color color)
|
public void SpawnBall(ScheduledBall scheduledBall)
|
||||||
{
|
{
|
||||||
var newBall = Instantiate(baseBall, transform).GetComponent<Ball>();
|
var newBall = Instantiate(baseBall, transform).GetComponent<Ball>();
|
||||||
|
|
||||||
newBall.startBeat = beat;
|
newBall.startBeat = scheduledBall.beat;
|
||||||
newBall.lengthBeat = length;
|
newBall.lengthBeat = scheduledBall.length;
|
||||||
newBall.goal = goal;
|
newBall.goal = scheduledBall.goal;
|
||||||
newBall.color = color;
|
newBall.color = scheduledBall.color;
|
||||||
|
newBall.useCustomNotes = scheduledBall.useCustomNotes;
|
||||||
|
newBall.bounceNotes = scheduledBall.bounceNotes;
|
||||||
|
newBall.bounceNote = scheduledBall.bounceNote;
|
||||||
|
newBall.rightNote = scheduledBall.rightNote;
|
||||||
|
newBall.leftNote = scheduledBall.leftNote;
|
||||||
|
newBall.goalNote = scheduledBall.goalNote;
|
||||||
|
|
||||||
newBall.curve = GetHeightCurve((float)length);
|
newBall.curve = GetHeightCurve((float)scheduledBall.length);
|
||||||
|
|
||||||
BeatAction.New(instance, new List<BeatAction.Action>()
|
BeatAction.New(instance, new List<BeatAction.Action>()
|
||||||
{
|
{
|
||||||
new BeatAction.Action(beat - length, delegate
|
new BeatAction.Action(scheduledBall.beat - scheduledBall.length, delegate
|
||||||
{
|
{
|
||||||
newBall.Init();
|
newBall.Init();
|
||||||
newBall.gameObject.SetActive(true);
|
newBall.gameObject.SetActive(true);
|
||||||
|
@ -278,13 +337,18 @@ namespace HeavenStudio.Games
|
||||||
}
|
}
|
||||||
|
|
||||||
List<double> bounceBeats = new();
|
List<double> bounceBeats = new();
|
||||||
public void PlayBounceSound(double beat, double length)
|
public void PlayBounceSound(double beat, double length, float[] pitches, float singlePitch)
|
||||||
{
|
{
|
||||||
var sounds = new List<MultiSound.Sound>();
|
var sounds = new List<MultiSound.Sound>();
|
||||||
for (int i = 0; i < 12 ; i++)
|
float volume = .65f;
|
||||||
{
|
for (int i = 0; i < 12 ; i++) {
|
||||||
|
if (i >= 6) volume += .059f;
|
||||||
|
|
||||||
var bounceBeat = beat + i * length;
|
var bounceBeat = beat + i * length;
|
||||||
if (!bounceBeats.Contains(bounceBeat)) sounds.Add(new MultiSound.Sound("bouncyRoad/ballBounce", bounceBeat));
|
if (!bounceBeats.Contains(bounceBeat)) {
|
||||||
|
float pitch = pitches == null ? singlePitch : pitches[i];
|
||||||
|
sounds.Add(new MultiSound.Sound("bouncyRoad/ballBounce", bounceBeat, pitch, volume));
|
||||||
|
}
|
||||||
bounceBeats.Add(bounceBeat);
|
bounceBeats.Add(bounceBeat);
|
||||||
}
|
}
|
||||||
MultiSound.Play(sounds.ToArray());
|
MultiSound.Play(sounds.ToArray());
|
||||||
|
|
Loading…
Reference in a new issue