2025-06-02 18:44:13 +02:00

121 lines
3.3 KiB
C#

using UnityEngine;
using Fusion;
public class MapSyncController : NetworkBehaviour
{
[SerializeField] private Transform rotatableMapBase;
[SerializeField] private Transform waterPlane;
[SerializeField] private Transform mapModel;
[Networked] public float MapRotation { get; set; }
[Networked] public float WaterLevel { get; set; }
private Coroutine waterLevelCoroutine;
private const float waterLerpDuration = 0.5f; // Duration in seconds
private float lastSentRotation = -1f;
public override void Spawned()
{
if (HasStateAuthority && rotatableMapBase != null && waterPlane != null)
{
WaterLevel = waterPlane.position.y - rotatableMapBase.position.y;
}
ApplyWaterLevel();
}
public override void FixedUpdateNetwork()
{
if (!HasStateAuthority || rotatableMapBase == null) return;
float currentY = rotatableMapBase.localEulerAngles.y;
if (Mathf.Abs(currentY - lastSentRotation) > 0.1f)
{
MapRotation = currentY;
lastSentRotation = currentY;
}
}
public override void Render()
{
if (mapModel != null)
{
mapModel.localRotation = Quaternion.Euler(0f, MapRotation, 0f);
if (!HasStateAuthority)
{
rotatableMapBase.localRotation = Quaternion.Euler(0f, MapRotation, 0f);
}
}
}
public void RequestAuthority()
{
Object.RequestStateAuthority();
}
public void ReleaseAuthority()
{
Object.ReleaseStateAuthority();
}
[Rpc(RpcSources.All, RpcTargets.StateAuthority, InvokeLocal = false)]
private void RPC_StreamRotation(float newRotationY)
{
MapRotation = newRotationY;
}
public void SendLiveRotation(float newYRotation)
{
RPC_StreamRotation(newYRotation);
}
private void ApplyWaterLevel()
{
if (rotatableMapBase != null && waterPlane != null)
{
Vector3 basePosition = rotatableMapBase.position;
Vector3 targetPosition = new Vector3(basePosition.x, basePosition.y + WaterLevel, basePosition.z);
if (waterLevelCoroutine != null)
StopCoroutine(waterLevelCoroutine);
waterLevelCoroutine = StartCoroutine(AnimateWaterLevel(waterPlane.position, targetPosition, waterLerpDuration));
}
}
private System.Collections.IEnumerator AnimateWaterLevel(Vector3 startPos, Vector3 endPos, float duration)
{
float elapsed = 0f;
while (elapsed < duration)
{
waterPlane.position = Vector3.Lerp(startPos, endPos, elapsed / duration);
elapsed += Time.deltaTime;
yield return null;
}
waterPlane.position = endPos;
}
// Optional water level RPCs
[Rpc(RpcSources.All, RpcTargets.All)]
public void RPC_RequestWaterLevel(float level)
{
WaterLevel = level;
ApplyWaterLevel();
}
[Rpc(RpcSources.All, RpcTargets.All)]
public void RPC_IncreaseWaterLevel(float amount)
{
WaterLevel += amount;
ApplyWaterLevel();
}
[Rpc(RpcSources.All, RpcTargets.All)]
public void RPC_DecreaseWaterLevel(float amount)
{
WaterLevel -= amount;
ApplyWaterLevel();
}
}