Clean code with clientrpc enabling of platforms

dev-hazim
Ali Sharoz 2 weeks ago
parent 9f8cd0077b
commit 80b678cafb

@ -595,6 +595,8 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: fbadb65558c0b1a48b58b765317ed874, type: 3}
m_Name:
m_EditorClassIdentifier:
PlatformID:
m_InternalValue: 0
--- !u!64 &249976107358570839
MeshCollider:
m_ObjectHideFlags: 0
@ -788,6 +790,8 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: fbadb65558c0b1a48b58b765317ed874, type: 3}
m_Name:
m_EditorClassIdentifier:
PlatformID:
m_InternalValue: 0
--- !u!64 &1223475210011116503
MeshCollider:
m_ObjectHideFlags: 0
@ -982,6 +986,8 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: fbadb65558c0b1a48b58b765317ed874, type: 3}
m_Name:
m_EditorClassIdentifier:
PlatformID:
m_InternalValue: 0
--- !u!64 &1326862948614608681
MeshCollider:
m_ObjectHideFlags: 0
@ -1160,6 +1166,8 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: fbadb65558c0b1a48b58b765317ed874, type: 3}
m_Name:
m_EditorClassIdentifier:
PlatformID:
m_InternalValue: 0
--- !u!64 &3169561862507413954
MeshCollider:
m_ObjectHideFlags: 0
@ -1338,6 +1346,8 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: fbadb65558c0b1a48b58b765317ed874, type: 3}
m_Name:
m_EditorClassIdentifier:
PlatformID:
m_InternalValue: 0
--- !u!64 &5215249593494578416
MeshCollider:
m_ObjectHideFlags: 0
@ -1516,6 +1526,8 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: fbadb65558c0b1a48b58b765317ed874, type: 3}
m_Name:
m_EditorClassIdentifier:
PlatformID:
m_InternalValue: 0
--- !u!64 &5615547279758710380
MeshCollider:
m_ObjectHideFlags: 0
@ -1694,6 +1706,8 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: fbadb65558c0b1a48b58b765317ed874, type: 3}
m_Name:
m_EditorClassIdentifier:
PlatformID:
m_InternalValue: 0
--- !u!64 &7017483914677023159
MeshCollider:
m_ObjectHideFlags: 0

