using System.Collections; using System.Collections.Generic; using UnityEngine; public class ShipsMuved : MonoBehaviour { [Header("Floating Settings")] public float bobbingSpeed = 0.5f; public float bobbingAmount = 0.2f; public float rotationSpeedX = 10f; public float rotationAmountX = 10f; public float rotationSpeedZ = 10f; public float rotationAmountZ = 10f; [Header("Sinking Settings")] public float sinkingSpeed = 0.5f; [Tooltip("Локальные смещения для вариантов затопления")] public Vector3[] sinkEndOffsets; [Tooltip("Углы Эйлера для локального поворота при затоплении (относительно текущего)")] public Vector3[] sinkEndRotationsEuler; [Header("Shake Settings")] public float shakeDuration = 1f; public float shakeMagnitude = 0.1f; private Vector3 startLocalPosition; private Quaternion startLocalRotation; private float randomOffsetX; private float randomOffsetY; private float randomOffsetZ; private float randomRotationSpeedX; private float randomRotationSpeedZ; private bool isActive = true; private bool isSinking = false; private float sinkProgress = 0f; private Vector3 sinkStartPosition; private Quaternion sinkStartRotation; private Vector3 sinkTargetPosition; private Quaternion sinkTargetRotation; private bool isShaking = false; private float shakeTimer = 0f; public event System.Action OnSunk; void Start() { startLocalPosition = transform.localPosition; startLocalRotation = transform.localRotation; randomOffsetX = Random.Range(-1000f, 1000f); randomOffsetY = Random.Range(-1000f, 1000f); randomOffsetZ = Random.Range(-1000f, 1000f); randomRotationSpeedX = Random.Range(0.5f, 2f) * rotationSpeedX; randomRotationSpeedZ = Random.Range(0.5f, 2f) * rotationSpeedZ; } public void StopMotion() { isActive = false; } public void Sink() { isSinking = true; isActive = false; sinkProgress = 0f; sinkStartPosition = transform.localPosition; sinkStartRotation = transform.localRotation; int index = Random.Range(0, Mathf.Min(sinkEndOffsets.Length, sinkEndRotationsEuler.Length)); Vector3 scaledOffset = Vector3.Scale(sinkEndOffsets[index], transform.localScale); sinkTargetPosition = sinkStartPosition + scaledOffset; sinkTargetRotation = sinkStartRotation * Quaternion.Euler(sinkEndRotationsEuler[index]); } public void Shake() { isShaking = true; shakeTimer = shakeDuration; } void Update() { if (isSinking) if (isSinking) { sinkProgress += Time.deltaTime * sinkingSpeed; transform.localPosition = Vector3.Lerp(sinkStartPosition, sinkTargetPosition, sinkProgress); transform.localRotation = Quaternion.Lerp(sinkStartRotation, sinkTargetRotation, sinkProgress); if (sinkProgress >= 1f) { isSinking = false; OnSunk?.Invoke(); // сообщаем всем слушателям } return; } if (!isActive) return; // Основное bobbing и вращение float newY = startLocalPosition.y + Mathf.Sin((Time.time + randomOffsetY) * bobbingSpeed) * bobbingAmount; float newRotationX = Mathf.Sin((Time.time + randomOffsetX) * randomRotationSpeedX) * rotationAmountX; float newRotationZ = Mathf.Sin((Time.time + randomOffsetZ) * randomRotationSpeedZ) * rotationAmountZ; Vector3 finalPosition = new Vector3(startLocalPosition.x, newY, startLocalPosition.z); Quaternion finalRotation = startLocalRotation * Quaternion.Euler(newRotationX, 0, newRotationZ); // Shake добавляется поверх if (isShaking) { shakeTimer -= Time.deltaTime; if (shakeTimer <= 0f) { isShaking = false; } else { Vector3 shakeOffset = Random.insideUnitSphere * shakeMagnitude; shakeOffset.y = 0; // оставим bobbing по Y finalPosition += shakeOffset; } } transform.localPosition = finalPosition; transform.localRotation = finalRotation; } }