using UdonSharp; using UnityEngine; using VRC.SDKBase; public class WaterSystem : UdonSharpBehaviour { [Header("--- Настройки синевы ---")] [SerializeField] private float offset = -0.4f; // Смещение синего экрана (глаза) [SerializeField] [Range(0f, 1f)] private float waterDensity = 1.0f; // Ползунок прозрачности воды под водой [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; if (headY < triggerTopY) { RenderSettings.fog = true; RenderSettings.fogDensity = waterDensity; } else { RenderSettings.fog = false; RenderSettings.fogDensity = 0f; } 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); } } if (shouldersY >= triggerTopY) { Vector3 vel = localPlayer.GetVelocity(); if (vel.y > 0) { vel.y = 0; localPlayer.SetVelocity(vel); } } } } }