1114 lines
39 KiB
C#
1114 lines
39 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.EventSystems;
|
|
using UnityEngine.InputSystem;
|
|
using UnityEngine.UI;
|
|
using TMPro;
|
|
using Unity.VisualScripting;
|
|
using UnityEngine.InputSystem.Users;
|
|
//using UnityEngine.Device;
|
|
using UnityEngine.SceneManagement;
|
|
using System;
|
|
using UnityEngine.InputSystem.UI;
|
|
using UnityEngine.InputSystem.Utilities;
|
|
//using UnityEngine.Windows;
|
|
|
|
public class PlayerInfo
|
|
{
|
|
public InputDevice Device { get; set; }
|
|
public string ControlScheme { get; set; }
|
|
}
|
|
|
|
public class ModeSelection : MonoBehaviour
|
|
{
|
|
public Button primaryButton;
|
|
public Button confirmButton;
|
|
public Button firstButtonAI;
|
|
public Button confirmButtonAI;
|
|
// Game mode selection buttons and graphics
|
|
public GameObject graphic1v1;
|
|
public GameObject graphic1v1ai;
|
|
public GameObject graphic2v2;
|
|
public GameObject graphic3v3;
|
|
public CharacterSelection CharacterSelectionScript;
|
|
public CashSystemCharacterSelection cashSystemCharacterSelection;
|
|
//[SerializeField] JoinPlayer joinPlayer;
|
|
public GameObject selectionScreen;
|
|
public GameObject modeSelectionScreen;
|
|
// Player selection buttons for each game mode
|
|
public Button[] playerButtons1v1;
|
|
public Button[] playerButtons1v1ai;
|
|
public Button[] playerButtons2v2;
|
|
public Button[] playerButtons3v3;
|
|
public Sprite[] characterImages;
|
|
// Character prefabs
|
|
public GameObject[] characterPrefabs;
|
|
// Maximum number of players for each game mode
|
|
public int maxPlayers1v1 = 2;
|
|
public int maxPlayers2v2 = 4;
|
|
public int maxPlayers3v3 = 6;
|
|
// Input devices for player selection
|
|
public Image characterImage;
|
|
private string previousCharacterName = "";
|
|
public InputActionAsset existingInputAsset;
|
|
public GameObject systemEvents;
|
|
public GameObject systemEvents2;
|
|
public Button[] playerButtons;
|
|
public PlayerInput playerIncontrol;
|
|
public InputAction.CallbackContext callbackContext;
|
|
string controlScheme;
|
|
public Dictionary<string,string> selectedPlayersAI = new Dictionary<string, string>();
|
|
public Dictionary<string, PlayerInfo> selectedPlayerDevice = new Dictionary<string, PlayerInfo>();
|
|
private int joinedPlayers = 0;
|
|
private int maxPlayers = 2; // Set this to the maximum number of players you want to allow.
|
|
private bool isMobile;
|
|
public HomeSrceen homeScreen;
|
|
public Button versusScreenBackButton;
|
|
#if ENABLE_INPUT_SYSTEM
|
|
private IDisposable onAnyButtonPressSubscription;
|
|
#endif
|
|
// Prevent duplicate scene loads
|
|
private bool isLoadingGameScene = false;
|
|
// Start is called before the first frame update
|
|
void Start()
|
|
{
|
|
//initialize 1v1 graphic
|
|
graphic1v1.SetActive(false);
|
|
graphic1v1ai.SetActive(false);
|
|
graphic2v2.SetActive(false);
|
|
graphic3v3.SetActive(false);
|
|
|
|
//graphic1v1.gameObject.transform.GetChild(1).GetChild(0).gameObject.SetActive(false);
|
|
|
|
// This subscribes us to events that will fire if any button is pressed. We'll most certainly want to throw this away
|
|
// when not in a selection screen (performance intensive)!
|
|
|
|
#if ENABLE_INPUT_SYSTEM
|
|
EnableJoinListener();
|
|
#endif
|
|
}
|
|
#if ENABLE_INPUT_SYSTEM
|
|
private void EnableJoinListener()
|
|
{
|
|
if (!Application.isPlaying)
|
|
return;
|
|
|
|
if (onAnyButtonPressSubscription != null)
|
|
return;
|
|
|
|
Action<InputControl> handler = control =>
|
|
{
|
|
if (control == null)
|
|
return;
|
|
HandleDeviceJoin(control.device);
|
|
};
|
|
|
|
onAnyButtonPressSubscription = InputSystem.onAnyButtonPress.Call(handler);
|
|
}
|
|
|
|
private void DisableJoinListener()
|
|
{
|
|
if (!Application.isPlaying)
|
|
return;
|
|
|
|
if (onAnyButtonPressSubscription != null)
|
|
{
|
|
onAnyButtonPressSubscription.Dispose();
|
|
onAnyButtonPressSubscription = null;
|
|
}
|
|
}
|
|
|
|
private void HandleDeviceJoin(InputDevice device)
|
|
{
|
|
if (device == null)
|
|
return;
|
|
|
|
if (joinedPlayers >= maxPlayers)
|
|
{
|
|
DisableJoinListener();
|
|
return;
|
|
}
|
|
|
|
if (!isActiveAndEnabled || modeSelectionScreen == null || !modeSelectionScreen.activeSelf)
|
|
return;
|
|
|
|
AddPlayer(device);
|
|
|
|
if (joinedPlayers >= maxPlayers)
|
|
{
|
|
DisableJoinListener();
|
|
}
|
|
}
|
|
#endif
|
|
|
|
private void OnEnable()
|
|
{
|
|
#if ENABLE_INPUT_SYSTEM
|
|
if (!Application.isPlaying)
|
|
return;
|
|
EnableJoinListener();
|
|
#endif
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
#if ENABLE_INPUT_SYSTEM
|
|
if (!Application.isPlaying)
|
|
return;
|
|
DisableJoinListener();
|
|
#endif
|
|
}
|
|
|
|
|
|
public void SelectFirstButton()
|
|
{
|
|
primaryButton.Select();
|
|
}
|
|
public void SelectFirstAIButton()
|
|
{
|
|
firstButtonAI.Select();
|
|
}
|
|
void AddPlayer(InputDevice device)
|
|
{
|
|
//return if the gameobject is not modeselection screen
|
|
if (!gameObject.activeSelf || !graphic1v1.gameObject.activeSelf || EventSystem.current.currentSelectedGameObject.name == "BackButton")
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (graphic1v1.gameObject.activeSelf || graphic2v2.gameObject.activeSelf || graphic3v3.gameObject.activeSelf)
|
|
{
|
|
// Avoid running if the device is already paired to a player
|
|
/*if (PlayerInput.all.Count > 0)
|
|
{*/
|
|
foreach (var player in PlayerInput.all)
|
|
{
|
|
//InputUser inputUser = player.user;
|
|
foreach (var playerDevice in player.devices)
|
|
{
|
|
if ((playerDevice.name.Contains("Keyboard") || playerDevice.name.Contains("Mouse")) && (device.name.Contains("Keyboard") || device.name.Contains("Mouse")))
|
|
{
|
|
/*print(device.name);
|
|
print("keyboard/mouse already added returned");*/
|
|
return;
|
|
}
|
|
if (device.name == playerDevice.name)
|
|
{
|
|
/*print(device.name);
|
|
print("device already added");*/
|
|
return;
|
|
}
|
|
/*else if ((device.name.Contains("Keyboard") || device.name.Contains("Mouse")) && (playerDevice.name.Contains("Keyboard") || playerDevice.name.Contains("Mouse")))
|
|
return;*/
|
|
}
|
|
}
|
|
//}
|
|
|
|
// Don't execute if not a gamepad or joystick or keyboard&mouse
|
|
if (!device.name.Contains("Controller") && !device.name.Contains("Joystick") && !device.name.Contains("Gamepad") && !device.name.Contains("Keyboard") && !device.name.Contains("Mouse"))
|
|
{
|
|
print("if returned");
|
|
return;
|
|
}
|
|
|
|
//print("Adding player");
|
|
//var playerNumberToAdd = PlayerInput.all.Count + 1;
|
|
|
|
if (device.name.Contains("Controller") || device.name.Contains("Gamepad"))
|
|
controlScheme = "Gamepad";
|
|
else if (device.name.Contains("Joystick"))
|
|
controlScheme = "Joystick";
|
|
else if (device.name.Contains("Keyboard") || device.name.Contains("Mouse"))
|
|
controlScheme = "Keyboard&Mouse";
|
|
|
|
foreach (var button in playerButtons1v1)
|
|
{
|
|
//print (button.name);
|
|
if (button.gameObject.GetComponent<PlayerInput>() == null)
|
|
{
|
|
PlayerInput buttonInput = button.gameObject.AddComponent<PlayerInput>();
|
|
buttonInput.actions = existingInputAsset;
|
|
buttonInput.defaultControlScheme = controlScheme;
|
|
buttonInput.neverAutoSwitchControlSchemes = true;
|
|
buttonInput.notificationBehavior = PlayerNotifications.InvokeUnityEvents;
|
|
|
|
buttonInput.uiInputModule = systemEvents.GetComponent<InputSystemUIInputModule>();
|
|
buttonInput.uiInputModule.enabled = true;
|
|
//buttonInput.uiInputModule.ActivateModule();
|
|
//buttonInput.uiInputModule.actionsAsset = existingInputAsset;
|
|
InputUser myUser = buttonInput.user;
|
|
//InputUser user = InputUser.PerformPairingWithDevice(device);
|
|
InputUser.PerformPairingWithDevice(device, myUser);
|
|
buttonInput.SwitchCurrentControlScheme(controlScheme, device);
|
|
buttonInput.defaultActionMap = "UI";
|
|
buttonInput.SwitchCurrentActionMap("UI");
|
|
buttonInput.currentActionMap["Submit"].performed += OnSubmit;
|
|
//buttonInput.gameObject.GetComponentInChildren<TextMeshProUGUI>().text = buttonInput.currentControlScheme.ToString();//this was about displaying the attached device to keyboard
|
|
buttonInput.camera = GameObject.Find("Main Camera").GetComponent<Camera>();
|
|
buttonInput.enabled = true;
|
|
buttonInput.ActivateInput();
|
|
joinedPlayers++;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
public void On1v1aiClick()
|
|
{
|
|
foreach (var button in playerButtons1v1ai)
|
|
{
|
|
if (EventSystem.current.currentSelectedGameObject == button.gameObject)
|
|
{
|
|
//button.gameObject.GetComponent<ButtonClickSound>().PlayClickSound();
|
|
PlayerPrefs.SetString("selectedbuttonpvp", button.name);
|
|
//print("sent button" + PlayerPrefs.GetString("selectedbuttonpvp"));
|
|
modeSelectionScreen.SetActive(false);
|
|
CharacterSelectionScript.selectCharacterButton.onClick.AddListener(onSelectionScreenSelectClick);
|
|
CharacterSelectionScript.backButton.onClick.AddListener(onSelectionScreenBackClick);
|
|
selectionScreen.SetActive(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called when the Confirm button is clicked in 3v3 mode (Cash System)
|
|
/// Wire this to the Confirm button's OnClick in the 3v3 graphic
|
|
/// </summary>
|
|
public void OnConfirmButton3v3()
|
|
{
|
|
Debug.Log("[ModeSelection] OnConfirmButton3v3 clicked");
|
|
|
|
// Check if we're in Cash System mode
|
|
if (SelectionOptions.Instance != null && SelectionOptions.Instance.isCashSystemSelected)
|
|
{
|
|
// Delegate to CashSystemCharacterSelection
|
|
if (cashSystemCharacterSelection != null)
|
|
{
|
|
cashSystemCharacterSelection.OnConfirmClicked();
|
|
}
|
|
else
|
|
{
|
|
// Fallback - get from graphic3v3
|
|
CashSystemCharacterSelection cashSelection = graphic3v3.GetComponent<CashSystemCharacterSelection>();
|
|
if (cashSelection != null)
|
|
{
|
|
cashSelection.OnConfirmClicked();
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError("[ModeSelection] CashSystemCharacterSelection not found!");
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Not in Cash System mode - use the original AI confirm handler
|
|
Debug.Log("[ModeSelection] Not in Cash System mode, calling OnconfirmButtonAIClick");
|
|
OnconfirmButtonAIClick();
|
|
}
|
|
}
|
|
|
|
public void OnconfirmButtonAIClick()
|
|
{
|
|
if (selectedPlayersAI.Count != 2 || SelectionOptions.Instance == null)
|
|
{
|
|
Debug.LogWarning("Not enough players selected or SelectionOptions not initialized");
|
|
return;
|
|
}
|
|
|
|
// Guard against duplicate loads
|
|
if (isLoadingGameScene || SceneLoader.IsLoading)
|
|
return;
|
|
|
|
// Disable input action and button to prevent double click
|
|
#if ENABLE_INPUT_SYSTEM
|
|
DisableJoinListener();
|
|
#endif
|
|
if (confirmButtonAI != null) confirmButtonAI.interactable = false;
|
|
|
|
// Check platform
|
|
isMobile = UnityEngine.Application.platform == RuntimePlatform.Android ||
|
|
UnityEngine.Application.platform == RuntimePlatform.IPhonePlayer;
|
|
|
|
|
|
if (!isMobile)
|
|
{
|
|
bool isKeyboardInput = Keyboard.current != null && Keyboard.current.enterKey.isPressed;
|
|
bool isMouseClick = Mouse.current != null && Mouse.current.leftButton.isPressed;
|
|
|
|
if (isKeyboardInput || isMouseClick)
|
|
{
|
|
SetupAIGame("Keyboard&Mouse", InputSystem.GetDevice<Keyboard>());
|
|
}
|
|
else
|
|
{
|
|
SetupAIGame("Gamepad", InputSystem.GetDevice<Gamepad>());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SetupAIGame("Gamepad", InputSystem.GetDevice<Gamepad>());
|
|
}
|
|
}
|
|
|
|
private void SetupAIGame(string controlScheme, InputDevice device)
|
|
{
|
|
SelectionOptions.Instance.selectedPlayersAI = selectedPlayersAI;
|
|
SelectionOptions.Instance.activeDeviceforAI = device;
|
|
SelectionOptions.Instance.controlSchemeforAI = controlScheme;
|
|
|
|
//GameManager.Instance.ShowLoadingUI();
|
|
//GameManager.Instance.gameObject.GetComponent<LoadingScreen>()?.UI_to_show_AfterLoading(1, "Game");
|
|
//GameManager.Instance.gameObject.GetComponent<LoadingScreen>()?.InitializeLoading();
|
|
|
|
// Start the loading sequence
|
|
StartCoroutine(LoadGameWithUI());
|
|
}
|
|
|
|
private IEnumerator LoadGameWithUI()
|
|
{
|
|
// Guard against multiple loads
|
|
if (isLoadingGameScene || SceneLoader.IsLoading)
|
|
yield break;
|
|
isLoadingGameScene = true;
|
|
|
|
// Show loading UI
|
|
GameManager.Instance.ShowLoadingUI();
|
|
|
|
// Load Game scene (Editor: built-in, Android: custom AssetBundle)
|
|
// SceneLoader now handles everything automatically!
|
|
var asyncLoad = SceneLoader.LoadSceneAsyncOnce("Movement Testing", LoadSceneMode.Single, allowSceneActivation: true);
|
|
if (asyncLoad == null)
|
|
{
|
|
isLoadingGameScene = false;
|
|
GameManager.Instance.HideLoadingUI();
|
|
yield break;
|
|
}
|
|
|
|
// IMPORTANT: Run the wait loop on GameManager so it survives scene changes
|
|
// This coroutine (running on ModeSelection) will be destroyed when MenuScene unloads!
|
|
GameManager.Instance.StartCoroutine(WaitForGameSceneLoad(asyncLoad));
|
|
|
|
// This coroutine will be destroyed here when the scene changes, which is fine
|
|
// because WaitForGameSceneLoad is running on GameManager (DontDestroyOnLoad)
|
|
}
|
|
|
|
private static IEnumerator WaitForGameSceneLoad(SceneLoader.SceneLoadHandle asyncLoad)
|
|
{
|
|
// Wait until scene is fully loaded
|
|
while (asyncLoad != null && !asyncLoad.isDone)
|
|
{
|
|
yield return null;
|
|
}
|
|
|
|
Debug.Log("[ModeSelection] Game scene loaded, hiding loading UI...");
|
|
if (GameManager.Instance != null)
|
|
{
|
|
GameManager.Instance.HideLoadingUI();
|
|
}
|
|
}
|
|
|
|
string GetKeyFromValue(Dictionary<string, string> dictionary, string value)
|
|
{
|
|
foreach (KeyValuePair<string, string> kvp in dictionary)
|
|
{
|
|
if (kvp.Value == value)
|
|
{
|
|
return kvp.Key;
|
|
}
|
|
}
|
|
return null; // Return null if the value is not found
|
|
}
|
|
string GetNameFromValue(Dictionary<string, PlayerInfo> dictionary, InputDevice device)
|
|
{
|
|
foreach (KeyValuePair<string, PlayerInfo> kvp in dictionary)
|
|
{
|
|
if (kvp.Value.Device == device)
|
|
{
|
|
return kvp.Key;
|
|
}
|
|
}
|
|
return null; // Return null if the value is not found
|
|
}
|
|
|
|
InputDevice GetDeviceFromValue(Dictionary<string, PlayerInfo> dictionary, InputDevice device)
|
|
{
|
|
foreach (KeyValuePair<string, PlayerInfo> kvp in dictionary)
|
|
{
|
|
if (kvp.Value.Device == device)
|
|
{
|
|
return kvp.Value.Device;
|
|
}
|
|
}
|
|
return null; // Return null if the value is not found
|
|
}
|
|
|
|
//this will help selecting character while in ai mode
|
|
public void onSelectionScreenSelectClick()
|
|
{
|
|
string selectedCharacterName = PlayerPrefs.GetString("selectedcharactername", "");
|
|
if (selectedCharacterName != "")
|
|
{
|
|
// Check if in Cash System mode
|
|
if (SelectionOptions.Instance != null && SelectionOptions.Instance.isCashSystemSelected)
|
|
{
|
|
HandleCashSystemCharacterSelection(selectedCharacterName);
|
|
return;
|
|
}
|
|
|
|
string selectedbuttonpvp = PlayerPrefs.GetString("selectedbuttonpvp");
|
|
|
|
if (!string.IsNullOrEmpty(selectedbuttonpvp))
|
|
{
|
|
// Remove the previous character selection if it exists
|
|
if (selectedbuttonpvp == "1.1ai" && selectedPlayersAI.ContainsValue("AI"))
|
|
{
|
|
print("removed characters " + GetKeyFromValue(selectedPlayersAI, "AI"));
|
|
selectedPlayersAI.Remove(GetKeyFromValue(selectedPlayersAI, "AI"));
|
|
}
|
|
else if(selectedbuttonpvp == "1.2ai" && selectedPlayersAI.ContainsValue("PLAYER")){
|
|
print("removed characters " + GetKeyFromValue(selectedPlayersAI, "PLAYER"));
|
|
selectedPlayersAI.Remove(GetKeyFromValue(selectedPlayersAI, "PLAYER"));
|
|
}
|
|
|
|
// Add the new character selection
|
|
if (selectedbuttonpvp == "1.1ai")
|
|
{
|
|
selectedPlayersAI.Add(selectedCharacterName, "AI");
|
|
}
|
|
else if (selectedbuttonpvp == "1.2ai")
|
|
{
|
|
selectedPlayersAI.Add(selectedCharacterName, "PLAYER");
|
|
}
|
|
|
|
UpdatePlayerSelectButtons(selectedCharacterName); // Pass the selected character name
|
|
PlayerPrefs.SetString("selectedcharactername", "");
|
|
|
|
// Deactivate the current screen
|
|
selectionScreen.SetActive(false);
|
|
// Activate the ModeScreen
|
|
CharacterSelectionScript.modeScreen.SetActive(true);
|
|
|
|
// Update the selected button
|
|
foreach (var button in playerButtons1v1ai)
|
|
{
|
|
if (button.name == selectedbuttonpvp)
|
|
{
|
|
GameObject buttonCurrent = button.gameObject;
|
|
print("button current" + buttonCurrent.name);
|
|
buttonCurrent.GetComponent<Button>().Select();
|
|
PlayerPrefs.SetString("selectedbuttonpvp", "");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
CharacterSelectionScript.selectCharacterButton.onClick.RemoveListener(onSelectionScreenSelectClick);
|
|
if (confirmButtonAI.onClick.GetPersistentEventCount() < 1)
|
|
{
|
|
confirmButtonAI.onClick.AddListener(OnconfirmButtonAIClick);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handle character selection for Cash System mode
|
|
/// </summary>
|
|
private void HandleCashSystemCharacterSelection(string selectedCharacterName)
|
|
{
|
|
Debug.Log($"[ModeSelection] Cash System character selected: {selectedCharacterName}");
|
|
|
|
// Clear the saved character name
|
|
PlayerPrefs.SetString("selectedcharactername", "");
|
|
|
|
// Deactivate the selection screen
|
|
selectionScreen.SetActive(false);
|
|
|
|
// Call the CashSystemCharacterSelection to handle the selection
|
|
if (cashSystemCharacterSelection != null)
|
|
{
|
|
cashSystemCharacterSelection.OnCharacterSelected(selectedCharacterName);
|
|
}
|
|
else
|
|
{
|
|
// Fallback - get it from the 3v3 graphic
|
|
CashSystemCharacterSelection cashSelection = graphic3v3.GetComponent<CashSystemCharacterSelection>();
|
|
if (cashSelection != null)
|
|
{
|
|
cashSelection.OnCharacterSelected(selectedCharacterName);
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError("[ModeSelection] CashSystemCharacterSelection not found!");
|
|
}
|
|
}
|
|
|
|
// Show mode selection screen again
|
|
if (modeSelectionScreen != null)
|
|
{
|
|
modeSelectionScreen.SetActive(true);
|
|
}
|
|
|
|
// Activate the 3v3 graphic/mode screen
|
|
graphic3v3.SetActive(true);
|
|
|
|
// Remove listener
|
|
CharacterSelectionScript.selectCharacterButton.onClick.RemoveListener(onSelectionScreenSelectClick);
|
|
}
|
|
|
|
public void onSelectionScreenBackClick()
|
|
{
|
|
|
|
PlayerPrefs.SetString("selectedcharactername", "");
|
|
string selectedbuttonpvp = PlayerPrefs.GetString("selectedbuttonpvp");
|
|
// Deactivate the current screen
|
|
selectionScreen.SetActive(false);
|
|
// Activate the ModeScreen
|
|
modeSelectionScreen.SetActive(true);
|
|
GameObject buttonCurrent = gameObject;
|
|
//primaryButton.Select();
|
|
foreach (var button in playerButtons1v1)
|
|
{
|
|
if (button.name == selectedbuttonpvp)
|
|
{
|
|
//Destroy(button.GetComponent<PlayerInput>());
|
|
buttonCurrent = button.gameObject;
|
|
buttonCurrent.GetComponent<Button>().Select();
|
|
PlayerPrefs.SetString("selectedbuttonpvp", "");
|
|
}
|
|
}
|
|
CharacterSelectionScript.selectCharacterButton.onClick.RemoveListener(onSelectionScreenBackClick);
|
|
if (SelectionOptions.Instance.isAISelected)
|
|
{
|
|
print("ai button selected");
|
|
firstButtonAI.Select();
|
|
}
|
|
else
|
|
{
|
|
primaryButton.Select();
|
|
}
|
|
|
|
if (confirmButtonAI.onClick.GetPersistentEventCount() < 1)
|
|
confirmButtonAI.onClick.AddListener(OnconfirmButtonAIClick);
|
|
}
|
|
public void ModeBackButton()
|
|
{
|
|
#if ENABLE_INPUT_SYSTEM
|
|
DisableJoinListener();
|
|
#endif
|
|
modeSelectionScreen.SetActive(false);
|
|
homeScreen.setModeScreen.SetActive(true);
|
|
}
|
|
public void OnSubmit(InputAction.CallbackContext context)
|
|
{
|
|
// Early exit if core components are missing
|
|
if (!this || !EventSystem.current || !EventSystem.current.currentSelectedGameObject || !GameManager.Instance?.gameObject)
|
|
{
|
|
#if ENABLE_INPUT_SYSTEM
|
|
DisableJoinListener();
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
GameObject currentButton = EventSystem.current.currentSelectedGameObject;
|
|
if (currentButton == null) return;
|
|
|
|
if (currentButton.name == "Confirm")
|
|
{
|
|
// Guard against duplicate loads
|
|
if (isLoadingGameScene || SceneLoader.IsLoading)
|
|
return;
|
|
|
|
if (currentButton.GetComponent<PlayerInput>() == null)
|
|
{
|
|
foreach (var player in PlayerInput.all)
|
|
{
|
|
if (player != null && player.user != null && context.control != null)
|
|
{
|
|
player.user.UnpairDevice(context.control.device);
|
|
}
|
|
}
|
|
|
|
if (SelectionOptions.Instance != null)
|
|
{
|
|
SelectionOptions.Instance.selectedPlayerDevice = selectedPlayerDevice;
|
|
if (confirmButton != null) confirmButton.interactable = false; // prevent double submit
|
|
StartCoroutine(LoadGameWithUI());
|
|
}
|
|
|
|
#if ENABLE_INPUT_SYSTEM
|
|
DisableJoinListener();
|
|
#endif
|
|
}
|
|
return;
|
|
}
|
|
|
|
// ...existing code for other branches...
|
|
}
|
|
|
|
|
|
private string DetermineControlScheme(InputDevice device)
|
|
{
|
|
if (device.name.Contains("Controller") || device.name.Contains("Gamepad"))
|
|
return "Gamepad";
|
|
if (device.name.Contains("Joystick"))
|
|
return "Joystick";
|
|
return "Keyboard&Mouse";
|
|
}
|
|
|
|
private void TransitionToModeScreen(InputAction.CallbackContext context, string controlScheme)
|
|
{
|
|
selectionScreen.SetActive(false);
|
|
CharacterSelectionScript.modeScreen.SetActive(true);
|
|
|
|
if (CharacterSelectionScript.selectCharacterButton != null)
|
|
{
|
|
var playerInput = CharacterSelectionScript.selectCharacterButton.gameObject.GetComponent<PlayerInput>();
|
|
if (playerInput != null)
|
|
{
|
|
playerInput.uiInputModule.enabled = false;
|
|
playerInput.DeactivateInput();
|
|
Destroy(playerInput);
|
|
}
|
|
}
|
|
|
|
foreach (var button1 in playerButtons1v1)
|
|
{
|
|
var old = systemEvents?.GetComponent<InputSystemUIInputModule>();
|
|
if (old != null)
|
|
{
|
|
old.enabled = true;
|
|
}
|
|
}
|
|
|
|
UpdateButtonSelection(context);
|
|
}
|
|
|
|
private void HandleBackButton(InputAction.CallbackContext context)
|
|
{
|
|
PlayerPrefs.SetString("selectedcharactername", "");
|
|
controlScheme = DetermineControlScheme(context.control.device);
|
|
string selectedbuttonpvp = PlayerPrefs.GetString("selectedbuttonpvp");
|
|
|
|
selectionScreen.SetActive(false);
|
|
modeSelectionScreen.SetActive(true);
|
|
|
|
CleanupCharacterSelection();
|
|
ResetUIInputModule();
|
|
UpdateButtonSelectionForBack(selectedbuttonpvp);
|
|
|
|
#if ENABLE_INPUT_SYSTEM
|
|
DisableJoinListener();
|
|
#endif
|
|
}
|
|
|
|
private void HandleModeSelectionBackButton()
|
|
{
|
|
#if ENABLE_INPUT_SYSTEM
|
|
DisableJoinListener();
|
|
#endif
|
|
modeSelectionScreen.SetActive(false);
|
|
homeScreen.setModeScreen.SetActive(true);
|
|
|
|
CleanupPlayerInputs();
|
|
}
|
|
|
|
private void HandlePlayerButtonSelection(InputAction.CallbackContext context)
|
|
{
|
|
if (playerButtons1v1 == null) return;
|
|
|
|
foreach (var button in playerButtons1v1)
|
|
{
|
|
if (button == null || !button.gameObject) continue;
|
|
|
|
if (EventSystem.current?.currentSelectedGameObject == button.gameObject)
|
|
{
|
|
var playerInput = button.GetComponent<PlayerInput>();
|
|
if (playerInput != null && playerInput.devices.Count > 0 && playerInput.devices[0] == context.control.device)
|
|
{
|
|
ProcessButtonSelection(button, playerInput, context);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ProcessButtonSelection(Button button, PlayerInput playerInput, InputAction.CallbackContext context)
|
|
{
|
|
try
|
|
{
|
|
// Validate all required components exist
|
|
if (!ValidateComponents(button, playerInput))
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Store current player input
|
|
playerIncontrol = playerInput;
|
|
|
|
// Save button selection
|
|
if (button != null)
|
|
{
|
|
PlayerPrefs.SetString("selectedbuttonpvp", button.name);
|
|
}
|
|
|
|
// Handle screen transitions
|
|
if (modeSelectionScreen != null && selectionScreen != null)
|
|
{
|
|
modeSelectionScreen.SetActive(false);
|
|
selectionScreen.SetActive(true);
|
|
}
|
|
|
|
// Setup input for character selection
|
|
SetupCharacterSelectionInput(context);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Debug.LogError($"Error in ProcessButtonSelection: {e.Message}\nStack Trace: {e.StackTrace}");
|
|
}
|
|
}
|
|
|
|
private bool ValidateComponents(Button button, PlayerInput playerInput)
|
|
{
|
|
if (button == null || playerInput == null || !button.gameObject || !modeSelectionScreen || !selectionScreen)
|
|
{
|
|
Debug.LogWarning("One or more required components are missing");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
|
|
private void SetupCharacterSelectionInput(InputAction.CallbackContext context)
|
|
{
|
|
if (CharacterSelectionScript == null || CharacterSelectionScript.selectCharacterButton == null)
|
|
{
|
|
Debug.LogWarning("Character selection components not properly initialized");
|
|
return;
|
|
}
|
|
|
|
var existingInput = CharacterSelectionScript.selectCharacterButton.gameObject.GetComponent<PlayerInput>();
|
|
if (existingInput == null)
|
|
{
|
|
DisableExistingUIInputModules();
|
|
CreateNewPlayerInput(context);
|
|
}
|
|
}
|
|
|
|
|
|
private void CreateNewPlayerInput(InputAction.CallbackContext context)
|
|
{
|
|
var buttonInput = CharacterSelectionScript.selectCharacterButton.gameObject.AddComponent<PlayerInput>();
|
|
if (buttonInput != null)
|
|
{
|
|
ConfigurePlayerInput(buttonInput, context);
|
|
}
|
|
}
|
|
|
|
private void ConfigurePlayerInput(PlayerInput buttonInput, InputAction.CallbackContext context)
|
|
{
|
|
// Get the active device
|
|
InputDevice device = GetActiveDevice();
|
|
if (device == null) return;
|
|
|
|
// Basic setup
|
|
buttonInput.actions = existingInputAsset;
|
|
buttonInput.defaultControlScheme = DetermineControlScheme(device);
|
|
buttonInput.neverAutoSwitchControlSchemes = true;
|
|
buttonInput.notificationBehavior = PlayerNotifications.InvokeUnityEvents;
|
|
|
|
// UI Module setup
|
|
if (systemEvents != null)
|
|
{
|
|
var uiModule = systemEvents.GetComponent<InputSystemUIInputModule>();
|
|
if (uiModule != null)
|
|
{
|
|
buttonInput.uiInputModule = uiModule;
|
|
uiModule.enabled = true;
|
|
}
|
|
}
|
|
|
|
// Device pairing
|
|
InputUser.PerformPairingWithDevice(device, buttonInput.user);
|
|
buttonInput.SwitchCurrentControlScheme(buttonInput.defaultControlScheme, device);
|
|
|
|
// Action map configuration
|
|
buttonInput.defaultActionMap = "UI";
|
|
buttonInput.SwitchCurrentActionMap("UI");
|
|
|
|
var submitAction = buttonInput.actions.FindAction("UI/Submit");
|
|
if (submitAction != null)
|
|
{
|
|
submitAction.performed += OnSubmit;
|
|
}
|
|
|
|
buttonInput.enabled = true;
|
|
}
|
|
|
|
private InputDevice GetActiveDevice()
|
|
{
|
|
if (Gamepad.current != null) return Gamepad.current;
|
|
if (Keyboard.current != null) return Keyboard.current;
|
|
if (Mouse.current != null) return Mouse.current;
|
|
|
|
return null;
|
|
}
|
|
|
|
|
|
|
|
private void UpdateButtonSelection(InputAction.CallbackContext context)
|
|
{
|
|
string selectedbuttonpvp = PlayerPrefs.GetString("selectedbuttonpvp");
|
|
foreach (var button in playerButtons1v1)
|
|
{
|
|
if (button.name == selectedbuttonpvp)
|
|
{
|
|
button.GetComponent<Button>().Select();
|
|
PlayerPrefs.SetString("selectedbuttonpvp", "");
|
|
}
|
|
}
|
|
}
|
|
|
|
private void CleanupCharacterSelection()
|
|
{
|
|
if (CharacterSelectionScript.selectCharacterButton != null)
|
|
{
|
|
var playerInput = CharacterSelectionScript.selectCharacterButton.gameObject.GetComponent<PlayerInput>();
|
|
if (playerInput != null)
|
|
{
|
|
playerInput.uiInputModule.enabled = false;
|
|
playerInput.DeactivateInput();
|
|
Destroy(playerInput);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ResetUIInputModule()
|
|
{
|
|
foreach (var button1 in playerButtons1v1)
|
|
{
|
|
var old = systemEvents?.GetComponent<InputSystemUIInputModule>();
|
|
if (old != null)
|
|
{
|
|
old.enabled = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void UpdateButtonSelectionForBack(string selectedbuttonpvp)
|
|
{
|
|
foreach (var button in playerButtons1v1)
|
|
{
|
|
if (button.name == selectedbuttonpvp)
|
|
{
|
|
button.GetComponent<Button>().Select();
|
|
PlayerPrefs.SetString("selectedbuttonpvp", "");
|
|
}
|
|
}
|
|
}
|
|
|
|
private void CleanupPlayerInputs()
|
|
{
|
|
foreach (var button1 in playerButtons1v1)
|
|
{
|
|
var old = systemEvents?.GetComponent<InputSystemUIInputModule>();
|
|
if (old != null)
|
|
{
|
|
old.enabled = false;
|
|
}
|
|
var playerInput = button1.GetComponent<PlayerInput>();
|
|
if (playerInput != null)
|
|
{
|
|
Destroy(playerInput);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void DisableExistingUIInputModules()
|
|
{
|
|
foreach (var button1 in playerButtons1v1)
|
|
{
|
|
var old = systemEvents?.GetComponent<InputSystemUIInputModule>();
|
|
if (old != null)
|
|
{
|
|
old.enabled = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public IEnumerator LoadingNextLevel(int levelToLoad)
|
|
{
|
|
yield return new WaitForSeconds(0.5f);
|
|
AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(levelToLoad);
|
|
|
|
// Wait until the asynchronous scene fully loads
|
|
while (!asyncLoad.isDone)
|
|
{
|
|
yield return null;
|
|
}
|
|
}
|
|
// Update is called once per frame
|
|
// OPTIMIZATION: Cache PlayerPrefs value instead of reading every frame
|
|
private bool wasScreenActive = false;
|
|
|
|
void Update()
|
|
{
|
|
bool isScreenActive = modeSelectionScreen.gameObject.activeSelf;
|
|
|
|
// Only check when screen first becomes active, not every frame
|
|
if (isScreenActive && !wasScreenActive)
|
|
{
|
|
// Screen just became active, check for character update
|
|
string storedCharacterName = PlayerPrefs.GetString("selectedcharactername");
|
|
|
|
if (!string.IsNullOrEmpty(storedCharacterName) && storedCharacterName != previousCharacterName)
|
|
{
|
|
UpdatePlayerSelectButtons(storedCharacterName);
|
|
previousCharacterName = storedCharacterName;
|
|
}
|
|
}
|
|
|
|
wasScreenActive = isScreenActive;
|
|
}
|
|
|
|
public void ActivateGameMode(int mode)
|
|
{
|
|
// Activate the corresponding game mode graphic
|
|
switch (mode)
|
|
{
|
|
case 1:
|
|
|
|
graphic1v1.SetActive(true);
|
|
graphic2v2.SetActive(false);
|
|
graphic3v3.SetActive(false);
|
|
/*button1v1.gameObject.transform.GetChild(1).gameObject.SetActive(true);
|
|
button2v2.gameObject.transform.GetChild(1).gameObject.SetActive(false);
|
|
button3v3.gameObject.transform.GetChild(1).gameObject.SetActive(false);*/
|
|
|
|
break;
|
|
case 2:
|
|
graphic1v1.SetActive(false);
|
|
graphic2v2.SetActive(true);
|
|
graphic3v3.SetActive(false);
|
|
/*button1v1.gameObject.transform.GetChild(1).gameObject.SetActive(false);
|
|
button2v2.gameObject.transform.GetChild(1).gameObject.SetActive(true);
|
|
button3v3.gameObject.transform.GetChild(1).gameObject.SetActive(false);*/
|
|
|
|
break;
|
|
case 3:
|
|
graphic1v1.SetActive(false);
|
|
graphic3v3.SetActive(true);
|
|
graphic2v2.SetActive(false);
|
|
/*button1v1.gameObject.transform.GetChild(1).gameObject.SetActive(false);
|
|
button2v2.gameObject.transform.GetChild(1).gameObject.SetActive(false);
|
|
button3v3.gameObject.transform.GetChild(1).gameObject.SetActive(true);*/
|
|
|
|
break;
|
|
}
|
|
}
|
|
public void UpdatePlayerSelectButtons(string characterName)
|
|
{
|
|
(Sprite characterSprite, Sprite characterSpriteBg) = GetCharacterSprite(characterName);
|
|
// Update the player select buttons with the character sprite
|
|
foreach (Button playerButton in playerButtons1v1)
|
|
{
|
|
string selectedbuttonpvp = PlayerPrefs.GetString("selectedbuttonpvp");
|
|
if (selectedbuttonpvp == playerButton.name)
|
|
{
|
|
// Update the player select buttons with the character sprite
|
|
Image buttonImageBg = playerButton.GetComponent<Image>();
|
|
//1.2 is the left button, 1.1 is the right button
|
|
if (buttonImageBg != null && playerButton.name == "1.2")
|
|
{
|
|
buttonImageBg.sprite = characterSprite;
|
|
}
|
|
if (buttonImageBg != null && playerButton.name == "1.1")
|
|
{
|
|
buttonImageBg.sprite = characterSpriteBg;
|
|
}
|
|
}
|
|
}
|
|
foreach (Button playerButton in playerButtons1v1ai)
|
|
{
|
|
string selectedbuttonpvp = PlayerPrefs.GetString("selectedbuttonpvp");
|
|
if (selectedbuttonpvp == playerButton.name)
|
|
{
|
|
// Update the player select buttons with the character sprite
|
|
Image buttonImageBg = playerButton.GetComponent<Image>();
|
|
//1.ai is left button, 1.1ai is the right button
|
|
if (buttonImageBg != null && playerButton.name == "1.2ai")
|
|
{
|
|
buttonImageBg.sprite = characterSprite;
|
|
}
|
|
if (buttonImageBg != null && playerButton.name == "1.1ai")
|
|
{
|
|
buttonImageBg.sprite = characterSpriteBg;
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach (Button playerButton in playerButtons2v2)
|
|
{
|
|
string selectedbuttonpvp = PlayerPrefs.GetString("selectedbuttonpvp");
|
|
if (selectedbuttonpvp == playerButton.name)
|
|
{
|
|
// Update the player select buttons with the character sprite
|
|
PlayerPrefs.SetString("selectedbuttonpvp", "");
|
|
|
|
Image buttonImage = playerButton.transform.GetChild(0).GetComponent<Image>();
|
|
Image buttonImageBg = playerButton.GetComponent<Image>();
|
|
if (buttonImage != null)
|
|
{
|
|
buttonImage.sprite = characterSprite;
|
|
buttonImageBg.sprite = characterSpriteBg;
|
|
graphic2v2.gameObject.transform.GetChild(1).GetChild(0).gameObject.SetActive(true);
|
|
graphic2v2.gameObject.transform.GetChild(1).Find("add").gameObject.SetActive(false);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
foreach (Button playerButton in playerButtons3v3)
|
|
{
|
|
string selectedbuttonpvp = PlayerPrefs.GetString("selectedbuttonpvp");
|
|
if (selectedbuttonpvp == playerButton.name)
|
|
{
|
|
|
|
// Update the player select buttons with the character sprite
|
|
PlayerPrefs.SetString("selectedbuttonpvp", "");
|
|
|
|
Image buttonImage = playerButton.transform.GetChild(0).GetComponent<Image>();
|
|
Image buttonImageBg = playerButton.GetComponent<Image>();
|
|
if (buttonImage != null)
|
|
{
|
|
buttonImage.sprite = characterSprite;
|
|
buttonImageBg.sprite = characterSpriteBg;
|
|
graphic3v3.gameObject.transform.GetChild(1).GetChild(0).gameObject.SetActive(true);
|
|
graphic3v3.gameObject.transform.GetChild(1).Find("add").gameObject.SetActive(false);
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
public (Sprite, Sprite) GetCharacterSprite(string characterName)
|
|
{
|
|
// Assuming you have a dictionary or some logic to retrieve the corresponding sprite based on the character name
|
|
// Implement the logic to return the sprite based on the character name
|
|
string[] characterNames = CharacterSelectionScript.characterNames;
|
|
foreach (string cName in characterNames)
|
|
{
|
|
if (cName == characterName)
|
|
{
|
|
Sprite characterSprite = CharacterSelectionScript.characterVsCardsLeft[System.Array.IndexOf(characterNames, characterName)];
|
|
Sprite characterSpriteBg = CharacterSelectionScript.characterVsCardsRight[System.Array.IndexOf(characterNames, characterName)];
|
|
return (characterSprite, characterSpriteBg);
|
|
}
|
|
}
|
|
return (null, null);
|
|
// Replace the return statement with your own code
|
|
}
|
|
}
|
|
|