@ -307,7 +307,7 @@ namespace Unity.BossRoom.Gameplay.GameplayObjects.Character
private void HandleOccupiedPlatform(Platform currentPlatform)
{
var nearestPlatform = PlatformManager.Instance.FindNearestUnoccupiedPlatform(transform.position);
var nearestPlatform = PlatformManager.Instance.GetNearestAvailablePlatform(transform.position);
if (nearestPlatform != null)
{
Debug.Log($"Platform {currentPlatform.PlatformID} is occupied. Moving to nearest Platform {nearestPlatform.PlatformID}.");
@ -322,14 +322,25 @@ namespace Unity.BossRoom.Gameplay.GameplayObjects.Character
private void MoveToPlatform(Platform platform)
{
SetTargetPlatform(platform.PlatformID);
var pltpos = PlatformManager.Instance.GetPlatformPosition(platform.PlatformID);
pltpos.y = 0;
int platformID = platform.PlatformID.Value; // Access the value of NetworkVariable<int>
SetTargetPlatform(platformID); // Set the target platform ID
var pltpos = PlatformManager.Instance.GetPlatformPosition(platformID); // Get platform position
pltpos.y = 0; // Reset Y-axis position for movement
Debug.Log($"Platform position: {pltpos}.");
IsSwapping = true;
ServerSendCharacterInputRpc(pltpos);
ServerSendCharacterInputRpc(pltpos); // Send the movement request
}
//private void MoveToPlatform(Platform platform)
//{
// SetTargetPlatform(platform.PlatformID);
// var pltpos = PlatformManager.Instance.GetPlatformPosition(platform.PlatformID);
// pltpos.y = 0;
// Debug.Log($"Platform position: {pltpos}.");
// IsSwapping = true;
// ServerSendCharacterInputRpc(pltpos);
//}
private void BecomeCrow()
{
ClearTargetPlatform();
@ -378,8 +389,8 @@ namespace Unity.BossRoom.Gameplay.GameplayObjects.Character
public void InitiateSwap(ServerCharacter initiatingPlayer, ServerCharacter targetPlayer)
{
var initiatingPlatform = PlatformManager.Instance.GetPlatformOccupiedByPlayer(initiatingPlayer);
var targetPlatform = PlatformManager.Instance.GetPlatformOccupiedByPlayer(targetPlayer);
var initiatingPlatform = PlatformManager.Instance.GetPlayerPlatform(initiatingPlayer);
var targetPlatform = PlatformManager.Instance.GetPlayerPlatform(targetPlayer);
if (initiatingPlatform == null || targetPlatform == null)
{

@ -9,184 +9,97 @@ namespace Unity.Multiplayer.Samples.BossRoom
[RequireComponent(typeof(Collider))]
public class Platform : NetworkBehaviour
{
public int PlatformID { get; private set; }
public NetworkVariable<int> PlatformID = new NetworkVariable<int>(0);
public bool IsOccupied { get; private set; }
private NetworkVariable<ulong> OccupierId = new NetworkVariable<ulong>(0, NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Server);
private Collider m_PlatformCollider;
private NetworkVariable<ulong> occupierId = new NetworkVariable<ulong>(0, NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Server);
private Collider platformCollider;
private Animator animator;
private NetworkAnimator networkAnimator;
public void PauseAnimation()
private void Awake()
{
platformCollider = GetComponent<Collider>();
if (!platformCollider.isTrigger)
platformCollider.isTrigger = true;
animator = GetComponent<Animator>();
}
public void Initialize(int id)
{
if (IsServer) PlatformID.Value = id;
}
public void StartRotation() => transform.DOLocalRotate(Vector3.up, 120).SetSpeedBased(true).SetId(PlatformID).SetLoops(-1, LoopType.Incremental);
private void PauseRotation() => DOTween.Pause(PlatformID);
private void ResumeRotation() => DOTween.Play(PlatformID);
public void Pause()
{
if (IsOwner)
{
// Pause the animation locally
animator.speed = 0f;
// Inform the server to pause animation for all clients
PauseAnimationServerRpc();
PauseServerRpc();
}
}
public void ResumeAnimation()
public void Resume()
{
if (IsOwner)
{
// Resume the animation locally
animator.speed = 1f;
// Inform the server to resume animation for all clients
ResumeAnimationServerRpc();
ResumeServerRpc();
}
}
[ServerRpc]
private void PauseAnimationServerRpc()
{
// On the server, pause animation for all clients
PauseAnimationClientRpc();
}
private void PauseServerRpc() => PauseClientRpc();
[ClientRpc]
private void PauseAnimationClientRpc()
{
animator.speed = 0f;
}
private void PauseClientRpc() => animator.speed = 0f;
[ServerRpc]
private void ResumeAnimationServerRpc()
{
// On the server, resume animation for all clients
ResumeAnimationClientRpc();
}
private void ResumeServerRpc() => ResumeClientRpc();
[ClientRpc]
private void ResumeAnimationClientRpc()
{
animator.speed = 1f;
}
private void Awake()
{
m_PlatformCollider = GetComponent<Collider>();
if (!m_PlatformCollider.isTrigger)
{
Debug.LogWarning($"Platform {name} collider must be set as a trigger.");
m_PlatformCollider.isTrigger = true; // Ensure it's a trigger.
}
animator = GetComponent<Animator>();
networkAnimator = GetComponent<NetworkAnimator>();
}
private void ResumeClientRpc() => animator.speed = 1f;
public void AssignID(int id)
{
PlatformID = id;
IsOccupied = false;
Debug.Log($"Platform {name} assigned ID: {PlatformID}");
}
public void AnimationStarter()
{
transform.DOLocalRotate(Vector3.up, 120).SetSpeedBased(true).SetId(PlatformID).SetLoops(-1, LoopType.Incremental);
}
void AnimationResumer()
{
Debug.Log("Play PlatformID: " + PlatformID);
DOTween.Play(PlatformID);
}
void AnimationPauser()
{
Debug.Log("Pause PlatformID: " + PlatformID);
DOTween.Pause(PlatformID);
}
public void Occupy(ServerCharacter player)
{
if (!IsServer)
{
Debug.LogError("Occupy can only be called on the server.");
return;
}
PauseAnimation();
if (IsOccupied)
{
Debug.LogWarning($"Platform {PlatformID} is already occupied.");
return;
}
bool giveScore = player.PreviousPlatformId != PlatformID;
// Check if the player who occupied this platform had this platform as their target platform
if (giveScore)
{
if (player.TargetPlatformId.HasValue && player.TargetPlatformId.Value == PlatformID)
{
// Successful swap
ScoreManager.Instance.AddPlayerScore(player.OwnerClientId, 10);
Debug.Log($"Player {player.OwnerClientId} successfully swapped to Platform {PlatformID}. Awarded 10 score.");
}
else
{
ScoreManager.Instance.AddPlayerScore(player.OwnerClientId, 20);
Debug.Log($"Crow Player {player.OwnerClientId} successfully stole Platform {PlatformID}. Awarded 20 score.");
}
}
if (!IsServer || IsOccupied) return;
Pause();
bool giveScore = player.PreviousPlatformId != PlatformID.Value;
int score = (player.TargetPlatformId == PlatformID.Value) ? 10 : 20;
if (giveScore) ScoreManager.Instance.AddPlayerScore(player.OwnerClientId, score);
IsOccupied = true;
OccupierId.Value = player.OwnerClientId;
player.OnArrivalOnPlatform(PlatformID);
Debug.Log($"Platform {PlatformID} is now occupied by Player {player.OwnerClientId}.");
occupierId.Value = player.OwnerClientId;
player.OnArrivalOnPlatform(PlatformID.Value);
}
public void Vacate(ServerCharacter player)
{
if (!IsServer)
{
Debug.LogError("Vacate can only be called on the server.");
return;
}
ResumeAnimation();
if (!IsServer || !IsOccupied || occupierId.Value != player.OwnerClientId) return;
if (!IsOccupied || OccupierId.Value != player.OwnerClientId)
{
Debug.LogWarning($"Platform {PlatformID} is not occupied by Player {player.OwnerClientId}.");
return;
}
Resume();
IsOccupied = false;
OccupierId.Value = 0;
player.OnLeavingPlatform(PlatformID);
Debug.Log($"Platform {PlatformID} is now vacated.");
occupierId.Value = 0;
player.OnLeavingPlatform(PlatformID.Value);
}
private void OnTriggerEnter(Collider other)
{
if (!IsServer) return;
if (other.TryGetComponent<ServerCharacter>(out var player))
{
if (!IsOccupied)
{
if (IsServer && other.TryGetComponent<ServerCharacter>(out var player) && !IsOccupied)
Occupy(player);
}
else
{
Debug.Log($"Player {player.OwnerClientId} attempted to occupy an already occupied Platform {PlatformID}.");
}
}
}
public ulong GetOccupierId()
{
return OccupierId.Value;
}
private void OnTriggerExit(Collider other)
{
if (!IsServer) return;
if (other.TryGetComponent<ServerCharacter>(out var player))
{
if (IsServer && other.TryGetComponent<ServerCharacter>(out var player))
Vacate(player);
if (OccupierId.Value == player.OwnerClientId)
player.OnLeavingPlatform(PlatformID);
}
}
public ulong GetOccupierId() => occupierId.Value;
}
}

@ -1,3 +1,4 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Unity.BossRoom.Gameplay.GameplayObjects.Character;
@ -9,112 +10,81 @@ namespace Unity.Multiplayer.Samples.BossRoom
public class PlatformManager : NetworkBehaviour
{
public static PlatformManager Instance;
public List<Platform> m_Platforms;
public int numberOfPlayers = 2; // Number of players (n)
public float planeRadius = 4f; // Radius of the circular plane
private List<Platform> platforms;
private void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(gameObject);
}
else
{
Instance = this;
}
}
private void Start()
{
//if (IsServer) // Ensure only the server assigns IDs and initializes
{
m_Platforms = GetComponentsInChildren<Platform>().ToList();
platforms = GetComponentsInChildren<Platform>(true).ToList();
if (IsServer) StartCoroutine(ServerSetup());
else StartCoroutine(ClientSetup());
}
for (int i = 0; i < m_Platforms.Count; i++)
private IEnumerator ServerSetup()
{
m_Platforms[i].AssignID(i + 1); // IDs start from 1
yield return new WaitForSeconds(0.5f);
ActivatePlatformsServerRpc();
}
Debug.Log("All platforms have been assigned unique IDs.");
Starter();
}
}
void Starter()
private IEnumerator ClientSetup()
{
int platformsToSpawn = PlayerPrefs.GetInt("NumberOfLobbyPlayers") - 1;
if (platformsToSpawn <= 0) return;
m_Platforms.ForEach(platform => platform.gameObject.SetActive(false));
for (int i = 0; i < platformsToSpawn; i++) m_Platforms[i].gameObject.SetActive(true);
m_Platforms = m_Platforms.Where(p => p.gameObject.activeInHierarchy).ToList();
float angleIncrement = 360f / platformsToSpawn;
for (int i = 0; i < platformsToSpawn; i++)
m_Platforms[i].transform.position = new Vector3(
Mathf.Cos(i * angleIncrement * Mathf.Deg2Rad) * planeRadius,
0f,
Mathf.Sin(i * angleIncrement * Mathf.Deg2Rad) * planeRadius
);
yield return new WaitForSeconds(0.5f);
platforms = GetComponentsInChildren<Platform>(true).ToList();
}
public Platform FindNearestUnoccupiedPlatform(Vector3 position)
{
if (!IsServer)
[ServerRpc(RequireOwnership = false)]
private void ActivatePlatformsServerRpc()
{
Debug.LogError("FindNearestUnoccupiedPlatform should only be called on the server.");
return null;
}
int activeCount = PlayerPrefs.GetInt("NumberOfLobbyPlayers") - 1;
if (activeCount <= 0) return;
return m_Platforms
.Where(platform => !platform.IsOccupied)
.OrderBy(platform => Vector3.Distance(position, platform.transform.position))
.FirstOrDefault();
}
platforms.ForEach(p => p.gameObject.SetActive(false));
for (int i = 0; i < activeCount; i++)
platforms[i].gameObject.SetActive(true);
public bool AreAllPlatformsOccupied()
{
return m_Platforms.All(platform => platform.IsOccupied);
var activeIds = platforms.Where(p => p.gameObject.activeSelf).Select(p => p.PlatformID.Value).ToArray();
ActivatePlatformsClientRpc(activeIds);
}
public bool AssignPlayerToPlatform(ServerCharacter player)
{
if (!IsServer)
[ClientRpc]
private void ActivatePlatformsClientRpc(int[] platformIds)
{
Debug.LogError("AssignPlayerToPlatform should only be called on the server.");
return false;
platforms = GetComponentsInChildren<Platform>(true).ToList();
platforms.ForEach(p => p.gameObject.SetActive(false));
foreach (int id in platformIds)
platforms.FirstOrDefault(p => p.PlatformID.Value == id)?.gameObject.SetActive(true);
}
var platform = m_Platforms.FirstOrDefault(p => !p.IsOccupied);
if (platform != null)
public Platform GetNearestAvailablePlatform(Vector3 position)
{
platform.Occupy(player);
return true;
return IsServer ? platforms.Where(p => !p.IsOccupied).OrderBy(p => Vector3.Distance(position, p.transform.position)).FirstOrDefault() : null;
}
Debug.LogWarning($"No unoccupied platforms available for {player.name}.");
return false;
}
public bool AllPlatformsOccupied() => platforms.All(p => p.IsOccupied);
public Platform GetPlatformOccupiedByPlayer(ServerCharacter player)
public bool AssignPlayerToPlatform(ServerCharacter player)
{
return m_Platforms.FirstOrDefault(p => p.IsOccupied && p.GetOccupierId() == player.OwnerClientId);
}
if (!IsServer) return false;
public bool IsPlatformOccupied(Platform platform)
{
return platform.IsOccupied;
}
var availablePlatform = platforms.FirstOrDefault(p => !p.IsOccupied);
if (availablePlatform == null) return false;
public Vector3 GetPlatformPosition(int platformId)
{
var platform = m_Platforms.FirstOrDefault(p => p.PlatformID == platformId);
return platform ? platform.transform.position : Vector3.zero;
availablePlatform.Occupy(player);
return true;
}
public Platform GetPlatformById(int platformId)
{
return m_Platforms.FirstOrDefault(p => p.PlatformID == platformId);
}
public Platform GetPlayerPlatform(ServerCharacter player) => platforms.FirstOrDefault(p => p.IsOccupied && p.GetOccupierId() == player.OwnerClientId);
public Vector3 GetPlatformPosition(int platformId) => platforms.FirstOrDefault(p => p.PlatformID.Value == platformId)?.transform.position ?? Vector3.zero;
public Platform GetPlatformById(int platformId) => platforms.FirstOrDefault(p => p.PlatformID.Value == platformId);
}
}

@ -101,7 +101,7 @@ public class ScoreManager : NetworkBehaviour
private IEnumerator ApplyCrowPenaltyCoroutine()
{
yield return new WaitUntil(() => PlatformManager.Instance != null && PlatformManager.Instance.AreAllPlatformsOccupied());
yield return new WaitUntil(() => PlatformManager.Instance != null && PlatformManager.Instance.AllPlatformsOccupied());
while (true)
{

Loading…
Cancel
Save