1using NaughtyAttributes;
5using System.Collections.Generic;
8using Random = UnityEngine.Random;
18 [AddComponentMenu(
"Ryle Radio/Radio Output")]
19 [RequireComponent(typeof(AudioSource))]
41 protected List<RadioTrackPlayer>
players =
new();
61 public List<RadioObserver>
Observers {
get;
private set; } =
new();
66 public Action<float>
OnTune {
get;
set; } =
new(_ => { });
97 get => Mathf.Round(
tune * 10) / 10;
174 int indexInData =
Data.TrackIDs.IndexOf(_player.TrackW.id);
177 int indexForNewPlayer =
players.Count;
180 for (
int i = 0; i <
players.Count; i++)
182 if (
Data.TrackIDs.IndexOf(
players[i].TrackW.id) > indexInData)
184 indexForNewPlayer = i;
193 players.Insert(indexForNewPlayer, _player);
234 player.DoDestroy += player =>
246 Debug.LogWarning($
"Can't find track with id {_id} to play as a one-shot!");
274 Debug.LogWarning($
"Can't find track with id {_id} to play as a loop!");
292 bool _createNew =
false,
297 var found =
players.Where(p => p.TrackW.id == _trackID);
300 if (found.Count() > 1)
303 switch (_multiplePlayerSelector)
307 _player = found.Last();
312 _player = found.First();
317 int index =
Random.Range(0, found.Count());
318 _player = found.ElementAt(index);
327 else if (found.Count() > 0)
330 _player = found.First();
365 int monoSampleCount = _data.Length / _channels;
368 for (
int index = 0; index < monoSampleCount; index++)
372 float combinedVolume = 0;
384 combinedVolume += outVolume;
390 int indexWithChannels = index * _channels;
393 for (
int channel = indexWithChannels; channel < indexWithChannels + _channels; channel++)
394 _data[channel] += sample;
A scene component that holds a reference to a RadioData.
RadioData Data
Read-only accessor for data.
RadioData data
The RadioData (aka just radio) that this component is linked to.
A component used to watch for specific happenings on a RadioOutput, e.g: a clip being a certain volum...
string[] AffectedTracks
The tracks selected on this Observer.
void AssignEvents(RadioTrackPlayer _player)
Assigns each event to a RadioTrackPlayer for one of our AffectedTracks. This is called when a new Rad...
The main scene component for a radio that plays it through an AudioSource.
RadioTrackPlayer PlayLoop(string _id)
Plays a track as a loop. A loop restarts when the track ends, then continues to play.
Action< float > OnTune
Event called whenever Tune is changed.
List< RadioObserver > Observers
Every RadioObserver associated with this output.
float Tune01
Tune scaled to [0 - 1], useful for UI
void LocalInit()
Initializes the RadioData- this needs to be separated from Init() as it would be recursive otherwise.
virtual void OnAudioFilterRead(float[] _data, int _channels)
Gets a set of samples from the radio to play from the AudioSource- this preserves the settings on the...
float Tune
The tune clamped to the full range.
void StartPlayers()
Creates every RadioTrackPlayer that this output needs for playback.
Vector3 cachedPos
The position of this object as of the last frame update. We can't access transform....
float DisplayTune
Tune with limited decimal points- looks better when displayed, more like an actual radio
Action playEvents
Called at the end of every audio cycle so that we don't interrupt threads when manipulating RadioTrac...
override void Init()
Initializes the output itself, and creates all required every required RadioTrackPlayer.
float tune
The current tune value of this output- akin to the frequency of a real radio. Controls what tracks ca...
List< RadioTrackPlayer > players
The players used by this output.
MultiplePlayersSelector
The method by which a RadioTrackPlayer is chosen from this output. Really only matters when you're pl...
@ Oldest
Selects the oldest player.
@ Random
Selects a random player (probably useless but funny to have)
@ Youngest
Selects the youngest player.
void PlayerCreation(RadioTrackPlayer _player)
Sets up and stores a new RadioTrackPlayer and alerts any RadioObserver of its creation.
float baseSampleRate
The normal sample rate of this output, applied to each RadioTrackPlayer.
void ExecOnTune()
Called when tune is modified in the inspector.
bool TryGetPlayer(string _trackID, out RadioTrackPlayer _player, bool _createNew=false, MultiplePlayersSelector _multiplePlayerSelector=MultiplePlayersSelector.Youngest)
Gets an active RadioTrackPlayer from this output.
virtual void Update()
Updates cachedPos.
RadioTrackPlayer PlayOneShot(string _id)
Plays a track as a one-shot. A one-shot destroys itself when its track ends.
The central data object defining the radio. Contains the tracks and information required to play the ...
const float LOW_TUNE
The lower limit for tune on this radio. This may become non-const at some point.
const float HIGH_TUNE
The upper limit for tune on this radio. This may become non-const at some point.
A class that plays a certain RadioTrack at runtime. It's created newly for each track on each RadioOu...
float GetSample(float _tune, Vector3 _receiverPosition, float _otherVolume, out float _outVolume, bool _applyVolume=true)
Gets the current sample from the track according to playback. I would recommend reading the code comm...
PlayerType
The different types of Player- mainly changes what it does when the end of the track is reached.
void IncrementSample()
Move this player to the next sample.
A wrapper class for RadioTrack so that track types can be switched between in the inspector!...
bool playOnInit
If true, this track plays on RadioData.Init() - usually on game start.
Base interfaces and classes for components, e.g: track accessors, output accessors.
Components to be placed on scene objects, e.g: Outputs, Broadcasters, Observers.
Tracks to be used on a radio- includes base classes.