using System; using System.Collections.Generic; using UnityEngine; using Wwise.Wooduan.Core; using Wwise.Wooduan.Tools; namespace Wwise.Wooduan.Components { public abstract class AkSpace : AkComponent { public const int AK_INVALID_FLOOR = -99; protected List _emittersInside = new List(); internal virtual bool IsOutdoor => false; internal virtual AkSpatialAudioRoom Room => AkOutdoor.GetInstance(); internal virtual int GetFloor(Vector3 position) { return 0; } internal BoxCollider Collider { get { if (!_collider) _collider = GetComponent(); return _collider; } } private BoxCollider _collider; internal virtual void Refresh(bool active) { } protected virtual void Init() { } protected virtual void Dispose() { } internal virtual void OnEmitterEntered(AkGameObj emitter) { _emittersInside.Add(emitter); } internal virtual void OnEmitterExited(AkGameObj emitter) { _emittersInside.Remove(emitter); } internal virtual bool IsPositionWithinSpace(Vector3 position) { return GetDistanceToPosition(position) == 0f; } internal virtual AkSpace FindSpaceAtPosition(Vector3 position) { if (GetDistanceToPosition(position) == 0f) return this; return null; } private void Awake() { Init(); } protected virtual void OnEnable() { Refresh(true); } private void OnDisable() { Refresh(false); } private void OnDestroy() { Dispose(); } internal Vector3 GetClosestPointToPosition(Vector3 position) { if (!Collider) return Vector3.zero; if (!Collider.enabled) Collider.enabled = true; return Collider.ClosestPoint(position); } internal float GetDistanceToPosition(Vector3 position) { if (!isActiveAndEnabled) return 9999f; var closestPoint = GetClosestPointToPosition(position); return closestPoint == position ? 0f : Vector3.Distance(closestPoint, position); } } public abstract class AkSpatialAudioRoom : AkSpace, IAkSpatialAudioObject { public AK.Wwise.Event roomToneEvent = new AK.Wwise.Event(); public AK.Wwise.AuxBus reverbAuxBus = new AK.Wwise.AuxBus(); private uint _roomtonePlayingID; protected List _geometries = new List(); internal override AkSpatialAudioRoom Room => this; internal ulong GetID() { return AkSoundEngine.GetAkGameObjectID(gameObject); } internal void PostRoomTone() { if (!AkSoundEngine.IsInitialized() || !roomToneEvent.IsValid() || _roomtonePlayingID != 0) return; _roomtonePlayingID = AkSoundEngine.PostEventOnRoom(roomToneEvent.Id, GetID()); AudioManager.ValidateEvent(_roomtonePlayingID, roomToneEvent.Name, gameObject, AudioTriggerSource.AkRoom); } internal void StopRoomTone() { if (!AkSoundEngine.IsInitialized() || _roomtonePlayingID == 0) return; AkSoundEngine.StopPlayingID(_roomtonePlayingID); AkWooduanHelper.DebugToConsole(AudioLogVerbosity.Notification, AudioObjectType.SFX, AudioTriggerSource.AkRoom, AudioAction.StopEvent, roomToneEvent.Name, gameObject); _roomtonePlayingID = 0; } protected abstract AkRoomParams GetRoomParams(); internal virtual void RegisterPortal(AkRoomPortal portal){} internal virtual void UnregisterPortal(AkRoomPortal portal){} internal abstract AkRoomPortal FindNearestPortalOpenedToOutdoor(Vector3 position, out float distance); internal abstract AkRoomPortal FindPortalAtPosition(Vector3 position, PortalType portalType); internal void RegisterGeometry(AkSurfaceReflector geometry) { if (!_geometries.Contains(geometry)) _geometries.Add(geometry); } internal void UnregisterGeometry(AkSurfaceReflector geometry) { if (_geometries.Contains(geometry)) _geometries.Remove(geometry); } public override bool IsValid() { return roomToneEvent.IsValid() || reverbAuxBus.IsValid(); } public bool IsRegisteredInWwise { get; set; } public void RegisterInWwise() { if (AkSoundEngine.IsInitialized() && !IsRegisteredInWwise && IsValid()) IsRegisteredInWwise = AkSoundEngine.SetRoom(GetID(), GetRoomParams(), 0, name) == AKRESULT.AK_Success; } public void UnregisterInWwise() { if (AkSoundEngine.IsInitialized() && IsRegisteredInWwise && IsValid()) IsRegisteredInWwise = AkSoundEngine.RemoveRoom(GetID()) != AKRESULT.AK_Success; } } }