Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Assets/1.TeamWorkspace/Module1/Editor.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 30 additions & 0 deletions Assets/1.TeamWorkspace/Module1/Editor/Module1AudioImport.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System.IO;
using UnityEditor;
using UnityEngine;

/// <summary>
/// Import settings for Module 1's sounds in Team Assets/Sound/Module1, so they survive a reimport.
/// The long ambience streams; the other loops stay compressed in memory; one-shots decompress on load
/// so they start without a hitch. Everything is preloaded with the scene.
/// </summary>
public class Module1AudioImport : AssetPostprocessor
{
const string Folder = "Assets/1.TeamWorkspace/Team Assets/Sound/Module1/";

void OnPreprocessAudio()
{
if (!assetPath.StartsWith(Folder)) return;
var importer = (AudioImporter)assetImporter;
string name = Path.GetFileNameWithoutExtension(assetPath);
bool ambience = name.StartsWith("m1_amb_");
bool loop = ambience || name.Contains("dragonfly") || name.Contains("sip_") || name.Contains("drink_") || name.Contains("heartbeat");

var s = importer.defaultSampleSettings;
s.loadType = ambience ? AudioClipLoadType.Streaming : loop ? AudioClipLoadType.CompressedInMemory : AudioClipLoadType.DecompressOnLoad;
s.compressionFormat = AudioCompressionFormat.Vorbis;
s.quality = 0.6f;
s.preloadAudioData = true;
importer.defaultSampleSettings = s;
importer.loadInBackground = ambience;
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 29 additions & 14 deletions Assets/1.TeamWorkspace/Module1/GameSystem/StereoSoundListener.cs
Original file line number Diff line number Diff line change
@@ -1,29 +1,44 @@
using System.Collections.Generic;
using UnityEngine;

// Hand-made stereo for the 2D sounds out in the world (the cars): louder the closer the mosquito is,
// panned to the side they are on. The player's own sounds (wing buzz on the camera, rain on the rig)
// are left alone.
public class StereoSoundListener : MonoBehaviour
{
public AudioSource[] Source;
public float HearimgDistance;

// Each source's volume as authored: how loud it is right next to the player.
private readonly Dictionary<AudioSource, float> _fullVolume = new Dictionary<AudioSource, float>();

private void Start()
{
Source = FindObjectsOfType<AudioSource>();
var world = new List<AudioSource>();
foreach (AudioSource source in FindObjectsByType<AudioSource>(FindObjectsInactive.Include, FindObjectsSortMode.None))
{
if (source.transform.IsChildOf(transform.root)) continue;
// 3D sources (frogs, dragonflies) are placed by Unity itself.
if (source.spatialBlend > 0f) continue;
world.Add(source);
_fullVolume[source] = source.volume;
}
Source = world.ToArray();
}

// Distance only sets the volume. Switching a source off out of range restarted a one-shot clip
// every time the player came back, left it silent once it had played through, and fought
// MovingCar, which switches a car's sound off while the car waits between passes.
private void Update()
{
foreach (AudioSource source in Source)
{
float dis = Vector3.Distance(transform.position, source.transform.position);
if (dis < HearimgDistance)
{
source.enabled = true;
source.volume = Mathf.InverseLerp(HearimgDistance, 0, dis);
float dir = Vector3.Dot(transform.right, (source.transform.position - transform.position).normalized);
source.panStereo = dir *= -1;
}
else if (dis >= HearimgDistance)
{
source.enabled = false;
}
if (source == null) continue;
Vector3 toSource = source.transform.position - transform.position;
float dis = toSource.magnitude;
source.volume = _fullVolume[source] * Mathf.InverseLerp(HearimgDistance, 0, dis);
// panStereo +1 is the right ear. This used to be negated, swapping left and right.
if (dis > 0.001f) source.panStereo = Vector3.Dot(transform.right, toSource / dis);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using UnityEngine;

/// <summary>
/// A dragonfly's wing drone, louder and faster while it is chasing the player, so the threat can be
/// heard closing in. <see cref="Module1Sounds"/> adds it to every roaming dragonfly.
/// </summary>
public class DragonflyWings : MonoBehaviour
{
AudioSource source;
DengerSource hunter;
float idleVolume, huntVolume, huntPitch;

public void Init(Module1SoundBank bank)
{
hunter = GetComponent<DengerSource>();
idleVolume = bank.DragonflyVolume;
huntVolume = bank.DragonflyHuntVolume;
huntPitch = bank.DragonflyHuntPitch;
source = Module1Sounds.Make3D(gameObject, bank.MaxDistance);
source.clip = bank.DragonflyWings;
source.loop = true;
source.volume = idleVolume;
if (source.clip == null) return;
// Each dragonfly starts at a different point in the recording so three of them do not phase.
source.time = Random.Range(0f, source.clip.length);
source.Play();
}

void Update()
{
if (source == null) return;
bool hunting = hunter != null && hunter.inRange;
source.volume = Mathf.MoveTowards(source.volume, hunting ? huntVolume : idleVolume, Time.deltaTime);
source.pitch = Mathf.MoveTowards(source.pitch, hunting ? huntPitch : 1f, Time.deltaTime);
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 41 additions & 0 deletions Assets/1.TeamWorkspace/Module1/Module1_Main/Script/FrogCroaks.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System.Collections;
using UnityEngine;

/// <summary>
/// A frog croaking now and then, in short bouts of one to three croaks, so the player hears where the
/// frogs (predators) are before seeing them. <see cref="Module1Sounds"/> adds it to every frog.
/// </summary>
public class FrogCroaks : MonoBehaviour
{
public AudioClip[] Clips;
public float Volume = 0.35f;
public Vector2 Interval = new Vector2(3f, 9f);

AudioSource source;

public void Init(Module1SoundBank bank)
{
Clips = bank.FrogCroaks;
Volume = bank.FrogVolume;
Interval = bank.FrogInterval;
source = Module1Sounds.Make3D(gameObject, bank.MaxDistance);
}

IEnumerator Start()
{
if (source == null || Clips == null || Clips.Length == 0) yield break;
// Out of step with the other frogs from the first croak.
yield return new WaitForSeconds(Random.Range(0f, Interval.y));
while (true)
{
int croaks = Random.Range(1, 4);
for (int i = 0; i < croaks; i++)
{
source.pitch = Random.Range(0.9f, 1.1f);
source.PlayOneShot(Clips[Random.Range(0, Clips.Length)], Volume);
yield return new WaitForSeconds(Random.Range(0.35f, 0.6f));
}
yield return new WaitForSeconds(Random.Range(Interval.x, Interval.y));
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions Assets/1.TeamWorkspace/Module1/Module1_Main/Script/GameManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,16 @@ public class GameManager : MonoBehaviour
public GameObject[] Human;
public WaterContainer[] waterContainers;
public bool IsRain;
/// <summary>True once the whole clutch is laid: the run is won and ends there (see <see cref="Victory"/>).</summary>
public bool Won;
private void Awake()
{
instance = this;
waterContainers = FindObjectsOfType<WaterContainer>();
// The in-headset HUD (Module 2 style) is built from code; it hides and mirrors the scene's PlayerUI.
if (GetComponent<Module1HUD>() == null) gameObject.AddComponent<Module1HUD>();
// Ambience, creatures and feedback sounds are added from code too (clips in Resources/Module1/Module1SoundBank).
if (GetComponent<Module1Sounds>() == null) gameObject.AddComponent<Module1Sounds>();
}

private void Start()
Expand Down Expand Up @@ -121,6 +125,26 @@ public void TimeOut()
DrinkNectarUI.text = DrinkNectarScore.ToString();
Invoke("RestartAble", 1);
}

/// <summary>
/// The player completed the life cycle and laid the full clutch. Called by QuestSystem when the
/// egg quest latches, so the run ends there instead of leaving the player to fly around until the
/// clock runs out. Shows the time-out score card (Module1HUD swaps in a win title) and, like a
/// time-out, the next button press goes back to the start menu rather than into a new life.
/// </summary>
public void Victory()
{
if (Won || player.Death || player.RestartAble) return;
Won = true;
CancelInvoke("Settime");
if (SaveManager.instance != null && SaveManager.instance.a != null)
{
// PlayerMain's restart sends a saved time of 0 to the menu.
SaveManager.instance.a.time = 0;
SaveManager.SavePlayerData(SaveManager.instance.a);
}
TimeOut();
}
public void RestartAble()
{
player.RestartAble = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ public class Module1HUD : MonoBehaviour

// The blood warning was only ever a picture with the sentence painted in (Warning2 UI.png).
const string BloodWarningText = "ຕ້ອງການໂປຣຕີນ (ເລືອດ) ດ່ວນ!";
// The win (GameManager.Won) had no screen in the scene: "mission complete", built on the quest
// card's own title ພາລະກິດ. It replaces the time-out title on the same score card.
const string WinTitle = "ພາລະກິດສຳເລັດ!";
// Fallbacks, used only if the scene object they normally come from is missing.
const string EnergyWord = "ພະລັງງານ"; // from PlayerMain.DeathMessage "ພະລັງງານໝົດ"
const string BloodWord = "ເລືອດ"; // from the quest "ດື່ມເລືອດ"
Expand Down Expand Up @@ -321,6 +324,9 @@ void UpdateEnd(bool dead, bool timedOut)
}
if (showTimeOut)
{
string title = gm.Won ? WinTitle : timeOutTitle ?? "";
if (timeOutTitleText.text != title) timeOutTitleText.text = title;
timeOutTitleText.color = gm.Won ? doneColor : warnColor;
timeOutValuesText.text = gm.score + "\n" + gm.DrinkNectarScore + "\n" + gm.MatingScore + "\n" + gm.DrinkBloodScore + "\n" + gm.LayEggScore;
}
Fade(deathGroup, showDeath);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using UnityEngine;

/// <summary>
/// Every Module 1 sound that <see cref="Module1Sounds"/> plays, with its volume, in one place so the mix
/// can be balanced without touching the scene. The team's original three sounds (wing buzz, cars) stay
/// where they were; the rain clip is taken over from the scene so it can fade.
///
/// All clips are CC0 from Freesound - see Team Assets/Sound/Module1/CREDITS.md.
/// Lives at Resources/Module1/Module1SoundBank.
/// </summary>
[CreateAssetMenu(menuName = "AEDES/Module 1 Sound Bank", fileName = "Module1SoundBank")]
public class Module1SoundBank : ScriptableObject
{
[Header("Atmosphere (2D, on the player)")]
public AudioClip Ambience;
[Range(0f, 1f)] public float AmbienceVolume = 0.4f;
[Tooltip("Ambience level while it rains, as a fraction of AmbienceVolume: the birds go quiet.")]
[Range(0f, 1f)] public float AmbienceDuringRain = 0.5f;
[Range(0f, 1f)] public float RainVolume = 0.15f;
[Tooltip("Seconds the rain takes to fade in or out.")]
public float RainFade = 2.5f;

[Header("Creatures (3D, fade to silence at MaxDistance like the cars)")]
public float MaxDistance = 20f;
public AudioClip[] FrogCroaks;
[Range(0f, 1f)] public float FrogVolume = 0.35f;
[Tooltip("Seconds between a frog's bouts of croaking.")]
public Vector2 FrogInterval = new Vector2(3f, 9f);
public AudioClip DragonflyWings;
[Range(0f, 1f)] public float DragonflyVolume = 0.6f;
[Tooltip("Wing volume while the dragonfly is chasing the player.")]
[Range(0f, 1f)] public float DragonflyHuntVolume = 1f;
[Tooltip("Wing pitch while chasing: faster beats.")]
public float DragonflyHuntPitch = 1.25f;

[Header("Feedback (2D, on the player)")]
public AudioClip SipNectar;
[Range(0f, 1f)] public float SipNectarVolume = 0.16f;
public AudioClip DrinkBlood;
[Range(0f, 1f)] public float DrinkBloodVolume = 0.35f;
public AudioClip BloodFull;
[Range(0f, 1f)] public float BloodFullVolume = 0.5f;
public AudioClip Mate;
[Range(0f, 1f)] public float MateVolume = 0.32f;
public AudioClip LayEgg;
[Range(0f, 1f)] public float LayEggVolume = 0.6f;
public AudioClip Danger;
[Range(0f, 1f)] public float DangerVolume = 0.25f;
[Tooltip("Eaten or run over. Not played when the mosquito starves.")]
public AudioClip DeathHit;
[Range(0f, 1f)] public float DeathHitVolume = 0.5f;
public AudioClip DeathSting;
[Range(0f, 1f)] public float DeathStingVolume = 0.32f;
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading