Advertisement
Guest User

Untitled

a guest
Jul 22nd, 2022
33
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.83 KB | None | 0 0
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEngine;
  5.  
  6. public class EcholocationBeeper : MonoBehaviour
  7. {
  8.     [SerializeField] private float speed = 10f;
  9.     [SerializeField] private float minDistance = 5f;
  10.  
  11.     [SerializeField] private AudioClip sound;
  12.     [SerializeField] private LayerMask wallLayer;
  13.  
  14.     [SerializeField] private AudioClip[] sounds;
  15.  
  16.     private Vector3[] directions = new[]
  17.     {
  18.         Vector3.forward,
  19.         Vector3.back,
  20.         Vector3.left,
  21.         Vector3.right
  22.     };
  23.  
  24.     private Dictionary<Vector3, float> cooldowns = new();
  25.     private Dictionary<Vector3, AudioSource> sources = new();
  26.     private Dictionary<Vector3, IEnumerator> coroutines = new();
  27.  
  28.     private void Awake()
  29.     {
  30.         Transform holder = new GameObject("Echolocation Audio Sources").transform;
  31.  
  32.         for (int i = 0; i < directions.Length; i++)
  33.         {
  34.             GameObject go = new($"Echo [{directions[i]}]");
  35.             var audio = go.AddComponent<AudioSource>();
  36.             audio.clip = sounds[i];
  37.             audio.spatialBlend = 1f;
  38.             audio.panStereo = directions[i].x;
  39.             audio.transform.parent = holder;
  40.             sources[directions[i]] = audio;
  41.  
  42.             cooldowns[directions[i]] = 0f;
  43.             coroutines[directions[i]] = null;
  44.         }
  45.     }
  46.  
  47.     private void Update()
  48.     {
  49.         void Raycast(Vector3 direction)
  50.         {
  51.             if (Physics.Raycast(transform.position, transform.rotation * direction, out var hit, 100f, wallLayer))
  52.             {
  53.                 float distance = Vector3.Distance(transform.position, hit.point);
  54.                 float travelTime = distance / speed;
  55.  
  56.                 if (distance > minDistance && (cooldowns[direction] == 0f || travelTime < cooldowns[direction]))
  57.                 {
  58.                     cooldowns[direction] = travelTime;
  59.                     if (coroutines[direction] != null)
  60.                     {
  61.                         StopCoroutine(coroutines[direction]);
  62.                     }
  63.  
  64.                     coroutines[direction] = PlaySoundCoroutine(direction, hit.point, distance);
  65.                     StartCoroutine(coroutines[direction]);
  66.                 }
  67.             }
  68.         }
  69.  
  70.         cooldowns.Keys.ToList().ForEach(dir => Raycast(dir));
  71.     }
  72.  
  73.     private IEnumerator PlaySoundCoroutine(Vector3 key, Vector3 position, float distance)
  74.     {
  75.         while (cooldowns[key] > 0)
  76.         {
  77.             cooldowns[key] -= Time.deltaTime;
  78.             yield return null;
  79.         }
  80.  
  81.         while (sources[key].isPlaying)
  82.         {
  83.             yield return null;
  84.         }
  85.  
  86.         cooldowns[key] = 0;
  87.         sources[key].volume = Mathf.InverseLerp(0f, 10f, distance);
  88.         sources[key].transform.position = position;
  89.         sources[key].Play();
  90.     }
  91. }
  92.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement