176 lines
6.0 KiB
C#
176 lines
6.0 KiB
C#
// --------------------------------------------------------------------------------------------------------------------
|
|
// <copyright file="CountdownTimer.cs" company="Exit Games GmbH">
|
|
// Part of: Photon Unity Utilities,
|
|
// </copyright>
|
|
// <summary>
|
|
// This is a basic CountdownTimer. In order to start the timer, the MasterClient can add a certain entry to the Custom Room Properties,
|
|
// which contains the property's name 'StartTime' and the actual start time describing the moment, the timer has been started.
|
|
// To have a synchronized timer, the best practice is to use PhotonNetwork.Time.
|
|
// In order to subscribe to the CountdownTimerHasExpired event you can call CountdownTimer.OnCountdownTimerHasExpired += OnCountdownTimerIsExpired;
|
|
// from Unity's OnEnable function for example. For unsubscribing simply call CountdownTimer.OnCountdownTimerHasExpired -= OnCountdownTimerIsExpired;.
|
|
// You can do this from Unity's OnDisable function for example.
|
|
// </summary>
|
|
// <author>developer@exitgames.com</author>
|
|
// --------------------------------------------------------------------------------------------------------------------
|
|
|
|
using ExitGames.Client.Photon;
|
|
using Photon.Realtime;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
namespace Photon.Pun.UtilityScripts
|
|
{
|
|
/// <summary>This is a basic, network-synced CountdownTimer based on properties.</summary>
|
|
/// <remarks>
|
|
/// In order to start the timer, the MasterClient can call SetStartTime() to set the timestamp for the start.
|
|
/// The property 'StartTime' then contains the server timestamp when the timer has been started.
|
|
///
|
|
/// In order to subscribe to the CountdownTimerHasExpired event you can call CountdownTimer.OnCountdownTimerHasExpired
|
|
/// += OnCountdownTimerIsExpired;
|
|
/// from Unity's OnEnable function for example. For unsubscribing simply call CountdownTimer.OnCountdownTimerHasExpired
|
|
/// -= OnCountdownTimerIsExpired;.
|
|
///
|
|
/// You can do this from Unity's OnEnable and OnDisable functions.
|
|
/// </remarks>
|
|
public class CountdownTimer : MonoBehaviourPunCallbacks
|
|
{
|
|
/// <summary>
|
|
/// OnCountdownTimerHasExpired delegate.
|
|
/// </summary>
|
|
public delegate void CountdownTimerHasExpired();
|
|
|
|
public const string CountdownStartTime = "StartTime";
|
|
|
|
[Header("Countdown time in seconds")]
|
|
public float Countdown = 5.0f;
|
|
|
|
private bool isTimerRunning;
|
|
|
|
private int startTime;
|
|
|
|
[Header("Reference to a Text component for visualizing the countdown")]
|
|
public Text Text;
|
|
|
|
|
|
/// <summary>
|
|
/// Called when the timer has expired.
|
|
/// </summary>
|
|
public static event CountdownTimerHasExpired OnCountdownTimerHasExpired;
|
|
|
|
|
|
public void Start()
|
|
{
|
|
if (this.Text == null) Debug.LogError("Reference to 'Text' is not set. Please set a valid reference.", this);
|
|
}
|
|
|
|
public override void OnEnable()
|
|
{
|
|
Debug.Log("OnEnable CountdownTimer");
|
|
base.OnEnable();
|
|
|
|
// the starttime may already be in the props. look it up.
|
|
Initialize();
|
|
}
|
|
|
|
public override void OnDisable()
|
|
{
|
|
base.OnDisable();
|
|
Debug.Log("OnDisable CountdownTimer");
|
|
}
|
|
|
|
|
|
public void Update()
|
|
{
|
|
if (!this.isTimerRunning) return;
|
|
|
|
float countdown = TimeRemaining();
|
|
this.Text.text = string.Format("Game starts in {0} seconds", countdown.ToString("n0"));
|
|
|
|
if (countdown > 0.0f) return;
|
|
|
|
OnTimerEnds();
|
|
}
|
|
|
|
|
|
private void OnTimerRuns()
|
|
{
|
|
this.isTimerRunning = true;
|
|
this.enabled = true;
|
|
}
|
|
|
|
private void OnTimerEnds()
|
|
{
|
|
this.isTimerRunning = false;
|
|
this.enabled = false;
|
|
|
|
Debug.Log("Emptying info text.", this.Text);
|
|
this.Text.text = string.Empty;
|
|
|
|
if (OnCountdownTimerHasExpired != null) OnCountdownTimerHasExpired();
|
|
}
|
|
|
|
|
|
public override void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged)
|
|
{
|
|
Debug.Log("CountdownTimer.OnRoomPropertiesUpdate " + propertiesThatChanged.ToStringFull());
|
|
Initialize();
|
|
}
|
|
|
|
|
|
private void Initialize()
|
|
{
|
|
int propStartTime;
|
|
if (TryGetStartTime(out propStartTime))
|
|
{
|
|
this.startTime = propStartTime;
|
|
Debug.Log("Initialize sets StartTime " + this.startTime + " server time now: " + PhotonNetwork.ServerTimestamp + " remain: " + TimeRemaining());
|
|
|
|
|
|
this.isTimerRunning = TimeRemaining() > 0;
|
|
|
|
if (this.isTimerRunning)
|
|
OnTimerRuns();
|
|
else
|
|
OnTimerEnds();
|
|
}
|
|
}
|
|
|
|
|
|
private float TimeRemaining()
|
|
{
|
|
int timer = PhotonNetwork.ServerTimestamp - this.startTime;
|
|
return this.Countdown - timer / 1000f;
|
|
}
|
|
|
|
|
|
public static bool TryGetStartTime(out int startTimestamp)
|
|
{
|
|
startTimestamp = PhotonNetwork.ServerTimestamp;
|
|
|
|
object startTimeFromProps;
|
|
if (PhotonNetwork.CurrentRoom.CustomProperties.TryGetValue(CountdownStartTime, out startTimeFromProps))
|
|
{
|
|
startTimestamp = (int)startTimeFromProps;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
public static void SetStartTime()
|
|
{
|
|
int startTime = 0;
|
|
bool wasSet = TryGetStartTime(out startTime);
|
|
|
|
Hashtable props = new Hashtable
|
|
{
|
|
{CountdownTimer.CountdownStartTime, (int)PhotonNetwork.ServerTimestamp}
|
|
};
|
|
PhotonNetwork.CurrentRoom.SetCustomProperties(props);
|
|
|
|
|
|
Debug.Log("Set Custom Props for Time: "+ props.ToStringFull() + " wasSet: "+wasSet);
|
|
}
|
|
}
|
|
} |