Beispiel #1
0
 void DrawDebugPath()
 {
     if (_los)
     {
         Debug.DrawLine(_sourceTransform.position, _listenerTransform.position, Color.red);
     }
     else
     {
         Color lineColor = Color.red;
         if (_nearestNodeToListener != null)
         {
             Debug.DrawLine(_listenerTransform.position, _nearestNodeToListener.position, lineColor);
         }
         Node currentNode = _nearestNodeToListener;
         while (currentNode != null && _transientNodes.ContainsKey(currentNode))
         {
             TransientNode tNode      = _transientNodes[currentNode];
             Node          parentNode = tNode.parent;
             if (parentNode != null)
             {
                 Debug.DrawLine(currentNode.position, parentNode.position, lineColor);
             }
             else
             {
                 Debug.DrawLine(currentNode.position, _sourceTransform.position, lineColor);
             }
             currentNode = parentNode;
         }
     }
 }
Beispiel #2
0
        void UpdateAudioSettings()
        {
            // Find nearest node to listener.
            _nearestNodeToListener = NearestNodeInLOS(_listenerTransform.position);
            if (_nearestNodeToListener == null)
            {
                Debug.Log("[Propagate] No PropagateNodes in line of sight of listener.");
                _nearestNodeToListener = NearestNode(_listenerTransform.position);
                if (_nearestNodeToListener == null)
                {
                    Debug.LogError("[Propagate] No PropagateNodes near listener. Falling back to standard audio source.");
                    audioSource.volume = 1.0f;
                    this.enabled       = false;
                    return;
                }
            }

            // Find the last visible node along the path.
            Node currentNode = _nearestNodeToListener;

            while (currentNode != null && _transientNodes.ContainsKey(currentNode))
            {
                TransientNode tNode = _transientNodes[currentNode];
                if (tNode.parent != null)
                {
                    if (CheckLOSToNode(tNode.parent, _listenerTransform.position))
                    {
                        _nearestNodeToListener = tNode.parent;
                    }
                    else
                    {
                        break;
                    }
                }
                currentNode = tNode.parent;
            }

            if (drawDebugPath)
            {
                //Debug.DrawLine(_listenerTransform.position, _nearestNodeToListener.position, Color.red);
            }

            TransientNode nearestTNodeToListener;
            bool          didGetNearestNode = _transientNodes.TryGetValue(_nearestNodeToListener, out nearestTNodeToListener);

            if (!didGetNearestNode)
            {
                Debug.LogError("[Propagate] No node near to listener.");
            }

            // Add the distance from last node to listener.
            float nodeListenerDist = Vector3.Distance(_nearestNodeToListener.position, _listenerTransform.position);
            float totalDistance    = nearestTNodeToListener.distanceToSource + nodeListenerDist;

            // Move the audio source.
            _perceivedPosition = Vector3.Lerp(_sourceTransform.position, _nearestNodeToListener.position, profile.percievedPositionEffect);
            Vector3 listenerNodeDirection = (_perceivedPosition - _listenerTransform.position).normalized;

            _perceivedPosition = _listenerTransform.position + (listenerNodeDirection * totalDistance);

            // Calculate the lowpass.
            float maxAngle            = profile.frequencySettings.maxAngle;
            float normalizedAngle     = RemapFloat(nearestTNodeToListener.curvatureToSource * Mathf.Rad2Deg, 0f, maxAngle, 0f, 1f);
            float normalizedFrequency = profile.frequencySettings.curve.Evaluate(normalizedAngle);

            _cutoffFrequency = RemapFloat(normalizedFrequency,
                                          0f, 1f,
                                          profile.frequencySettings.minCutoff,
                                          profile.frequencySettings.maxCutoff);


            // Calculate volume reduction due to blocked LOS.
            _volume = 1.0f;
            RaycastHit hitInfo;

            if (Physics.Linecast(_listenerTransform.position, _nearestNodeToListener.position, out hitInfo) && !hitInfo.collider.CompareTag("Player"))
            {
                AudioOccluder occluder = hitInfo.collider.GetComponent <AudioOccluder>();
                if (occluder != null)
                {
                    _volume          *= 1f - occluder.volumeReduction;
                    _cutoffFrequency *= 1f - occluder.frequencyReduction;
                }
                else
                {
                    _volume          *= 1f - profile.occlusionSettings.volumeReduction;
                    _cutoffFrequency *= 1f - profile.occlusionSettings.frequencyReduction;
                }
            }

            currentNode = _nearestNodeToListener;
            while (currentNode != null && _transientNodes.ContainsKey(currentNode))
            {
                TransientNode tNode = _transientNodes[currentNode];
                if (tNode.parent != null && Physics.Linecast(currentNode.position, tNode.parent.position, out hitInfo))
                {
                    AudioOccluder occluder = hitInfo.collider.GetComponent <AudioOccluder>();
                    if (occluder != null)
                    {
                        _volume          *= 1f - occluder.volumeReduction;
                        _cutoffFrequency *= 1f - occluder.frequencyReduction;
                    }
                    else
                    {
                        _volume          *= 1f - profile.occlusionSettings.volumeReduction;
                        _cutoffFrequency *= 1f - profile.occlusionSettings.frequencyReduction;
                    }
                }
                currentNode = tNode.parent;
            }
        }
Beispiel #3
0
        void Propagate()
        {
            _transientNodes.Clear();
            var openNodes = new List <Node>();

            // Find nearest node.
            Node nearestNode = NearestNodeInLOS(_sourceTransform.position);

            if (nearestNode == null)
            {
                Debug.LogError("[Propagate] Could not find PropagateNode in line of sight to audio source. Falling back to standard Audio Source.");
                audioSource.volume = 1.0f;
                this.enabled       = false;
                return;
            }

            Node currentNode = nearestNode;

            _transientNodes[currentNode] = new TransientNode()
            {
                parent = null
            };

            while (currentNode != null)
            {
                TransientNode tNode = _transientNodes[currentNode];
                if (tNode.parent != null)
                {
                    TransientNode parentTNode = _transientNodes[tNode.parent];
                    tNode.distanceToSource  = parentTNode.distanceToSource + Vector3.Distance(tNode.parent.position, currentNode.position);
                    tNode.direction         = Quaternion.Euler((currentNode.position - tNode.parent.position).normalized);
                    tNode.curvatureToSource = parentTNode.curvatureToSource + Quaternion.Angle(parentTNode.direction, tNode.direction);
                }
                else
                {
                    tNode.distanceToSource  = Vector3.Distance(currentNode.position, _sourceTransform.position);
                    tNode.curvatureToSource = 0;
                    tNode.direction         = Quaternion.identity;
                    tNode.parent            = null;
                }
                _transientNodes[currentNode] = tNode;

                foreach (var connectedNode in currentNode.connections)
                {
                    if (!_transientNodes.ContainsKey(connectedNode) && !openNodes.Contains(connectedNode))
                    {
                        openNodes.Add(connectedNode);
                        _transientNodes[connectedNode] = new TransientNode()
                        {
                            parent = currentNode
                        };
                    }
                }

                if (openNodes.Count > 0)
                {
                    currentNode = openNodes[0];
                    openNodes.RemoveAt(0);
                }
                else
                {
                    currentNode = null;
                }
            }
        }