/** * Copyright 2019 The Knights Of Unity, created by Pawel Stolarczyk * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Collections; using System.Threading.Tasks; using DemoGame.Scripts.Gameplay.NetworkCommunication; using DemoGame.Scripts.Menus; using DemoGame.Scripts.Session; using Nakama; using UnityEngine; namespace DemoGame.Scripts.Matchmaking { /// /// Panel informing user about their matchmaking progress. /// public class MatchmakingMenu : Menu { #region Fields /// /// Sprite indicating match searching progress. /// [SerializeField] private RectTransform _rotatingSymbol = null; /// /// rotation speed. /// [SerializeField] private float _degreesPerSecond = 90; /// /// Mathmaker ticker used to leave queue or join match. /// private IMatchmakerTicket ticket; #endregion #region Mono /// /// Sets the back button on click listener. /// private void Awake() { base.SetBackButtonHandler(MenuManager.Instance.HideTopMenu); } /// /// Rotates . /// private void Update() { if (gameObject.activeInHierarchy == true) { _rotatingSymbol.Rotate(Vector3.forward, -_degreesPerSecond * Time.deltaTime); } } #endregion #region Methods /// /// Joins matchmaker queue and shows this panel. /// public async override void Show() { if (IsShown == false) { await StartMatchmakerAsync(); base.Show(); } } /// /// Leaves matchmaker queue and hides this panel. /// public async override void Hide() { if (IsShown == true) { await StopMatchmakerAsync(ticket); base.Hide(); } } /// /// Joins matchmaker queue. /// /// /// Nakama allows for joining multiple matchmakers, however for the purposes of this demo, /// we will allow only for joining a single matchmaking queue. /// private async Task StartMatchmakerAsync() { if (ticket != null) { Debug.Log("Matchmaker already started"); return false; } ISocket socket = NakamaSessionManager.Instance.Socket; // Create params object with default values MatchmakingParams param = new MatchmakingParams(); socket.OnMatchmakerMatched += OnMatchmakerMatched; // Join the matchmaker ticket = await MatchmakingManager.EnterQueueAsync(socket, param); if (ticket == null) { Debug.Log("Couldn't start matchmaker" + Environment.NewLine + "Try again later"); socket.OnMatchmakerMatched -= OnMatchmakerMatched; return false; } else { // Matchmaker queue joined return true; } } /// /// Invoked whenever matchmaker finds an opponent. /// private void OnMatchmakerMatched(object sender, IMatchmakerMatched e) { UnityMainThreadDispatcher.Instance().Enqueue(() => { ISocket socket = NakamaSessionManager.Instance.Socket; socket.OnMatchmakerMatched -= OnMatchmakerMatched; StartCoroutine(LoadBattle(e)); }); } /// /// Leaves matchmaker queue. /// private async Task StopMatchmakerAsync(IMatchmakerTicket ticket) { if (ticket == null) { Debug.Log("Couldn't stop matchmaker; matchmaking hasn't been started yet"); return false; } ISocket socket = NakamaSessionManager.Instance.Socket; bool good = await MatchmakingManager.LeaveQueueAsync(socket, ticket); this.ticket = null; socket.OnMatchmakerMatched -= OnMatchmakerMatched; return good; } /// /// Starts the game scene and joins the match /// private IEnumerator LoadBattle(IMatchmakerMatched matched) { AsyncOperation asyncLoad = UnityEngine.SceneManagement.SceneManager.LoadSceneAsync("BattleScene", UnityEngine.SceneManagement.LoadSceneMode.Additive); while (!asyncLoad.isDone) { yield return null; } UnityEngine.SceneManagement.SceneManager.UnloadSceneAsync("MainScene"); MatchCommunicationManager.Instance.JoinMatchAsync(matched); } #endregion } }