128 lines
5.1 KiB
C#
128 lines
5.1 KiB
C#
using UnityEngine;
|
||
|
||
public class SubmarinaRotator : MonoBehaviour
|
||
{
|
||
[Header("Настройки поворота")]
|
||
[SerializeField] private Camera targetCamera;
|
||
[SerializeField] private float rotationSpeed = 180f;
|
||
[SerializeField] private float smoothTime = 0.2f;
|
||
[SerializeField] private float maxSpeed = 0f;
|
||
[SerializeField] private float minYaw = -60f;
|
||
[SerializeField] private float maxYaw = 60f;
|
||
|
||
[Header("Настройки звука")]
|
||
[Tooltip("Источник звука (если не указан — будет добавлен/найден)")]
|
||
[SerializeField] private AudioSource audioSource;
|
||
|
||
[Tooltip("Минимальная громкость (при скорости = 0)")]
|
||
[SerializeField] private float minVolume = 0f;
|
||
[Tooltip("Максимальная громкость (при максимальной скорости)")]
|
||
[SerializeField] private float maxVolume = 0.5f;
|
||
[SerializeField] private float maxPitch = 1.2f;
|
||
[SerializeField] private float minPitch = 0.8f;
|
||
|
||
[Tooltip("Кривая громкости (1 = линейно, >1 = быстрее нарастание, <1 = медленнее)")]
|
||
[SerializeField] private float volumeCurve = 1.2f;
|
||
|
||
[Tooltip("Плавность изменения громкости (чтобы не было резких скачков)")]
|
||
[SerializeField] private float volumeSmoothTime = 0.05f;
|
||
|
||
// Приватные переменные
|
||
private float currentYaw;
|
||
private float targetYaw;
|
||
private float yawVelocity; // ← ЭТА ПЕРЕМЕННАЯ НУЖНА ДЛЯ ГРОМКОСТИ!
|
||
private float currentVolume;
|
||
private float currentPitch;
|
||
private float volumeVelocity;
|
||
private float pitchVelocity;
|
||
|
||
private void Start()
|
||
{
|
||
targetCamera = CamerasManager.VR_Camera;
|
||
currentYaw = transform.eulerAngles.y;
|
||
targetYaw = currentYaw;
|
||
|
||
// Настройка AudioSource
|
||
if (audioSource == null)
|
||
audioSource = GetComponent<AudioSource>();
|
||
|
||
if (audioSource == null)
|
||
audioSource = gameObject.AddComponent<AudioSource>();
|
||
|
||
// Настройки AudioSource для вращения
|
||
audioSource.loop = true;
|
||
audioSource.playOnAwake = false;
|
||
audioSource.spatialBlend = 1f; // 3D звук
|
||
|
||
// Запускаем звук
|
||
audioSource.Play();
|
||
}
|
||
|
||
private void LateUpdate()
|
||
{
|
||
if (targetCamera == null) return;
|
||
|
||
// === ПОВОРОТ ===
|
||
Vector3 cameraForward = targetCamera.transform.forward;
|
||
Vector3 flatCameraDirection = new Vector3(cameraForward.x, 0f, cameraForward.z).normalized;
|
||
|
||
float maxSpeedLocal = maxSpeed > 0 ? maxSpeed : rotationSpeed;
|
||
if (flatCameraDirection != Vector3.zero)
|
||
{
|
||
Quaternion targetRotation = Quaternion.LookRotation(flatCameraDirection, Vector3.up);
|
||
float rawTargetYaw = NormalizeAngle(targetRotation.eulerAngles.y);
|
||
float compensatedTargetYaw = rawTargetYaw/* * Config.sensitivity;*/;
|
||
targetYaw = Mathf.Clamp(compensatedTargetYaw, minYaw, maxYaw);
|
||
|
||
currentYaw = Mathf.SmoothDampAngle(currentYaw, targetYaw, ref yawVelocity, smoothTime, maxSpeedLocal, Time.deltaTime);
|
||
transform.rotation = Quaternion.Euler(0f, currentYaw, 0f);
|
||
}
|
||
|
||
// === ЗВУК (громкость от скорости поворота) ===
|
||
// Берём абсолютную скорость вращения (град/сек)
|
||
float speed = Mathf.Abs(yawVelocity);
|
||
|
||
// Вычисляем целевую громкость
|
||
float t = Mathf.Clamp01(speed / maxSpeedLocal);
|
||
// Применяем кривую
|
||
t = Mathf.Pow(t, volumeCurve);
|
||
float targetVolume = Mathf.Lerp(minVolume, maxVolume, t);
|
||
float targetPitch = Mathf.Lerp(minPitch, maxPitch, t);
|
||
|
||
// Плавно меняем громкость (чтобы не было резких скачков)
|
||
currentVolume = Mathf.SmoothDamp(currentVolume, targetVolume, ref volumeVelocity, volumeSmoothTime);
|
||
currentPitch = Mathf.SmoothDamp(currentPitch, targetPitch, ref pitchVelocity, volumeSmoothTime);
|
||
|
||
// Применяем громкость
|
||
if (audioSource != null)
|
||
{
|
||
audioSource.volume = currentVolume;
|
||
audioSource.pitch = currentPitch;
|
||
}
|
||
}
|
||
|
||
private float NormalizeAngle(float angle)
|
||
{
|
||
angle %= 360f;
|
||
if (angle > 180f) angle -= 360f;
|
||
if (angle < -180f) angle += 360f;
|
||
return angle;
|
||
}
|
||
|
||
// Опционально: визуализация
|
||
private void OnDrawGizmosSelected()
|
||
{
|
||
if (targetCamera == null) return;
|
||
|
||
Vector3 flatDir = targetCamera.transform.forward;
|
||
flatDir.y = 0;
|
||
if (flatDir.magnitude > 0.01f)
|
||
{
|
||
flatDir.Normalize();
|
||
Gizmos.color = Color.green;
|
||
Gizmos.DrawRay(transform.position, flatDir * 2f);
|
||
Gizmos.color = Color.yellow;
|
||
Gizmos.DrawRay(transform.position, transform.forward * 1.5f);
|
||
}
|
||
}
|
||
} |