using System.Collections.Generic; using DarkTonic.MasterAudio; using UnityEngine; public class TransformFollower : MonoBehaviour { [Tooltip("This is for diagnostic purposes only. Do not change or assign this field.")] public Transform RuntimeFollowingTransform; private GameObject _goToFollow; private Transform _trans; private GameObject _go; private SphereCollider _collider; private string _soundType; private string _variationName; private bool _willFollowSource; private bool _isInsideTrigger; private bool _hasPlayedSound; private float _playVolume; private bool _positionAtClosestColliderPoint; private MasterAudio.AmbientSoundExitMode _exitMode; private float _exitFadeTime; private MasterAudio.AmbientSoundReEnterMode _reEnterMode; private float _reEnterFadeTime; private readonly List _actorColliders = new List(); private Vector3 _lastListenerPos = new Vector3(float.MinValue, float.MinValue, float.MinValue); private readonly Dictionary _lastPositionByCollider = new Dictionary(); private PlaySoundResult playingVariation; private PlaySoundResult fadingVariation; public SphereCollider Trigger { get { if (_collider != null) { return _collider; } _collider = GameObj.AddComponent(); _collider.isTrigger = true; return _collider; } } public GameObject GameObj { get { if (_go != null) { return _go; } _go = base.gameObject; return _go; } } public Transform Trans { get { if (_trans == null) { _trans = base.transform; } return _trans; } } private void Awake() { if (!(Trigger == null)) { _ = _actorColliders.Count; } if (!(_lastListenerPos == Vector3.zero) && playingVariation == null) { _ = _positionAtClosestColliderPoint; } } private void OnDisable() { AmbientUtil.RemoveTransformFollower(this); PerformTriggerExit(); } public void UpdateAudioVariation(SoundGroupVariation newVariation) { playingVariation.ActingVariation = newVariation; } public void StartFollowing(Transform transToFollow, string soundType, string variationName, float volume, float trigRadius, bool willFollowSource, bool positionAtClosestColliderPoint, bool useTopCollider, bool useChildColliders, MasterAudio.AmbientSoundExitMode exitMode, float exitFadeTime, MasterAudio.AmbientSoundReEnterMode reEnterMode, float reEnterFadeTime) { RuntimeFollowingTransform = transToFollow; _goToFollow = transToFollow.gameObject; Trigger.radius = trigRadius; _soundType = soundType; _variationName = variationName; _playVolume = volume; _willFollowSource = willFollowSource; _exitMode = exitMode; _exitFadeTime = exitFadeTime; _reEnterMode = reEnterMode; _reEnterFadeTime = reEnterFadeTime; _lastPositionByCollider.Clear(); if (useTopCollider) { Collider component = transToFollow.GetComponent(); if (component != null) { _actorColliders.Add(component); _lastPositionByCollider.Add(component, transToFollow.position); } } if (useChildColliders && transToFollow != null) { for (int i = 0; i < transToFollow.childCount; i++) { Collider component2 = transToFollow.GetChild(i).GetComponent(); if (component2 != null) { _actorColliders.Add(component2); _lastPositionByCollider.Add(component2, transToFollow.position); } } } _lastListenerPos = MasterAudio.ListenerTrans.position; int num = 0; if (_actorColliders.Count == 0 && num == 0 && positionAtClosestColliderPoint) { Debug.Log("Can't follow collider of '" + transToFollow.name + "' because it doesn't have any colliders."); return; } _positionAtClosestColliderPoint = positionAtClosestColliderPoint; if (_positionAtClosestColliderPoint) { RecalcClosestColliderPosition(forceRecalc: true); MasterAudio.QueueTransformFollowerForColliderPositionRecalc(this); } } private void StopFollowing() { RuntimeFollowingTransform = null; Object.Destroy(GameObj); } private void PlaySound() { bool flag = !string.IsNullOrEmpty(_variationName); bool flag2 = _positionAtClosestColliderPoint || _exitMode == MasterAudio.AmbientSoundExitMode.FadeSound; bool flag3 = _willFollowSource && !_positionAtClosestColliderPoint; if (fadingVariation != null && fadingVariation.ActingVariation != null) { MasterAudio.AmbientSoundReEnterMode ambientSoundReEnterMode = _reEnterMode; if (!fadingVariation.ActingVariation.IsPlaying) { ambientSoundReEnterMode = MasterAudio.AmbientSoundReEnterMode.StopExistingSound; } switch (ambientSoundReEnterMode) { case MasterAudio.AmbientSoundReEnterMode.FadeInSameSound: fadingVariation.ActingVariation.FadeToVolume(_playVolume, _reEnterFadeTime); playingVariation = fadingVariation; fadingVariation = null; _hasPlayedSound = true; return; case MasterAudio.AmbientSoundReEnterMode.StopExistingSound: fadingVariation.ActingVariation.Stop(); break; } } if (flag3) { if (flag2) { if (flag) { playingVariation = MasterAudio.PlaySound3DFollowTransform(_soundType, RuntimeFollowingTransform, _playVolume, 1f, 0f, _variationName); } else { playingVariation = MasterAudio.PlaySound3DFollowTransform(_soundType, RuntimeFollowingTransform, _playVolume); } } else if (flag) { MasterAudio.PlaySound3DFollowTransformAndForget(_soundType, RuntimeFollowingTransform, _playVolume, 1f, 0f, _variationName); } else { MasterAudio.PlaySound3DFollowTransformAndForget(_soundType, RuntimeFollowingTransform, _playVolume); } } else if (flag2) { if (flag) { playingVariation = MasterAudio.PlaySound3DAtTransform(_soundType, RuntimeFollowingTransform, _playVolume, 1f, 0f, _variationName); } else { playingVariation = MasterAudio.PlaySound3DAtTransform(_soundType, RuntimeFollowingTransform, _playVolume); } } else if (flag) { MasterAudio.PlaySound3DAtTransformAndForget(_soundType, RuntimeFollowingTransform, _playVolume, 1f, 0f, _variationName); } else { MasterAudio.PlaySound3DAtTransformAndForget(_soundType, RuntimeFollowingTransform, _playVolume); } fadingVariation = null; _hasPlayedSound = true; } public void ManualUpdate() { if (RuntimeFollowingTransform == null || !DTMonoHelper.IsActive(_goToFollow)) { StopFollowing(); return; } if (!_positionAtClosestColliderPoint) { Trans.position = RuntimeFollowingTransform.position; } if (_isInsideTrigger && !_hasPlayedSound) { PlaySound(); } } public bool RecalcClosestColliderPosition(bool forceRecalc = false) { Vector3 position = MasterAudio.ListenerTrans.position; bool flag = _lastListenerPos != position; Vector3 vector = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue); bool flag2 = false; int count = _actorColliders.Count; int num = 0; if (count > 0) { float num2 = float.MaxValue; if (count == 1) { Collider collider = _actorColliders[0]; if (collider == null) { return false; } Vector3 position2 = collider.transform.position; if (!forceRecalc && _lastPositionByCollider[collider] == position2 && !flag) { return false; } flag2 = true; vector = collider.ClosestPoint(position); _lastPositionByCollider[collider] = position2; } else { for (int i = 0; i < _actorColliders.Count; i++) { Collider collider2 = _actorColliders[i]; Vector3 position3 = collider2.transform.position; if (forceRecalc || !(_lastPositionByCollider[collider2] == position3) || flag) { flag2 = true; Vector3 vector2 = collider2.ClosestPoint(position); float sqrMagnitude = (position - vector2).sqrMagnitude; if (sqrMagnitude < num2) { vector = vector2; num2 = sqrMagnitude; } _lastPositionByCollider[collider2] = position3; } } } } else if (num <= 0) { return false; } if (!flag2) { return false; } Trans.position = vector; Trans.LookAt(MasterAudio.ListenerTrans); if (playingVariation != null && playingVariation.ActingVariation != null) { playingVariation.ActingVariation.MoveToAmbientColliderPosition(vector, this); } _lastListenerPos = position; return true; } private void OnTriggerEnter(Collider other) { if (!(RuntimeFollowingTransform == null) && !(other == null) && !(base.name == "~ListenerFollower~") && !(other.name != "~ListenerFollower~")) { _isInsideTrigger = true; PlaySound(); } } private void OnTriggerExit(Collider other) { if (!(RuntimeFollowingTransform == null) && !(other == null) && !(other.name != "~ListenerFollower~")) { PerformTriggerExit(); } } private void PerformTriggerExit() { _isInsideTrigger = false; _hasPlayedSound = false; if (!(MasterAudio.GrabGroup(_soundType, logIfMissing: false) == null)) { switch (_exitMode) { case MasterAudio.AmbientSoundExitMode.StopSound: MasterAudio.StopSoundGroupOfTransform(RuntimeFollowingTransform, _soundType); break; case MasterAudio.AmbientSoundExitMode.FadeSound: MasterAudio.FadeOutSoundGroupOfTransform(RuntimeFollowingTransform, _soundType, _exitFadeTime); break; } fadingVariation = playingVariation; playingVariation = null; } } }