2025-06-04 19:22:54 +02:00

156 lines
4.1 KiB
C#

using UnityEngine;
using Fusion;
public class MapSyncController : NetworkBehaviour
{
[SerializeField] private Transform rotatableMapBase;
[SerializeField] private Transform waterPlane;
[SerializeField] private Transform mapModel;
public GameObject scenario0;
public GameObject scenario1;
public GameObject scenario2;
[Networked] public float MapRotation { get; set; }
[Networked] public float WaterLevel { get; set; }
public int CurrentScenario { 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();
ApplyScenario(0);
}
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 void ApplyScenario(int scenario)
{
Debug.Log($"ApplyScenario called with: {scenario}");
if (scenario0 == null || scenario1 == null)
{
Debug.LogError("Scenario GameObjects are not assigned!");
return;
}
if (scenario == 0)
{
scenario0.SetActive(true);
scenario1.SetActive(false);
scenario2.SetActive(false);
}
else if (scenario == 1)
{
scenario0.SetActive(false);
scenario1.SetActive(true);
scenario2.SetActive(true);
}
CurrentScenario = scenario;
}
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();
}
}