Skip to content

Commit 8cb6a1b

Browse files
add audio support for SER
1 parent 3a0a5e6 commit 8cb6a1b

File tree

7 files changed

+259
-4
lines changed

7 files changed

+259
-4
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using SER.ArgumentSystem.Arguments;
2+
using SER.ArgumentSystem.BaseArguments;
3+
using SER.MethodSystem.BaseMethods;
4+
5+
namespace SER.MethodSystem.Methods.AudioMethods;
6+
7+
public class CreateGlobalSpeakerMethod : SynchronousMethod
8+
{
9+
public override string Description => "Creates a speaker to play audio through.";
10+
11+
public override Argument[] ExpectedArguments { get; } =
12+
[
13+
new TextArgument("speaker name"),
14+
new FloatArgument("volume", 0f)
15+
{
16+
DefaultValue = new(1f, "100%"),
17+
Description = "The volume of the audio."
18+
},
19+
new PlayersArgument("target players")
20+
{
21+
DefaultValue = new(null, "all"),
22+
Description = "If specified, only the provided players will hear the audio."
23+
}
24+
];
25+
26+
public override void Execute()
27+
{
28+
var targetPlayers = Args.GetPlayers("target players");
29+
30+
AudioPlayer.Create(
31+
Args.GetText("speaker name"),
32+
condition: hub =>
33+
{
34+
if (targetPlayers is null) return true;
35+
36+
return targetPlayers.Any(p => p.ReferenceHub == hub);
37+
},
38+
onIntialCreation: p =>
39+
{
40+
p.AddSpeaker("Main", Args.GetFloat("volume"), isSpatial: false, maxDistance: 5000f);
41+
}
42+
);
43+
}
44+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
using SER.ArgumentSystem.Arguments;
2+
using SER.ArgumentSystem.BaseArguments;
3+
using SER.Helpers.Exceptions;
4+
using SER.MethodSystem.BaseMethods;
5+
using SER.MethodSystem.MethodDescriptors;
6+
using UnityEngine;
7+
8+
namespace SER.MethodSystem.Methods.AudioMethods;
9+
10+
public class CreatePlayerAttachedSpeakerMethod : SynchronousMethod, ICanError
11+
{
12+
public override string Description => "Creates a speaker attached to the player to play audio through.";
13+
14+
public string[] ErrorReasons =>
15+
[
16+
"Player does not have a model to attach a speaker to."
17+
];
18+
19+
public override Argument[] ExpectedArguments { get; } =
20+
[
21+
new PlayerArgument("player to attach"),
22+
new TextArgument("speaker name"),
23+
new FloatArgument("volume", 0f)
24+
{
25+
DefaultValue = new(1f, "100%"),
26+
Description = "The volume of the audio."
27+
},
28+
new FloatArgument("min distance", 0f)
29+
{
30+
DefaultValue = new(5f, null),
31+
Description = "The minimum distance for full-volume audio."
32+
},
33+
new FloatArgument("max distance", 0f)
34+
{
35+
DefaultValue = new(15f, null),
36+
Description = "The maximum audible distance for the audio."
37+
},
38+
new BoolArgument("is stereo")
39+
{
40+
DefaultValue = new(null, "true"),
41+
Description = "Whether the audio will be 3D."
42+
},
43+
new PlayersArgument("target players")
44+
{
45+
DefaultValue = new(null, "all"),
46+
Description = "If specified, only the provided players will hear the audio."
47+
}
48+
];
49+
50+
public override void Execute()
51+
{
52+
var player = Args.GetPlayer("player to attach");
53+
var speakerName = Args.GetText("speaker name");
54+
var volume = Args.GetFloat("volume");
55+
var minDistance = Args.GetFloat("min distance");
56+
var maxDistance = Args.GetFloat("max distance");
57+
var isStereo = Args.GetBool("is stereo");
58+
var targetPlayers = Args.GetPlayers("target players");
59+
60+
AudioPlayer.Create(
61+
speakerName,
62+
condition: hub =>
63+
{
64+
if (targetPlayers is null) return true;
65+
66+
return targetPlayers.Any(p => p.ReferenceHub == hub);
67+
},
68+
onIntialCreation: p =>
69+
{
70+
p.transform.parent = player.GameObject?.transform
71+
?? throw new ScriptRuntimeError(
72+
$"Player '{player.Nickname}' does not have a model to attach a speaker to.");
73+
74+
Speaker speaker = p.AddSpeaker("Main", volume, isStereo, minDistance, maxDistance);
75+
76+
speaker.transform.parent = player.GameObject.transform;
77+
speaker.transform.localPosition = Vector3.zero;
78+
}
79+
);
80+
}
81+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using SER.ArgumentSystem.Arguments;
2+
using SER.ArgumentSystem.BaseArguments;
3+
using SER.MethodSystem.BaseMethods;
4+
5+
namespace SER.MethodSystem.Methods.AudioMethods;
6+
7+
public class DestroySpeakerMethod : SynchronousMethod
8+
{
9+
public override string Description => "Destorys a speaker.";
10+
11+
public override Argument[] ExpectedArguments { get; } =
12+
[
13+
new TextArgument("speaker name"),
14+
];
15+
16+
public override void Execute()
17+
{
18+
if (AudioPlayer.TryGet(Args.GetText("speaker name"), out var ap))
19+
{
20+
UnityEngine.Object.Destroy(ap);
21+
}
22+
}
23+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using SER.ArgumentSystem.Arguments;
2+
using SER.ArgumentSystem.BaseArguments;
3+
using SER.MethodSystem.BaseMethods;
4+
using SER.ValueSystem;
5+
6+
namespace SER.MethodSystem.Methods.AudioMethods;
7+
8+
public class IsAudioLoadedMethod : ReturningMethod<BoolValue>
9+
{
10+
public override string Description => "Returns true if a given audio clip has been loaded";
11+
12+
public override Argument[] ExpectedArguments =>
13+
[
14+
new TextArgument("clip name")
15+
{
16+
Description = "This is NOT the path or the file name, but a clip name"
17+
}
18+
];
19+
20+
public override void Execute()
21+
{
22+
ReturnValue = AudioClipStorage.AudioClips.ContainsKey(Args.GetText("clip name"));
23+
}
24+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using SER.ArgumentSystem.Arguments;
2+
using SER.ArgumentSystem.BaseArguments;
3+
using SER.Helpers.Exceptions;
4+
using SER.MethodSystem.BaseMethods;
5+
using SER.MethodSystem.MethodDescriptors;
6+
7+
namespace SER.MethodSystem.Methods.AudioMethods;
8+
9+
public class LoadAudioMethod : SynchronousMethod, IAdditionalDescription, ICanError
10+
{
11+
public override string Description => "Loads an audio file into the audio player.";
12+
13+
public string AdditionalDescription =>
14+
"SER is using 'AudioPlayerApi' to manage audio. If the method errors, the logs will be displayed by AudioPlayerApi, not SER.";
15+
16+
public string[] ErrorReasons =>
17+
[
18+
"File doesn't exist",
19+
"File was already loaded",
20+
"File is not of type 'ogg'"
21+
];
22+
23+
public override Argument[] ExpectedArguments { get; } =
24+
[
25+
new TextArgument("file path"),
26+
new TextArgument("clip name")
27+
{
28+
Description = "You will be using this name to refer to this path."
29+
}
30+
];
31+
32+
public override void Execute()
33+
{
34+
if (!AudioClipStorage.LoadClip(
35+
Args.GetText("file path"),
36+
Args.GetText("clip name")
37+
)) throw new ScriptRuntimeError("Audio has failed to load");
38+
}
39+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
using SER.ArgumentSystem.Arguments;
2+
using SER.ArgumentSystem.BaseArguments;
3+
using SER.Helpers.Exceptions;
4+
using SER.MethodSystem.BaseMethods;
5+
using SER.MethodSystem.MethodDescriptors;
6+
7+
namespace SER.MethodSystem.Methods.AudioMethods;
8+
9+
public class PlayAudioMethod : SynchronousMethod, ICanError
10+
{
11+
public override string Description => "Plays a loaded audio clip from a created speaker.";
12+
13+
public string[] ErrorReasons =>
14+
[
15+
"Speaker does not exist."
16+
];
17+
18+
public override Argument[] ExpectedArguments { get; } =
19+
[
20+
new TextArgument("speaker name"),
21+
new TextArgument("clip name"),
22+
new BoolArgument("loop music")
23+
{
24+
DefaultValue = new(false, null)
25+
}
26+
];
27+
28+
public override void Execute()
29+
{
30+
var speakerName = Args.GetText("speaker name");
31+
var clipName = Args.GetText("clip name");
32+
33+
if (!AudioPlayer.TryGet(speakerName, out AudioPlayer audioPlayer))
34+
throw new ScriptRuntimeError($"Speaker with name '{speakerName}' does not exist.");
35+
36+
audioPlayer.AddClip(clipName, loop: Args.GetBool("loop music"));
37+
}
38+
}

SER.csproj

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,17 @@
7878
</ItemGroup>
7979

8080
<ItemGroup>
81-
<PackageReference Include="Costura.Fody" Version="6.0.0" PrivateAssets='All' />
82-
81+
<PackageReference Include="AudioPlayerApi" Version="1.1.2" />
82+
<PackageReference Include="Costura.Fody" Version="6.0.0" PrivateAssets="All" />
8383
<PackageReference Include="Fody" Version="6.9.3" />
84-
8584
<PackageReference Include="ncalc" Version="1.3.8" />
8685
</ItemGroup>
87-
86+
87+
<!-- older versions of packages use different versions of these -->
88+
<!-- this forces them to use the newest, silencing the warnings -->
89+
<ItemGroup>
90+
<PackageReference Include="System.Memory" Version="4.6.0" />
91+
<PackageReference Include="System.Numerics.Vectors" Version="4.6.0" />
92+
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.1.0" />
93+
</ItemGroup>
8894
</Project>

0 commit comments

Comments
 (0)