156 lines
4.1 KiB
C#
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();
|
|
}
|
|
}
|