EVERYTHING
This commit is contained in:
@@ -0,0 +1,470 @@
|
||||
using System.Collections;
|
||||
using System.Text;
|
||||
using BlockSpace.Voxels;
|
||||
using ExitGames.Client.Photon;
|
||||
using Photon.Pun;
|
||||
using Photon.Realtime;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BlockSpace.Gamemodes
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
[RequireComponent(typeof(PhotonView))]
|
||||
[RequireComponent(typeof(GamemodeZone))]
|
||||
public sealed class BuildBattleController : MonoBehaviourPunCallbacks
|
||||
{
|
||||
private enum Phase : byte
|
||||
{
|
||||
Build = 0,
|
||||
Play = 1
|
||||
}
|
||||
|
||||
private const double BuildDurationSeconds = 60.0;
|
||||
|
||||
private const double PlayDurationSeconds = 30.0;
|
||||
|
||||
[SerializeField]
|
||||
private string[] themes = new string[5] { "Castle", "Rocket", "Robot", "Dragon", "Treehouse" };
|
||||
|
||||
[SerializeField]
|
||||
private TMP_Text themeText;
|
||||
|
||||
[SerializeField]
|
||||
private TMP_Text timerText;
|
||||
|
||||
[SerializeField]
|
||||
private VoxelGroupManager groupManager;
|
||||
|
||||
[SerializeField]
|
||||
private bool enableLogs = true;
|
||||
|
||||
private GamemodeZone zone;
|
||||
|
||||
private string currentTheme;
|
||||
|
||||
private bool localWasInZone;
|
||||
|
||||
private bool cachedCreatorMode;
|
||||
|
||||
private bool cachedEditingLocked;
|
||||
|
||||
private Coroutine masterLoop;
|
||||
|
||||
private bool bootstrapAttempted;
|
||||
|
||||
private bool hasPhaseCache;
|
||||
|
||||
private Phase cachedPhase;
|
||||
|
||||
private double cachedStartTime;
|
||||
|
||||
private double nextMissingPropsLogTime;
|
||||
|
||||
private string PhaseKey => $"BB_{zone.zoneID}_phase";
|
||||
|
||||
private string StartKey => $"BB_{zone.zoneID}_start";
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
zone = GetComponent<GamemodeZone>();
|
||||
if (groupManager == null)
|
||||
{
|
||||
groupManager = ((VoxelGroupManager.Instance != null) ? VoxelGroupManager.Instance : Object.FindObjectOfType<VoxelGroupManager>());
|
||||
}
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (themeText != null)
|
||||
{
|
||||
themeText.text = "Waiting for next round...";
|
||||
}
|
||||
Log($"Start (inRoom={PhotonNetwork.InRoom}, isMaster={PhotonNetwork.IsMasterClient}, viewID={((base.photonView != null) ? base.photonView.ViewID : (-1))})");
|
||||
TryStartMasterLoop();
|
||||
}
|
||||
|
||||
private new void OnEnable()
|
||||
{
|
||||
Log($"OnEnable (inRoom={PhotonNetwork.InRoom}, isMaster={PhotonNetwork.IsMasterClient})");
|
||||
TryStartMasterLoop();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
UpdateTimerText();
|
||||
UpdateMasterPhaseAdvance();
|
||||
ApplyLocalToolRules();
|
||||
}
|
||||
|
||||
private IEnumerator MasterLoop()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
yield return WaitForSecondsNetwork(60.0);
|
||||
StartPlayPhase();
|
||||
yield return WaitForSecondsNetwork(30.0);
|
||||
StartBuildPhase();
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnJoinedRoom()
|
||||
{
|
||||
if (themeText != null)
|
||||
{
|
||||
themeText.text = "Waiting for next round...";
|
||||
}
|
||||
Log($"OnJoinedRoom (isMaster={PhotonNetwork.IsMasterClient}, viewID={((base.photonView != null) ? base.photonView.ViewID : (-1))})");
|
||||
TryStartMasterLoop();
|
||||
}
|
||||
|
||||
public override void OnMasterClientSwitched(Player newMasterClient)
|
||||
{
|
||||
Log($"OnMasterClientSwitched (newMaster={newMasterClient?.ActorNumber}, amMaster={PhotonNetwork.IsMasterClient})");
|
||||
TryStartMasterLoop();
|
||||
}
|
||||
|
||||
private void TryStartMasterLoop()
|
||||
{
|
||||
if (!PhotonNetwork.InRoom)
|
||||
{
|
||||
Log("TryStartMasterLoop: not in room yet");
|
||||
}
|
||||
else if (!PhotonNetwork.IsMasterClient)
|
||||
{
|
||||
Log("TryStartMasterLoop: not master");
|
||||
if (masterLoop != null)
|
||||
{
|
||||
StopCoroutine(masterLoop);
|
||||
masterLoop = null;
|
||||
Log("Stopped master loop.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EnsurePhotonViewReady();
|
||||
if (masterLoop == null)
|
||||
{
|
||||
Log("Starting master loop; kicking BUILD immediately.");
|
||||
StartBuildPhase();
|
||||
masterLoop = StartCoroutine(MasterLoop());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void EnsurePhotonViewReady()
|
||||
{
|
||||
if (!(base.photonView == null) && base.photonView.ViewID == 0 && PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient)
|
||||
{
|
||||
bool flag = PhotonNetwork.AllocateViewID(base.photonView);
|
||||
Log($"AllocateViewID -> {flag} (viewID={base.photonView.ViewID})");
|
||||
}
|
||||
}
|
||||
|
||||
private void StartBuildPhase()
|
||||
{
|
||||
if (PhotonNetwork.IsMasterClient && !IsFreshPhase(Phase.Build))
|
||||
{
|
||||
EnsurePhotonViewReady();
|
||||
Log($"BUILD start (zoneID={zone.zoneID})");
|
||||
int num = ((groupManager != null) ? groupManager.RemoveGroupsForZone(zone) : 0);
|
||||
Log($"BUILD cleared {num} group(s) in zone {zone.zoneID}");
|
||||
string text = PickRandomTheme();
|
||||
RPC_SetTheme(text);
|
||||
Log("BUILD theme picked: " + text);
|
||||
base.photonView.RPC("RPC_SetTheme", RpcTarget.AllViaServer, text);
|
||||
SetPhaseProperties(Phase.Build, PhotonNetwork.Time);
|
||||
}
|
||||
}
|
||||
|
||||
private void StartPlayPhase()
|
||||
{
|
||||
if (PhotonNetwork.IsMasterClient && !IsFreshPhase(Phase.Play))
|
||||
{
|
||||
EnsurePhotonViewReady();
|
||||
Log($"PLAY start (zoneID={zone.zoneID})");
|
||||
SetPhaseProperties(Phase.Play, PhotonNetwork.Time);
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsFreshPhase(Phase phase)
|
||||
{
|
||||
if (hasPhaseCache && cachedPhase == phase)
|
||||
{
|
||||
return PhotonNetwork.Time - cachedStartTime < 1.0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private string PickRandomTheme()
|
||||
{
|
||||
if (themes == null || themes.Length == 0)
|
||||
{
|
||||
return "Something";
|
||||
}
|
||||
int num = Random.Range(0, themes.Length);
|
||||
if (!string.IsNullOrEmpty(themes[num]))
|
||||
{
|
||||
return themes[num];
|
||||
}
|
||||
return "Something";
|
||||
}
|
||||
|
||||
private void SetPhaseProperties(Phase phase, double startTimestamp)
|
||||
{
|
||||
if (PhotonNetwork.InRoom)
|
||||
{
|
||||
if (PhotonNetwork.CurrentRoom == null)
|
||||
{
|
||||
Log("SetPhaseProperties: CurrentRoom is null");
|
||||
return;
|
||||
}
|
||||
ExitGames.Client.Photon.Hashtable propertiesToSet = new ExitGames.Client.Photon.Hashtable
|
||||
{
|
||||
{
|
||||
PhaseKey,
|
||||
(int)phase
|
||||
},
|
||||
{ StartKey, startTimestamp }
|
||||
};
|
||||
PhotonNetwork.CurrentRoom.SetCustomProperties(propertiesToSet);
|
||||
Log(string.Format("SetPhaseProperties: {0} start={1:F3}", (phase == Phase.Build) ? "BUILD" : "PLAY", startTimestamp));
|
||||
LogRoomProps("After SetCustomProperties");
|
||||
cachedPhase = phase;
|
||||
cachedStartTime = startTimestamp;
|
||||
hasPhaseCache = true;
|
||||
base.photonView.RPC("RPC_SyncPhase", RpcTarget.AllViaServer, (int)phase, startTimestamp);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateTimerText()
|
||||
{
|
||||
if (timerText == null || !PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!TryGetSyncedPhase(out var phase, out var startTime))
|
||||
{
|
||||
if (PhotonNetwork.Time >= nextMissingPropsLogTime)
|
||||
{
|
||||
nextMissingPropsLogTime = PhotonNetwork.Time + 2.0;
|
||||
Log("UpdateTimerText: missing phase/start properties");
|
||||
LogRoomProps("Timer missing props");
|
||||
}
|
||||
if (!bootstrapAttempted && PhotonNetwork.IsMasterClient)
|
||||
{
|
||||
bootstrapAttempted = true;
|
||||
Log("UpdateTimerText: bootstrapping BUILD phase (master detected, no phase cache present).");
|
||||
StartBuildPhase();
|
||||
}
|
||||
if (!TryGetSyncedPhase(out phase, out startTime))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
bootstrapAttempted = false;
|
||||
double num = ((phase == Phase.Build) ? 60.0 : 30.0);
|
||||
double num2 = PhotonNetwork.Time - startTime;
|
||||
int num3 = Mathf.Max(0, Mathf.CeilToInt((float)(num - num2)));
|
||||
timerText.text = ((phase == Phase.Build) ? "BUILD: " : "PLAY: ") + num3;
|
||||
}
|
||||
|
||||
private void UpdateMasterPhaseAdvance()
|
||||
{
|
||||
if (!PhotonNetwork.InRoom || !PhotonNetwork.IsMasterClient || !TryGetSyncedPhase(out var phase, out var startTime))
|
||||
{
|
||||
return;
|
||||
}
|
||||
double num = ((phase == Phase.Build) ? 60.0 : 30.0);
|
||||
double num2 = PhotonNetwork.Time - startTime;
|
||||
if (!(num2 < num))
|
||||
{
|
||||
Log(string.Format("Master advancing phase from {0} after {1:F2}s", (phase == Phase.Build) ? "BUILD" : "PLAY", num2));
|
||||
if (phase == Phase.Build)
|
||||
{
|
||||
StartPlayPhase();
|
||||
}
|
||||
else
|
||||
{
|
||||
StartBuildPhase();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool TryGetSyncedPhase(out Phase phase, out double startTime)
|
||||
{
|
||||
if (hasPhaseCache)
|
||||
{
|
||||
phase = cachedPhase;
|
||||
startTime = cachedStartTime;
|
||||
return true;
|
||||
}
|
||||
if (TryGetPhaseAndStart(out phase, out startTime))
|
||||
{
|
||||
cachedPhase = phase;
|
||||
cachedStartTime = startTime;
|
||||
hasPhaseCache = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool TryGetPhaseAndStart(out Phase phase, out double startTime)
|
||||
{
|
||||
phase = Phase.Build;
|
||||
startTime = 0.0;
|
||||
if (PhotonNetwork.CurrentRoom.CustomProperties == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
PhotonNetwork.CurrentRoom.CustomProperties.TryGetValue(PhaseKey, out var value);
|
||||
PhotonNetwork.CurrentRoom.CustomProperties.TryGetValue(StartKey, out var value2);
|
||||
if (value == null || value2 == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (value is int value3)
|
||||
{
|
||||
phase = (Phase)Mathf.Clamp(value3, 0, 1);
|
||||
}
|
||||
else if (value is byte value4)
|
||||
{
|
||||
phase = (Phase)Mathf.Clamp(value4, 0, 1);
|
||||
}
|
||||
if (value2 is double num)
|
||||
{
|
||||
startTime = num;
|
||||
}
|
||||
else if (value2 is float num2)
|
||||
{
|
||||
startTime = num2;
|
||||
}
|
||||
else if (value2 is int num3)
|
||||
{
|
||||
startTime = num3;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void OnRoomPropertiesUpdate(ExitGames.Client.Photon.Hashtable propertiesThatChanged)
|
||||
{
|
||||
if (propertiesThatChanged != null && (propertiesThatChanged.ContainsKey(PhaseKey) || propertiesThatChanged.ContainsKey(StartKey)))
|
||||
{
|
||||
LogRoomProps("OnRoomPropertiesUpdate (phase/start changed)");
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyLocalToolRules()
|
||||
{
|
||||
if (zone == null || groupManager == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
bool flag = GamemodeZoneManager.Instance != null && GamemodeZoneManager.Instance.CurrentZone == zone;
|
||||
if (flag != localWasInZone)
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
cachedCreatorMode = groupManager.CreatorMode;
|
||||
cachedEditingLocked = groupManager.EditingLocked;
|
||||
}
|
||||
else
|
||||
{
|
||||
groupManager.SetEditingLocked(cachedEditingLocked);
|
||||
groupManager.SetCreatorMode(cachedCreatorMode);
|
||||
}
|
||||
localWasInZone = flag;
|
||||
}
|
||||
if (flag && PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null && TryGetSyncedPhase(out var phase, out var _))
|
||||
{
|
||||
if (phase == Phase.Build)
|
||||
{
|
||||
groupManager.SetEditingLocked(locked: false);
|
||||
groupManager.SetCreatorMode(enabled: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
groupManager.SetEditingLocked(locked: true);
|
||||
groupManager.SetCreatorMode(enabled: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator WaitForSecondsNetwork(double seconds)
|
||||
{
|
||||
double start = PhotonNetwork.Time;
|
||||
while (PhotonNetwork.Time - start < seconds)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
|
||||
[PunRPC]
|
||||
private void RPC_SetTheme(string theme)
|
||||
{
|
||||
currentTheme = theme;
|
||||
if (themeText != null)
|
||||
{
|
||||
themeText.text = "Theme: " + theme;
|
||||
}
|
||||
Log("RPC_SetTheme received: " + theme);
|
||||
}
|
||||
|
||||
[PunRPC]
|
||||
private void RPC_SyncPhase(int phase, double startTimestamp)
|
||||
{
|
||||
cachedPhase = (Phase)Mathf.Clamp(phase, 0, 1);
|
||||
cachedStartTime = startTimestamp;
|
||||
hasPhaseCache = true;
|
||||
Log(string.Format("RPC_SyncPhase received: {0} start={1:F3}", (cachedPhase == Phase.Build) ? "BUILD" : "PLAY", startTimestamp));
|
||||
}
|
||||
|
||||
private void Log(string message)
|
||||
{
|
||||
if (enableLogs)
|
||||
{
|
||||
Debug.Log($"[BuildBattle zone={zone.zoneID}] {message}", this);
|
||||
}
|
||||
}
|
||||
|
||||
private void LogRoomProps(string prefix)
|
||||
{
|
||||
if (enableLogs && PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null)
|
||||
{
|
||||
object value = null;
|
||||
object value2 = null;
|
||||
if (PhotonNetwork.CurrentRoom.CustomProperties != null)
|
||||
{
|
||||
PhotonNetwork.CurrentRoom.CustomProperties.TryGetValue(PhaseKey, out value);
|
||||
PhotonNetwork.CurrentRoom.CustomProperties.TryGetValue(StartKey, out value2);
|
||||
}
|
||||
string text = ((PhotonNetwork.CurrentRoom.CustomProperties != null) ? FormatHashtable(PhotonNetwork.CurrentRoom.CustomProperties) : "null");
|
||||
Debug.Log(string.Format("[BuildBattle zone={0}] {1} keys=({2}={3}, {4}={5}) all={6}", zone.zoneID, prefix, PhaseKey, value ?? "null", StartKey, value2 ?? "null", text), this);
|
||||
}
|
||||
}
|
||||
|
||||
private static string FormatHashtable(IDictionary table)
|
||||
{
|
||||
if (table == null)
|
||||
{
|
||||
return "null";
|
||||
}
|
||||
StringBuilder stringBuilder = new StringBuilder(256);
|
||||
stringBuilder.Append("{");
|
||||
bool flag = true;
|
||||
foreach (DictionaryEntry item in table)
|
||||
{
|
||||
if (!flag)
|
||||
{
|
||||
stringBuilder.Append(", ");
|
||||
}
|
||||
flag = false;
|
||||
stringBuilder.Append((item.Key != null) ? item.Key.ToString() : "null");
|
||||
stringBuilder.Append("=");
|
||||
stringBuilder.Append((item.Value != null) ? item.Value.ToString() : "null");
|
||||
}
|
||||
stringBuilder.Append("}");
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 06715e3dff39b88da77c8f77f24a4212
|
||||
timeCreated: 1780325055
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
externalObjects: {}
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace BlockSpace.Gamemodes
|
||||
{
|
||||
public enum GamemodeType : byte
|
||||
{
|
||||
BuildBattle = 0,
|
||||
Tag = 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0a05560d801134644a774c189adb0943
|
||||
@@ -0,0 +1,132 @@
|
||||
using System.Collections.Generic;
|
||||
using BlockSpace.Voxels;
|
||||
using Photon.VR.Player;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BlockSpace.Gamemodes
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
[RequireComponent(typeof(Collider))]
|
||||
public sealed class GamemodeZone : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
public int zoneID;
|
||||
|
||||
[SerializeField]
|
||||
public GamemodeType type;
|
||||
|
||||
private readonly HashSet<int> playersInside = new HashSet<int>();
|
||||
|
||||
private Collider zoneCollider;
|
||||
|
||||
public IReadOnlyCollection<int> PlayersInside => playersInside;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
zoneCollider = GetComponent<Collider>();
|
||||
if (zoneCollider != null)
|
||||
{
|
||||
zoneCollider.isTrigger = true;
|
||||
}
|
||||
if (GamemodeZoneManager.Instance == null)
|
||||
{
|
||||
GameObject obj = new GameObject("GamemodeZoneManager");
|
||||
obj.AddComponent<GamemodeZoneManager>();
|
||||
Object.DontDestroyOnLoad(obj);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
EnsureZoneManager();
|
||||
GamemodeZoneManager.Instance?.RegisterZone(this);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
GamemodeZoneManager.Instance?.UnregisterZone(this);
|
||||
}
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
Collider component = GetComponent<Collider>();
|
||||
if (component != null)
|
||||
{
|
||||
component.isTrigger = true;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ContainsGroup(VoxelGroup group)
|
||||
{
|
||||
if (group == null || group.size.x <= 0 || group.size.y <= 0 || group.size.z <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (zoneCollider == null)
|
||||
{
|
||||
zoneCollider = GetComponent<Collider>();
|
||||
}
|
||||
if (zoneCollider != null)
|
||||
{
|
||||
return zoneCollider.bounds.Intersects(group.GetWorldBounds());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool ContainsWorldPosition(Vector3 worldPosition)
|
||||
{
|
||||
if (zoneCollider == null)
|
||||
{
|
||||
zoneCollider = GetComponent<Collider>();
|
||||
}
|
||||
if (zoneCollider != null)
|
||||
{
|
||||
return zoneCollider.bounds.Contains(worldPosition);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
internal void RefreshPlayersInside(PhotonVRPlayer[] players)
|
||||
{
|
||||
playersInside.Clear();
|
||||
if (players == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (PhotonVRPlayer photonVRPlayer in players)
|
||||
{
|
||||
if (!(photonVRPlayer == null) && !(photonVRPlayer.photonView == null) && photonVRPlayer.photonView.Owner != null && ContainsWorldPosition(GetPlayerZonePosition(photonVRPlayer)))
|
||||
{
|
||||
playersInside.Add(photonVRPlayer.photonView.Owner.ActorNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static Vector3 GetPlayerZonePosition(PhotonVRPlayer player)
|
||||
{
|
||||
if (player == null)
|
||||
{
|
||||
return Vector3.zero;
|
||||
}
|
||||
if (player.Head != null)
|
||||
{
|
||||
return player.Head.position;
|
||||
}
|
||||
if (!(player.Body != null))
|
||||
{
|
||||
return player.transform.position;
|
||||
}
|
||||
return player.Body.position;
|
||||
}
|
||||
|
||||
private static void EnsureZoneManager()
|
||||
{
|
||||
if (!(GamemodeZoneManager.Instance != null))
|
||||
{
|
||||
GameObject obj = new GameObject("GamemodeZoneManager");
|
||||
obj.AddComponent<GamemodeZoneManager>();
|
||||
Object.DontDestroyOnLoad(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b3fcd6fe0b347da5e9598a2a20a86acc
|
||||
timeCreated: 1780325055
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
externalObjects: {}
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,93 @@
|
||||
using System.Collections.Generic;
|
||||
using Photon.VR.Player;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BlockSpace.Gamemodes
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
public sealed class GamemodeZoneManager : MonoBehaviour
|
||||
{
|
||||
private readonly List<GamemodeZone> zones = new List<GamemodeZone>();
|
||||
|
||||
public static GamemodeZoneManager Instance { get; private set; }
|
||||
|
||||
public GamemodeZone CurrentZone { get; private set; }
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance != null && Instance != this)
|
||||
{
|
||||
Object.Destroy(base.gameObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
Instance = this;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (Instance == this)
|
||||
{
|
||||
Instance = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
RefreshZonesFromPlayerPositions();
|
||||
}
|
||||
|
||||
internal void RegisterZone(GamemodeZone zone)
|
||||
{
|
||||
if (!(zone == null) && !zones.Contains(zone))
|
||||
{
|
||||
zones.Add(zone);
|
||||
}
|
||||
}
|
||||
|
||||
internal void UnregisterZone(GamemodeZone zone)
|
||||
{
|
||||
if (!(zone == null))
|
||||
{
|
||||
zones.Remove(zone);
|
||||
if (CurrentZone == zone)
|
||||
{
|
||||
CurrentZone = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshZonesFromPlayerPositions()
|
||||
{
|
||||
if (zones.Count == 0)
|
||||
{
|
||||
CurrentZone = null;
|
||||
return;
|
||||
}
|
||||
PhotonVRPlayer[] array = Object.FindObjectsByType<PhotonVRPlayer>(FindObjectsInactive.Include);
|
||||
PhotonVRPlayer photonVRPlayer = null;
|
||||
foreach (PhotonVRPlayer photonVRPlayer2 in array)
|
||||
{
|
||||
if (!(photonVRPlayer2 == null) && photonVRPlayer2.photonView != null && photonVRPlayer2.photonView.IsMine)
|
||||
{
|
||||
photonVRPlayer = photonVRPlayer2;
|
||||
}
|
||||
}
|
||||
CurrentZone = null;
|
||||
Vector3 worldPosition = ((photonVRPlayer != null) ? GamemodeZone.GetPlayerZonePosition(photonVRPlayer) : Vector3.zero);
|
||||
for (int j = 0; j < zones.Count; j++)
|
||||
{
|
||||
GamemodeZone gamemodeZone = zones[j];
|
||||
if (!(gamemodeZone == null))
|
||||
{
|
||||
gamemodeZone.RefreshPlayersInside(array);
|
||||
if (photonVRPlayer != null && CurrentZone == null && gamemodeZone.ContainsWorldPosition(worldPosition))
|
||||
{
|
||||
CurrentZone = gamemodeZone;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e68242b621309c19393fc31f439cd809
|
||||
timeCreated: 1780325055
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
externalObjects: {}
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user