using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
public class WaterSystem : UdonSharpBehaviour
{
[Header("--- Настройки синевы ---")]
[SerializeField] private float offset = -0.4f; // Смещение синего экрана (глаза)
[Header("--- Настройки плавания ---")]
[SerializeField] private float swimSpeed = 2.5f; // Скорость всплытия вверх
[SerializeField] private float shouldersOffset = 0.22f; // Высота плеч аватара
private VRCPlayerApi localPlayer;
private bool inWater = false;
void Start()
{
// Инициализируем локального игрока при старте
localPlayer = Networking.LocalPlayer;
}
public override void OnPlayerTriggerEnter(VRCPlayerApi player)
{
if (player != null && player.isLocal)
{
inWater = true;
// Твоя оригинальная физика невесомости
player.SetGravityStrength(0.01f);
player.SetWalkSpeed(2f); // Замедление ходьбы в воде
player.SetRunSpeed(2.5f); // Замедление бега в воде
}
}
public override void OnPlayerTriggerExit(VRCPlayerApi player)
{
if (player != null && player.isLocal)
{
inWater = false;
// Отключаем туман и сбрасываем плотность в 0 для суши
RenderSettings.fog = false;
RenderSettings.fogDensity = 0f;
// Возвращаем стандартные настройки для суши
player.SetGravityStrength(1.0f);
player.SetWalkSpeed(4f);
player.SetRunSpeed(4f);
}
}
void Update()
{
if (inWater && localPlayer != null)
{
// Берем высоту глаз конкретного аватара в реальном времени
float headY = localPlayer.GetTrackingData(VRCPlayerApi.TrackingDataType.Head).position.y;
// Твой оригинальный расчет уровня воды по позиции объекта
float triggerTopY = transform.position.y + offset;
// Расчет высоты плеч аватара
float shouldersY = headY - shouldersOffset;
// 1. Проверка синего экрана (по глазам) с плотностью на 1.0
if (headY < triggerTopY)
{
RenderSettings.fog = true;
RenderSettings.fogDensity = 1.0f; // Выставляем плотность на однёрку
}
else
{
RenderSettings.fog = false;
RenderSettings.fogDensity = 0f; // Убираем густоту над водой
}
// 2. Плавание вверх при зажатии кнопок
bool isJumping = Input.GetButton("Jump"); // Работает на ПК (Пробел)
// Фикс для телефонов: проверяем направление взгляда и движение вперед
Vector3 lookDir = localPlayer.GetTrackingData(VRCPlayerApi.TrackingDataType.Head).rotation * Vector3.forward;
bool mobileSwimUp = (Input.GetAxisRaw("Vertical") > 0.1f) && (lookDir.y > 0.4f);
if (isJumping || mobileSwimUp)
{
if (shouldersY < triggerTopY) // Если плечи под водой — плывем вверх
{
Vector3 vel = localPlayer.GetVelocity();
vel.y = swimSpeed;
localPlayer.SetVelocity(vel);
}
}
// 3. Блокиратор левитации (не пускает в воздух выше плеч)
if (shouldersY >= triggerTopY)
{
Vector3 vel = localPlayer.GetVelocity();
if (vel.y > 0)
{
vel.y = 0;
localPlayer.SetVelocity(vel);
}
}
}
}
}