Files
UltimateFishing/Assets/Scripts/Assembly-CSharp/Oculus/Platform/Samples/VrHoops/MatchController.cs
2026-02-21 16:45:37 +08:00

392 lines
11 KiB
C#

using System.Collections.Generic;
using Oculus.Platform.Models;
using UnityEngine;
using UnityEngine.UI;
namespace Oculus.Platform.Samples.VrHoops
{
public class MatchController : MonoBehaviour
{
private enum State
{
UNKNOWN = 0,
NONE = 1,
WAITING_TO_START_PRACTICE = 2,
PRACTICING = 3,
VIEWING_RESULTS_PRACTICE = 4,
WAITING_FOR_MATCH = 5,
WAITING_TO_SETUP_MATCH = 6,
PLAYING_MATCH = 7,
VIEWING_MATCH_RESULTS = 8
}
[SerializeField]
private Text m_timerText;
[SerializeField]
private Camera m_camera;
[SerializeField]
private Transform m_idleCameraTransform;
[SerializeField]
private Text m_matchmakeButtonText;
[SerializeField]
private PlayerArea[] m_playerAreas = new PlayerArea[3];
[SerializeField]
private uint PRACTICE_WARMUP_TIME = 5u;
[SerializeField]
private uint MATCH_WARMUP_TIME = 30u;
[SerializeField]
private uint MATCH_TIME = 20u;
[SerializeField]
private uint MATCH_COOLDOWN_TIME = 10u;
[SerializeField]
private GameObject m_mostWinsLeaderboard;
[SerializeField]
private GameObject m_highestScoresLeaderboard;
[SerializeField]
private GameObject m_leaderboardEntryPrefab;
[SerializeField]
private GameObject m_flytext;
private State m_currentState;
private float m_nextStateTransitionTime;
private int m_localSlot;
public float MatchStartTime
{
get
{
State currentState = m_currentState;
if (currentState == State.WAITING_TO_START_PRACTICE || currentState == State.WAITING_TO_SETUP_MATCH)
{
return m_nextStateTransitionTime;
}
return 0f;
}
private set
{
m_nextStateTransitionTime = value;
}
}
private void Start()
{
PlatformManager.Matchmaking.EnqueueResultCallback = OnMatchFoundCallback;
PlatformManager.Matchmaking.MatchPlayerAddedCallback = MatchPlayerAddedCallback;
PlatformManager.P2P.StartTimeOfferCallback = StartTimeOfferCallback;
PlatformManager.Leaderboards.MostWinsLeaderboardUpdatedCallback = MostWinsLeaderboardCallback;
PlatformManager.Leaderboards.HighScoreLeaderboardUpdatedCallback = HighestScoreLeaderboardCallback;
TransitionToState(State.NONE);
}
private void Update()
{
UpdateCheckForNextTimedTransition();
UpdateMatchTimer();
}
private void TransitionToState(State newState)
{
Debug.LogFormat("MatchController State {0} -> {1}", m_currentState, newState);
if (m_currentState != newState)
{
State currentState = m_currentState;
m_currentState = newState;
switch (newState)
{
case State.NONE:
SetupForIdle();
MoveCameraToIdlePosition();
PlatformManager.TransitionToState(PlatformManager.State.WAITING_TO_PRACTICE_OR_MATCHMAKE);
m_matchmakeButtonText.text = "Play Online";
break;
case State.WAITING_TO_START_PRACTICE:
SetupForPractice();
MoveCameraToMatchPosition();
PlatformManager.TransitionToState(PlatformManager.State.MATCH_TRANSITION);
m_nextStateTransitionTime = Time.time + (float)PRACTICE_WARMUP_TIME;
break;
case State.PRACTICING:
PlatformManager.TransitionToState(PlatformManager.State.PLAYING_A_LOCAL_MATCH);
m_nextStateTransitionTime = Time.time + (float)MATCH_TIME;
break;
case State.VIEWING_RESULTS_PRACTICE:
PlatformManager.TransitionToState(PlatformManager.State.MATCH_TRANSITION);
m_nextStateTransitionTime = Time.time + (float)MATCH_COOLDOWN_TIME;
m_timerText.text = "0:00.00";
break;
case State.WAITING_FOR_MATCH:
PlatformManager.TransitionToState(PlatformManager.State.MATCH_TRANSITION);
m_matchmakeButtonText.text = "Cancel";
break;
case State.WAITING_TO_SETUP_MATCH:
m_nextStateTransitionTime = Time.time + (float)MATCH_WARMUP_TIME;
break;
case State.PLAYING_MATCH:
PlatformManager.TransitionToState(PlatformManager.State.PLAYING_A_NETWORKED_MATCH);
m_nextStateTransitionTime = Time.time + (float)MATCH_TIME;
break;
case State.VIEWING_MATCH_RESULTS:
PlatformManager.TransitionToState(PlatformManager.State.MATCH_TRANSITION);
m_nextStateTransitionTime = Time.time + (float)MATCH_COOLDOWN_TIME;
m_timerText.text = "0:00.00";
CalculateMatchResults();
break;
}
}
}
private void UpdateCheckForNextTimedTransition()
{
if (m_currentState != State.NONE && Time.time >= m_nextStateTransitionTime)
{
switch (m_currentState)
{
case State.WAITING_TO_START_PRACTICE:
TransitionToState(State.PRACTICING);
break;
case State.PRACTICING:
TransitionToState(State.VIEWING_RESULTS_PRACTICE);
break;
case State.VIEWING_RESULTS_PRACTICE:
TransitionToState(State.NONE);
break;
case State.WAITING_TO_SETUP_MATCH:
TransitionToState(State.PLAYING_MATCH);
break;
case State.PLAYING_MATCH:
TransitionToState(State.VIEWING_MATCH_RESULTS);
break;
case State.VIEWING_MATCH_RESULTS:
PlatformManager.Matchmaking.EndMatch();
TransitionToState(State.NONE);
break;
case State.WAITING_FOR_MATCH:
break;
}
}
}
private void UpdateMatchTimer()
{
if (Time.time <= m_nextStateTransitionTime)
{
switch (m_currentState)
{
case State.WAITING_TO_START_PRACTICE:
case State.WAITING_TO_SETUP_MATCH:
m_timerText.text = string.Format("{0:0}", Mathf.Ceil(Time.time - MatchStartTime));
break;
case State.PRACTICING:
case State.PLAYING_MATCH:
{
float num = m_nextStateTransitionTime - Time.time;
m_timerText.text = string.Format("{0:#0}:{1:#00}.{2:00}", Mathf.Floor(num / 60f), Mathf.Floor(num) % 60f, Mathf.Floor(num * 100f) % 100f);
break;
}
case State.VIEWING_RESULTS_PRACTICE:
case State.WAITING_FOR_MATCH:
break;
}
}
}
private void SetupForIdle()
{
for (int i = 0; i < m_playerAreas.Length; i++)
{
m_playerAreas[i].SetupForPlayer<AIPlayer>("* AI *");
}
}
private void SetupForPractice()
{
m_localSlot = Random.Range(0, m_playerAreas.Length - 1);
for (int i = 0; i < m_playerAreas.Length; i++)
{
if (i == m_localSlot)
{
m_playerAreas[i].SetupForPlayer<LocalPlayer>(PlatformManager.MyOculusID);
}
else
{
m_playerAreas[i].SetupForPlayer<AIPlayer>("* AI *");
}
}
}
private Player MatchPlayerAddedCallback(int slot, User user)
{
Player result = null;
if (m_currentState == State.WAITING_TO_SETUP_MATCH && slot < m_playerAreas.Length)
{
if (user.ID == PlatformManager.MyID)
{
LocalPlayer localPlayer = m_playerAreas[slot].SetupForPlayer<LocalPlayer>(user.OculusID);
MoveCameraToMatchPosition();
result = localPlayer;
m_localSlot = slot;
}
else
{
RemotePlayer remotePlayer = m_playerAreas[slot].SetupForPlayer<RemotePlayer>(user.OculusID);
remotePlayer.User = user;
result = remotePlayer;
}
}
return result;
}
private void MoveCameraToIdlePosition()
{
BallEjector componentInChildren = m_camera.gameObject.GetComponentInChildren<BallEjector>();
if ((bool)componentInChildren)
{
componentInChildren.transform.SetParent(m_camera.transform.parent, false);
m_camera.transform.SetParent(m_idleCameraTransform, false);
}
}
private void MoveCameraToMatchPosition()
{
PlayerArea[] playerAreas = m_playerAreas;
foreach (PlayerArea playerArea in playerAreas)
{
LocalPlayer componentInChildren = playerArea.GetComponentInChildren<LocalPlayer>();
if ((bool)componentInChildren)
{
BallEjector componentInChildren2 = componentInChildren.GetComponentInChildren<BallEjector>();
m_camera.transform.SetParent(componentInChildren.transform, false);
componentInChildren2.transform.SetParent(m_camera.transform, false);
break;
}
}
DisplayAchievementFlytext();
}
public void StartPracticeMatch()
{
if (m_currentState == State.NONE)
{
TransitionToState(State.WAITING_TO_START_PRACTICE);
}
}
public void PlayOnlineOrCancel()
{
Debug.Log("Play online or Cancel");
if (m_currentState == State.NONE)
{
PlatformManager.Matchmaking.QueueForMatch();
TransitionToState(State.WAITING_FOR_MATCH);
}
else if (m_currentState == State.WAITING_FOR_MATCH)
{
PlatformManager.Matchmaking.LeaveQueue();
TransitionToState(State.NONE);
}
}
private void OnMatchFoundCallback(bool success)
{
if (success)
{
TransitionToState(State.WAITING_TO_SETUP_MATCH);
}
else
{
TransitionToState(State.NONE);
}
}
private float StartTimeOfferCallback(float remoteTime)
{
if (m_currentState == State.WAITING_TO_SETUP_MATCH && remoteTime > MatchStartTime && remoteTime - 60f < MatchStartTime)
{
Debug.Log("Moving Start time by " + (remoteTime - MatchStartTime));
MatchStartTime = remoteTime;
}
return MatchStartTime;
}
private void MostWinsLeaderboardCallback(SortedDictionary<int, LeaderboardEntry> entries)
{
foreach (Transform item in m_mostWinsLeaderboard.transform)
{
Object.Destroy(item.gameObject);
}
foreach (LeaderboardEntry value in entries.Values)
{
GameObject gameObject = Object.Instantiate(m_leaderboardEntryPrefab);
gameObject.transform.SetParent(m_mostWinsLeaderboard.transform, false);
gameObject.GetComponent<Text>().text = string.Format("{0} - {1} - {2}", value.Rank, value.User.OculusID, value.Score);
}
}
private void HighestScoreLeaderboardCallback(SortedDictionary<int, LeaderboardEntry> entries)
{
foreach (Transform item in m_highestScoresLeaderboard.transform)
{
Object.Destroy(item.gameObject);
}
foreach (LeaderboardEntry value in entries.Values)
{
GameObject gameObject = Object.Instantiate(m_leaderboardEntryPrefab);
gameObject.transform.SetParent(m_highestScoresLeaderboard.transform, false);
gameObject.GetComponent<Text>().text = string.Format("{0} - {1} - {2}", value.Rank, value.User.OculusID, value.Score);
}
}
private void CalculateMatchResults()
{
LocalPlayer localPlayer = null;
RemotePlayer remotePlayer = null;
PlayerArea[] playerAreas = m_playerAreas;
foreach (PlayerArea playerArea in playerAreas)
{
if (playerArea.Player is LocalPlayer)
{
localPlayer = playerArea.Player as LocalPlayer;
}
else if (playerArea.Player is RemotePlayer && (remotePlayer == null || playerArea.Player.Score > remotePlayer.Score))
{
remotePlayer = playerArea.Player as RemotePlayer;
}
}
if ((bool)localPlayer && (bool)remotePlayer)
{
bool flag = localPlayer.Score > remotePlayer.Score;
PlatformManager.Leaderboards.SubmitMatchScores(flag, localPlayer.Score);
if (flag)
{
PlatformManager.Achievements.RecordWinForLocalUser();
}
}
}
private void DisplayAchievementFlytext()
{
if (PlatformManager.Achievements.LikesToWin)
{
GameObject gameObject = Object.Instantiate(m_flytext);
gameObject.GetComponent<Text>().text = "Likes to Win!";
gameObject.transform.position = Vector3.up * 40f;
gameObject.transform.SetParent(m_playerAreas[m_localSlot].NameText.transform, false);
}
}
}
}