using System.Linq; using NaughtyAttributes; using UnityEngine; namespace Station46.Environments.Intro_Sphere.Scripts { public class FollowSphere : MonoBehaviour { private const int AverageLength = 3; private static readonly int FresnelPower = Shader.PropertyToID("_FresnelPower"); public float minDistance = 0.001f, speed = 200, sizeFactor = 1, brightnessFactor = 1; [SerializeField] private Transform target; [BoxGroup("Internal")] [SerializeField] private AudioSource audioSource; [BoxGroup("Internal")] [SerializeField] private Transform centerTransform; [BoxGroup("Internal")] [SerializeField] private MeshRenderer sphereRenderer; private float[] _audioSamples; private readonly float[] _samplesAverage = new float[AverageLength]; private int averageIndex; private float _initialBrightness; private Material _sphereMaterial; private Rigidbody _rigidbody; private void Awake() { var clip = audioSource.clip; _audioSamples = new float[clip.samples*clip.channels]; clip.GetData(_audioSamples, 0); _sphereMaterial = sphereRenderer.material; _initialBrightness = _sphereMaterial.GetFloat(FresnelPower); _rigidbody = GetComponent(); } private void FixedUpdate() { var position = transform.position; var followPosition = target.position; if (Vector3.Distance(position, followPosition) >= minDistance) { _rigidbody.AddForce(speed * (followPosition - position)); } } private void Update() { if (audioSource.isPlaying) { _samplesAverage[averageIndex] = Mathf.Abs(_audioSamples[audioSource.timeSamples]); averageIndex = (averageIndex + 1) % AverageLength; var average = _samplesAverage.Average(); SetCenterSize(1 + sizeFactor * average); SetSphereMaterialBrightness(_initialBrightness - brightnessFactor * average); } } private void SetCenterSize(float size) => centerTransform.localScale = new Vector3(size, size, size); private void SetSphereMaterialBrightness(float brightness) => _sphereMaterial.SetFloat(FresnelPower, brightness); } }