Skip to content

Instantly share code, notes, and snippets.

@williamozeas
Created April 21, 2023 02:36
Show Gist options
  • Save williamozeas/2d7c7931f25934cea49008ecd7882421 to your computer and use it in GitHub Desktop.
Save williamozeas/2d7c7931f25934cea49008ecd7882421 to your computer and use it in GitHub Desktop.
Sound effect tracker to implement reversed SFX for time reversal mechanic for Giuseppe, a game made in ~4 weeks by Weekender Studios as part of CMU 53-471 Game Design, Prototyping & Production in Spring 2023. Full game
/*Code by William Ozeas. Redistribution is not permitted.
* Sound effect tracker to implement reversed SFX for time reversal mechanic for Giuseppe, a game made in ~4 weeks by
* Weekender Studios as part of CMU 53-471 Game Design, Prototyping & Production in Spring 2023. Full game can be
* found here: https://willozeas.itch.io/giuseppe
*/
/* Boilerplate code omitted */
/* ReversibleSoundEffect - a sound effect container class that keeps track of when a sound effect was played,
its source, timeline, and an action that sets relevant SFX parameters in a lambda function. */
public class ReversibleSoundEffect
{
public (float, float) times;
private Action _sfxAction;
private InstancedRewindManager _manager = null;
private AudioSource _source;
private Timeline _timeline;
public ReversibleSoundEffect(Action sfxAction, AudioSource source, Timeline timeline, float length = -1f)
{
/* Code setting initialization variables omitted */
times = (GameManager.Instance.Time, GameManager.Instance.Time + length);
}
public void Play()
{
_source.pitch = 1;
_source.timeSamples = 0;
_sfxAction();
switch (_timeline)
{
case(Timeline.World):
{
AudioManager.Instance.WorldSfxTracker.AddSfx(this);
AudioManager.Instance.WorldSfxTracker.AddToPlaying(this);
break;
}
case(Timeline.Player):
{
AudioManager.Instance.PlayerSfxTracker.AddSfx(this);
AudioManager.Instance.PlayerSfxTracker.AddToPlaying(this);
break;
}
}
}
public void OnReverse()
{
_source.timeSamples = _source.clip.samples - 1;
switch (_timeline)
{
case(Timeline.World):
{
AudioManager.Instance.WorldSfxTracker.AddToPlaying(this);
_source.pitch = GameManager.Instance.Player.RewindRampWorld;
break;
}
case(Timeline.Player):
{
AudioManager.Instance.PlayerSfxTracker.AddToPlaying(this);
_source.pitch = GameManager.Instance.Player.RewindRampPlayer;
break;
}
}
_sfxAction();
}
/* Basic comparison code omitted */
}
/* SoundEffectTracker - Keeps track of ReversibleSoundEffects to trigger them & set correct speeds when reversing time. */
public class SoundEffectTracker : MonoBehaviour
{
/* Boilerplate code omitted */
private List<ReversibleSoundEffect> _sfx = new List<ReversibleSoundEffect>(); //list of started SFX, ordered by start time
private List<ReversibleSoundEffect> _sfxEnds = new List<ReversibleSoundEffect>(); //list of ended SFX, ordered by end time
private List<ReversibleSoundEffect> _playingSFX = new List<ReversibleSoundEffect>(); //list of currently playing SFX
void FixedUpdate() //in FixedUpdate to match our FixedUpdate method of time tracking
{
//replaying sounds
if ((Timeline == Timeline.World && RewindManager.IsBeingRewinded) //If world rewound
|| (Timeline == Timeline.Player && GameManager.Instance.Player.PlayerRewinder.IsBeingRewinded)) //or player rewound
{
while(_sfxEnds.Count > 0) {
ReversibleSoundEffect peek = _sfxEnds[_sfxEnds.Count - 1]; //then get the most recently played sound effect
if (GameManager.Instance.Time < peek.times.Item2) //if its end time has passed, play it reversed
{
peek.OnReverse();
_sfxEnds.Remove(peek);
_playingSFX.Add(peek);
} else {
break; // the most recently ended SFX is not to play yet
}
}
}
//Check playing sound effects to update list of playing SFX
for (int i = _playingSFX.Count - 1; i >= 0; i--)
{
ReversibleSoundEffect sfx = _playingSFX[i];
if (sfx.times.Item2 < GameManager.Instance.Time) //Sound Effect is over
{
_playingSFX.RemoveAt(i);
_sfxEnds.Add(i);
continue;
}
if (sfx.times.Item1 > GameManager.Instance.Time) //Reversing, and SFX start time has passed
{
_playingSFX.RemoveAt(i);
_sfx.Remove(sfx);
continue;
}
if (RewindManager.IsBeingRewinded)
{
sfx.SetSpeed(-GameManager.Instance.Player.RewindRampWorld);
}
else
{
sfx.SetSpeed(1);
}
}
}
public void AddSfx(ReversibleSoundEffect newSfx)
{
_sfx.Add(newSfx);
}
public void AddToPlaying(ReversibleSoundEffect newSfx)
{
_playingSFX.Add(newSfx);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment