a few sound changes, occlusion different approach, test cafeteria ambience
This commit is contained in:
198
Assets/_PROJECT/Scripts/Audio/Occlusion.cs
Normal file
198
Assets/_PROJECT/Scripts/Audio/Occlusion.cs
Normal file
@@ -0,0 +1,198 @@
|
||||
using UnityEngine;
|
||||
using FMODUnity;
|
||||
using FMOD.Studio;
|
||||
|
||||
public class FirstPersonOcclusion : MonoBehaviour
|
||||
{
|
||||
[Header("FMOD Event")]
|
||||
[SerializeField]
|
||||
private FMODUnity.EventReference SelectAudio;
|
||||
private EventInstance AudioOccluded;
|
||||
private EventDescription AudioDes;
|
||||
private StudioListener Listener;
|
||||
private PLAYBACK_STATE pb;
|
||||
|
||||
[Header("Occlusion Options")]
|
||||
[SerializeField]
|
||||
[Range(0f, 10f)]
|
||||
private float SoundOcclusionWidening = 1f;
|
||||
[SerializeField]
|
||||
[Range(0f, 10f)]
|
||||
private float PlayerOcclusionWidening = 1f;
|
||||
[SerializeField]
|
||||
private LayerMask OcclusionLayer;
|
||||
|
||||
private bool AudioIsVirtual;
|
||||
private float MaxDistance;
|
||||
private float ListenerDistance;
|
||||
private float lineCastHitCount = 0f;
|
||||
private Color colour;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
Debug.Log("--- Start Method ---");
|
||||
|
||||
// 1. Event Instance Creation
|
||||
AudioOccluded = RuntimeManager.CreateInstance(SelectAudio);
|
||||
Debug.Log($"Created FMOD Event Instance for: {SelectAudio.Path}");
|
||||
|
||||
// 2. Attaching Instance
|
||||
RuntimeManager.AttachInstanceToGameObject(AudioOccluded, gameObject);
|
||||
Debug.Log($"Attached FMOD Event Instance to GameObject: {gameObject.name}");
|
||||
|
||||
// 3. Starting Audio
|
||||
AudioOccluded.start();
|
||||
Debug.Log("Started FMOD Event Instance.");
|
||||
|
||||
// 4. Releasing Instance (This allows the event to self-manage its lifetime, which is fine)
|
||||
AudioOccluded.release();
|
||||
Debug.Log("Released FMOD Event Instance.");
|
||||
|
||||
// 5. Getting Event Description and Max Distance
|
||||
AudioDes = RuntimeManager.GetEventDescription(SelectAudio);
|
||||
AudioDes.getMinMaxDistance(out float minDistance, out MaxDistance);
|
||||
Debug.Log($"FMOD Event Min/Max Distance: {minDistance:F2} / {MaxDistance:F2}");
|
||||
|
||||
// 6. Finding Listener
|
||||
Listener = FindObjectOfType<StudioListener>();
|
||||
if (Listener != null)
|
||||
{
|
||||
Debug.Log($"Found FMOD StudioListener on GameObject: {Listener.gameObject.name}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("FATAL: Could not find FMOD StudioListener in the scene!");
|
||||
}
|
||||
Debug.Log("--- End Start Method ---");
|
||||
}
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
// Debug.Log("--- FixedUpdate Method ---"); // Too frequent, only log conditions
|
||||
|
||||
AudioOccluded.isVirtual(out AudioIsVirtual);
|
||||
AudioOccluded.getPlaybackState(out pb);
|
||||
ListenerDistance = Vector3.Distance(transform.position, Listener.transform.position);
|
||||
|
||||
// 7. Check Occlusion Condition
|
||||
if (!AudioIsVirtual && pb == PLAYBACK_STATE.PLAYING && ListenerDistance <= MaxDistance)
|
||||
{
|
||||
Debug.Log($"Occlusion Check: Not Virtual, Playing, Distance {ListenerDistance:F2} <= Max {MaxDistance:F2}. Calling OccludeBetween.");
|
||||
OccludeBetween(transform.position, Listener.transform.position);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Log reasons why occlusion is NOT being checked
|
||||
if (AudioIsVirtual) Debug.Log("Occlusion Skipped: Audio is Virtual.");
|
||||
if (pb != PLAYBACK_STATE.PLAYING) Debug.Log($"Occlusion Skipped: Playback State is not PLAYING. State: {pb}");
|
||||
if (ListenerDistance > MaxDistance) Debug.Log($"Occlusion Skipped: Distance {ListenerDistance:F2} > Max Distance {MaxDistance:F2}.");
|
||||
}
|
||||
|
||||
// 8. Reset Hit Count
|
||||
// Debug.Log($"Resetting lineCastHitCount from {lineCastHitCount:F0} to 0.");
|
||||
lineCastHitCount = 0f;
|
||||
}
|
||||
|
||||
private void OccludeBetween(Vector3 sound, Vector3 listener)
|
||||
{
|
||||
Debug.Log("--- OccludeBetween Method ---");
|
||||
|
||||
// 9. Calculate Points (Log only a few to avoid clutter)
|
||||
Vector3 SoundLeft = CalculatePoint(sound, listener, SoundOcclusionWidening, true);
|
||||
Vector3 SoundRight = CalculatePoint(sound, listener, SoundOcclusionWidening, false);
|
||||
// Debug.Log($"Sound Positions: Center {sound}, Left {SoundLeft}, Right {SoundRight}");
|
||||
|
||||
Vector3 ListenerLeft = CalculatePoint(listener, sound, PlayerOcclusionWidening, true);
|
||||
Vector3 ListenerRight = CalculatePoint(listener, sound, PlayerOcclusionWidening, false);
|
||||
// Debug.Log($"Listener Positions: Center {listener}, Left {ListenerLeft}, Right {ListenerRight}");
|
||||
|
||||
Vector3 SoundAbove = new Vector3(sound.x, sound.y + SoundOcclusionWidening, sound.z);
|
||||
Vector3 SoundBelow = new Vector3(sound.x, sound.y - SoundOcclusionWidening, sound.z);
|
||||
Vector3 ListenerAbove = new Vector3(listener.x, listener.y + PlayerOcclusionWidening * 0.5f, listener.z);
|
||||
Vector3 ListenerBelow = new Vector3(listener.x, listener.y - PlayerOcclusionWidening * 0.5f, listener.z);
|
||||
|
||||
// 10. Casting Lines (The line casts themselves will log hits)
|
||||
CastLine(SoundLeft, ListenerLeft);
|
||||
CastLine(SoundLeft, listener);
|
||||
CastLine(SoundLeft, ListenerRight);
|
||||
|
||||
CastLine(sound, ListenerLeft);
|
||||
CastLine(sound, listener);
|
||||
CastLine(sound, ListenerRight);
|
||||
|
||||
CastLine(SoundRight, ListenerLeft);
|
||||
CastLine(SoundRight, listener);
|
||||
CastLine(SoundRight, ListenerRight);
|
||||
|
||||
CastLine(SoundAbove, ListenerAbove);
|
||||
CastLine(SoundBelow, ListenerBelow);
|
||||
|
||||
if (PlayerOcclusionWidening == 0f || SoundOcclusionWidening == 0f)
|
||||
{
|
||||
colour = Color.blue;
|
||||
}
|
||||
else
|
||||
{
|
||||
colour = Color.green;
|
||||
}
|
||||
|
||||
SetParameter();
|
||||
Debug.Log("--- End OccludeBetween Method ---");
|
||||
}
|
||||
|
||||
private Vector3 CalculatePoint(Vector3 a, Vector3 b, float m, bool posOrneg)
|
||||
{
|
||||
// Debug.Log($"Calculating offset point for: {a} to {b} with magnitude {m} and posOrneg {posOrneg}");
|
||||
float x;
|
||||
float z;
|
||||
// n is the 2D distance between a and b
|
||||
float n = Vector3.Distance(new Vector3(a.x, 0f, a.z), new Vector3(b.x, 0f, b.z));
|
||||
float mn = (m / n);
|
||||
|
||||
// Safety check for division by zero (if sound and listener are exactly on top of each other horizontally)
|
||||
if (n == 0f)
|
||||
{
|
||||
// If points are on the same XZ position, just return the point 'a'
|
||||
// Debug.LogWarning("CalculatePoint: Division by zero avoided. Sound and Listener are at the same XZ position.");
|
||||
return a;
|
||||
}
|
||||
|
||||
if (posOrneg)
|
||||
{
|
||||
x = a.x + (mn * (a.z - b.z));
|
||||
z = a.z - (mn * (a.x - b.x));
|
||||
}
|
||||
else
|
||||
{
|
||||
x = a.x - (mn * (a.z - b.z));
|
||||
z = a.z + (mn * (a.x - b.x));
|
||||
}
|
||||
return new Vector3(x, a.y, z);
|
||||
}
|
||||
|
||||
private void CastLine(Vector3 Start, Vector3 End)
|
||||
{
|
||||
RaycastHit hit;
|
||||
// 11. Raycast result
|
||||
bool isHit = Physics.Linecast(Start, End, out hit, OcclusionLayer);
|
||||
|
||||
if (isHit)
|
||||
{
|
||||
lineCastHitCount++;
|
||||
Debug.Log($"Linecast HIT! Hit Count: {lineCastHitCount:F0}/11. Object hit: {hit.collider.name}.");
|
||||
Debug.DrawLine(Start, End, Color.red);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.DrawLine(Start, End, colour);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetParameter()
|
||||
{
|
||||
float occlusionValue = lineCastHitCount / 11; // 11 is the total number of line casts
|
||||
// 12. Final Parameter Value
|
||||
Debug.Log($"Setting FMOD Parameter 'Occlusion' to: {occlusionValue:F2} (Hits: {lineCastHitCount:F0}/11)");
|
||||
AudioOccluded.setParameterByName("Occlusion", occlusionValue);
|
||||
}
|
||||
}
|
||||
11
Assets/_PROJECT/Scripts/Audio/Occlusion.cs.meta
Normal file
11
Assets/_PROJECT/Scripts/Audio/Occlusion.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6c6205a218222364ca440c740b7a6b8f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user