76 lines
2.8 KiB
C#
76 lines
2.8 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering;
|
|
|
|
public class AmbientSoundGenerator : MonoBehaviour {
|
|
public GameObject AmbientSfxPrefab;
|
|
public AmbientEffect[] Effects;
|
|
public float Cooldown;
|
|
|
|
[Header("Runtime values")]
|
|
public float AmbientNoiseCooldown = 0f;
|
|
public float Roll = 0f;
|
|
|
|
private Transform World;
|
|
|
|
private float[] CumulativeChances;
|
|
private float TotalCumulativeChance;
|
|
private int[] RollsSince;
|
|
|
|
private void Update() {
|
|
// Initialize in Update, since in VR, we don't actually start in the right scene,
|
|
// because the player needs to be initialized in another scene,
|
|
// because the player persists over scene loads. Go figure.
|
|
if (World == null) {
|
|
GameObject WorldObject = GameObject.FindGameObjectWithTag("World");
|
|
if (WorldObject == null) {
|
|
// Not in the game scene.
|
|
return;
|
|
}
|
|
World = WorldObject.transform;
|
|
CumulativeChances = new float[Effects.Length];
|
|
TotalCumulativeChance = 0;
|
|
for (int I = 0; I < Effects.Length; I++) {
|
|
CumulativeChances[I] = TotalCumulativeChance;
|
|
TotalCumulativeChance += Effects[I].Chance;
|
|
}
|
|
RollsSince = new int[Effects.Length];
|
|
}
|
|
|
|
AmbientNoiseCooldown -= Time.deltaTime;
|
|
if (AmbientNoiseCooldown <= 0) {
|
|
AmbientNoiseCooldown += Cooldown;
|
|
|
|
Roll = Random.Range(0, TotalCumulativeChance);
|
|
AmbientEffect Effect = null;
|
|
for (int I = CumulativeChances.Length - 1; I >= 0; I--) {
|
|
if (Roll >= CumulativeChances[I]) {
|
|
if (Effects[I].RollsSinceLast <= RollsSince[I]) {
|
|
Effect = Effects[I];
|
|
RollsSince[I] = -1;
|
|
} else {
|
|
Effect = Effects[0];
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (int I = 0; I < RollsSince.Length; I++) {
|
|
RollsSince[I]++;
|
|
}
|
|
|
|
float Distance = Random.Range(Effect.MinDistance, Effect.MaxDistance);
|
|
float Rads = Random.Range(0, 2 * Mathf.PI);
|
|
Vector3 Offset = new Vector3(Mathf.Cos(Rads) * Distance, Random.Range(Effect.MinY, Effect.MaxY), Mathf.Sin(Rads) * Distance);
|
|
GameObject Obj = Instantiate(AmbientSfxPrefab, transform.position + Offset, new Quaternion(), World);
|
|
AudioSource Sfx = Obj.GetComponent<AudioSource>();
|
|
if (Sfx != null && Effect.Clips.Length > 0) {
|
|
Sfx.clip = Effect.Clips[Random.Range(0, Effect.Clips.Length)];
|
|
Sfx.volume = Mathf.Sqrt(Random.Range(0.3f, 1f));
|
|
Sfx.Play();
|
|
}
|
|
}
|
|
}
|
|
}
|