120 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			120 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
|  | using System; | ||
|  | using System.Collections.Generic; | ||
|  | using System.Threading.Tasks; | ||
|  | using Unity.Services.Authentication; | ||
|  | using Unity.Services.Matchmaker; | ||
|  | using Unity.Services.Matchmaker.Models; | ||
|  | using UnityEngine; | ||
|  | 
 | ||
|  | namespace TPSBR | ||
|  | { | ||
|  | 	/// <summary> | ||
|  | 	/// Uses Unity matchmaker to connect to Multiplay game servers | ||
|  | 	/// </summary> | ||
|  | 	public sealed class Matchmaker : SceneService | ||
|  | 	{ | ||
|  | 		// PUBLIC MEMBERS | ||
|  | 
 | ||
|  | 		public Action<MultiplayAssignment> MatchFound; | ||
|  | 		public Action<string>              MatchmakerFailed; | ||
|  | 
 | ||
|  | 		// PRIVATE MEMBERS | ||
|  | 
 | ||
|  | 		private float  _pollIntervalS = 1.0f; | ||
|  | 		private float  _pollTimerS    = 0.0f; | ||
|  | 		private string _ticketId      = string.Empty; | ||
|  | 
 | ||
|  | 		// PUBLIC METHODS | ||
|  | 
 | ||
|  | 		public async Task StartMatchmaker(string queueName) | ||
|  | 		{ | ||
|  | 			// submit a ticket to the unity matchmaker | ||
|  | 			CreateTicketResponse createTicketResponse; | ||
|  | 			try | ||
|  | 			{ | ||
|  | 				createTicketResponse = await MatchmakerService.Instance.CreateTicketAsync( | ||
|  | 					new List<Unity.Services.Matchmaker.Models.Player>() | ||
|  | 					{ | ||
|  | 						new Unity.Services.Matchmaker.Models.Player(Context.PlayerData.UnityID) | ||
|  | 					}, new CreateTicketOptions(queueName)); | ||
|  | 			} | ||
|  | 			catch (MatchmakerServiceException e) | ||
|  | 			{ | ||
|  | 				MatchmakerFailed?.Invoke($"{e.Reason}: {e.Message}"); | ||
|  | 				return; | ||
|  | 			} | ||
|  | 
 | ||
|  | 			_ticketId = createTicketResponse.Id; | ||
|  | 			Debug.Log("Ticket " + _ticketId); | ||
|  | 			_pollTimerS = 0f; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		public async Task CancelMatchmaker() | ||
|  | 		{ | ||
|  | 			if (string.IsNullOrEmpty(_ticketId)) return; | ||
|  | 
 | ||
|  | 			Debug.Log("Deleting ticket " + _ticketId); | ||
|  | 			await MatchmakerService.Instance.DeleteTicketAsync(_ticketId); | ||
|  | 			_ticketId = string.Empty; | ||
|  | 			Debug.Log("Ticket deleted"); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// SceneService ITNERFACE | ||
|  | 
 | ||
|  | 		protected override async void OnDeinitialize() | ||
|  | 		{ | ||
|  | 			await CancelMatchmaker(); | ||
|  | 			base.OnDeinitialize(); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		protected override async void OnTick() | ||
|  | 		{ | ||
|  | 			base.OnTick(); | ||
|  | 
 | ||
|  | 			if (string.IsNullOrEmpty(_ticketId)) return; | ||
|  | 
 | ||
|  | 			_pollTimerS += Time.deltaTime; | ||
|  | 			if (_pollTimerS < _pollIntervalS) return; | ||
|  | 			_pollTimerS = 0f; | ||
|  | 
 | ||
|  | 			// poll for the results | ||
|  | 			TicketStatusResponse ticketStatus = await MatchmakerService.Instance.GetTicketAsync(_ticketId); | ||
|  | 			if (ticketStatus == null) | ||
|  | 			{ | ||
|  | 				return; | ||
|  | 			} | ||
|  | 
 | ||
|  | 			MultiplayAssignment assignment = null; | ||
|  | 			if (ticketStatus.Type == typeof(MultiplayAssignment)) | ||
|  | 			{ | ||
|  | 				assignment = ticketStatus.Value as MultiplayAssignment; | ||
|  | 			} | ||
|  | 			else | ||
|  | 			{ | ||
|  | 				throw new NotImplementedException("Non-Multiplay assignment received. This sample only supports matchmaking into Multiplay-based games"); | ||
|  | 			} | ||
|  | 
 | ||
|  | 			switch (assignment.Status) | ||
|  | 			{ | ||
|  | 				case MultiplayAssignment.StatusOptions.InProgress: | ||
|  | 					break; | ||
|  | 				case MultiplayAssignment.StatusOptions.Found: | ||
|  | 					Debug.Log("Match found: " + assignment.MatchId); | ||
|  | 					_ticketId = string.Empty; | ||
|  | 					MatchFound?.Invoke(assignment); | ||
|  | 					break; | ||
|  | 				case MultiplayAssignment.StatusOptions.Failed: | ||
|  | 					_ticketId = string.Empty; | ||
|  | 					MatchmakerFailed?.Invoke("Matchmaking failed. " + assignment.Message); | ||
|  | 					break; | ||
|  | 				case MultiplayAssignment.StatusOptions.Timeout: | ||
|  | 					_ticketId = string.Empty; | ||
|  | 					MatchmakerFailed?.Invoke("Matchmaking timed out"); | ||
|  | 					break; | ||
|  | 				default: | ||
|  | 					throw new InvalidOperationException(); | ||
|  | 			} | ||
|  | 		} | ||
|  | 	} | ||
|  | } |