chunk 1: core gameplay scripts scenes runtime assets
This commit is contained in:
121
Assets/Scripts/Character Selection System/CharacterSelection.cs
Normal file
121
Assets/Scripts/Character Selection System/CharacterSelection.cs
Normal file
@@ -0,0 +1,121 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
using TMPro;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using Unity.VisualScripting;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
public class CharacterSelection : MonoBehaviour
|
||||
{
|
||||
private int currentSelection = 0;
|
||||
|
||||
public Button primaryButton;
|
||||
public Button selectCharacterButton; // New button for character selection
|
||||
public Sprite[] buttonImages;
|
||||
public Sprite[] characterImages;
|
||||
public string[] characterNames;
|
||||
public string[] characterDescriptions;
|
||||
public Sprite[] selectButtons;
|
||||
public Sprite[] characterCards;
|
||||
public Sprite[] characterVsCardsLeft;
|
||||
public Sprite[] characterVsCardsRight;
|
||||
public Image backgroundImage;
|
||||
public Image characterImage;
|
||||
public TextMeshProUGUI characterName;
|
||||
public TextMeshProUGUI characterDescription;
|
||||
public Button[] buttons;
|
||||
private int currentIndex = 0;
|
||||
|
||||
public GameObject modeScreen; // Reference to the ModeScreen object to activate
|
||||
public ModeSelection modeSelection;
|
||||
public HomeSrceen homeScreen;
|
||||
public Button backButton;
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
primaryButton.Select();
|
||||
//buttons = selectButtons;
|
||||
SetBackgroundImage(currentIndex);
|
||||
EventSystem.current.SetSelectedGameObject(buttons[0].gameObject);
|
||||
|
||||
//backButton.onClick.AddListener(ModeBackButton);
|
||||
}
|
||||
|
||||
// OPTIMIZATION: Cache last selected index to avoid redundant updates
|
||||
private int lastSelectedIndex = -1;
|
||||
private GameObject lastSelectedObject = null;
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
// Cache the current selected object
|
||||
GameObject currentSelected = EventSystem.current?.currentSelectedGameObject;
|
||||
|
||||
// Early exit if nothing changed
|
||||
if (currentSelected == lastSelectedObject) return;
|
||||
lastSelectedObject = currentSelected;
|
||||
|
||||
if (currentSelected == null) return;
|
||||
|
||||
// Only GetComponent if the selected object changed
|
||||
Button selectedButton = currentSelected.GetComponent<Button>();
|
||||
if (selectedButton == null) return;
|
||||
|
||||
int selectedIndex = System.Array.IndexOf(buttons, selectedButton);
|
||||
|
||||
// Only update UI if index actually changed
|
||||
if (selectedIndex != lastSelectedIndex && selectedIndex >= 0)
|
||||
{
|
||||
lastSelectedIndex = selectedIndex;
|
||||
currentIndex = selectedIndex;
|
||||
try
|
||||
{
|
||||
SetButtonImage(selectedButton, selectedIndex);
|
||||
SetBackgroundImage(selectedIndex);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
private void SetButtonImage(Button button, int index)
|
||||
{
|
||||
if (button != null && buttonImages.Length > index)
|
||||
{
|
||||
button.GetComponent<Image>().sprite = buttonImages[index];
|
||||
}
|
||||
}
|
||||
|
||||
private void SetBackgroundImage(int index)
|
||||
{
|
||||
if (backgroundImage != null && buttonImages.Length > index)
|
||||
{
|
||||
backgroundImage.sprite = buttonImages[index];
|
||||
characterImage.sprite = characterImages[index];
|
||||
characterName.text = characterNames[index];
|
||||
characterDescription.text = characterDescriptions[index];
|
||||
|
||||
if (characterNames[index] == "Windham" || characterNames[index] == "Amira" || characterNames[index] == "Ziggy" || characterNames[index] == "Bahman" || characterNames[index] == "Amon" || characterNames[index] == "Imani")
|
||||
{
|
||||
selectCharacterButton.GetComponent<Button>().enabled = true;
|
||||
selectCharacterButton.GetComponent<Image>().sprite = selectButtons[index];
|
||||
PlayerPrefs.SetString("selectedcharactername", characterNames[index]);
|
||||
}
|
||||
else
|
||||
{
|
||||
selectCharacterButton.GetComponent <Button>().enabled = false;
|
||||
selectCharacterButton.GetComponent<Image>().sprite = selectCharacterButton.transform.GetChild(1).GetComponent<Image>().sprite;
|
||||
PlayerPrefs.SetString("selectedcharactername", characterNames[index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
primaryButton.Select();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 455a81dec040e964c8798d5e4ca4744d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
1113
Assets/Scripts/Character Selection System/ModeSelection.cs
Normal file
1113
Assets/Scripts/Character Selection System/ModeSelection.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 47a6ca989d901a74ab4ffd5e1b3b30bd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,284 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.SceneManagement;
|
||||
// (Removed unused generics import after legacy multi-select removal)
|
||||
using UnityEngine.EventSystems;
|
||||
using TMPro;
|
||||
|
||||
public class ModeSelectionManager : MonoBehaviour
|
||||
{
|
||||
public TMP_Text selectedModesText; // Displays current selected high-level mode (e.g., Practice / Coming Soon)
|
||||
|
||||
|
||||
public HomeSrceen homescreen;
|
||||
|
||||
// Legacy per-dimension buttons (kept if other systems still reference them, but no longer selected by user directly)
|
||||
public Button one; // 1v1
|
||||
public Button kill; // Kill condition
|
||||
public Button ai; // AI opponent
|
||||
|
||||
// Flags still used by downstream logic
|
||||
public bool is1v1Selected;
|
||||
public bool isKillSelected;
|
||||
public bool isTimeSelected;
|
||||
public bool isFreeSelected;
|
||||
public bool isPlayerSelected;
|
||||
public bool isAISelected;
|
||||
|
||||
public GameObject Mobile_LocalPopUp; // Still available if later needed for Local mode (not used in Practice path)
|
||||
|
||||
// New single-mode buttons (current design: only one top-level choice).
|
||||
[Header("Single Mode Buttons (New Design)")]
|
||||
public Button practiceModeButton; // Combines 1v1 + Kill + AI
|
||||
public Button cashModeButton; // Locked (coming soon)
|
||||
public Button tournamentModeButton; // Locked (coming soon)
|
||||
|
||||
[Header("Locked Mode Popup (Optional)")]
|
||||
public GameObject lockedModePopup; // Simple popup to show "Coming Soon" (assign in inspector)
|
||||
public TMP_Text lockedModeMessage; // Text element inside the popup
|
||||
|
||||
private enum GameMode { None, Practice, Cash, Tournament }
|
||||
private GameMode currentMode = GameMode.None;
|
||||
|
||||
[Header("Visual Settings")]
|
||||
public Color normalColor = Color.white; // Base color for unselected buttons
|
||||
public Color selectedColor = new Color(0.25f, 0.85f, 0.25f); // Color when a mode is actually chosen
|
||||
public Color lockedColor = new Color(0.6f, 0.6f, 0.6f); // Optional tint for locked modes (not permanent)
|
||||
public bool tintLockedModes = false; // Toggle to visually differentiate locked buttons
|
||||
|
||||
[Tooltip("If true, navigation focus (arrow / gamepad) will not recolor buttons until a mode is clicked.")]
|
||||
public bool ignoreFocusColor = true;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
// Do not auto-select any mode; wait for user interaction.
|
||||
currentMode = GameMode.None;
|
||||
if (selectedModesText != null)
|
||||
selectedModesText.text = "Select Mode";
|
||||
ConfigureNavigation();
|
||||
SetInitialFocus();
|
||||
UpdateModeVisuals();
|
||||
}
|
||||
|
||||
// ---------------------- SINGLE-SELECTION API ---------------------- //
|
||||
// Player picks ONE high-level mode. Practice maps internally to (1v1 + Kill + AI).
|
||||
|
||||
public void SelectPracticeMode()
|
||||
{
|
||||
currentMode = GameMode.Practice;
|
||||
// Emulate having chosen 1v1, kill, AI
|
||||
is1v1Selected = true;
|
||||
isKillSelected = true; SelectionOptions.Instance.isKillSelected = true; SelectionOptions.Instance.isTimeSelected = false;
|
||||
isAISelected = true; SelectionOptions.Instance.isAISelected = true; SelectionOptions.Instance.isPlayerSelected = false;
|
||||
isTimeSelected = false; isPlayerSelected = false; isFreeSelected = false;
|
||||
selectedModesText.text = "Mode: Practice";
|
||||
UpdateModeVisuals();
|
||||
}
|
||||
|
||||
public void SelectCashMode()
|
||||
{
|
||||
currentMode = GameMode.Cash;
|
||||
// Set Cash System flags
|
||||
is1v1Selected = false;
|
||||
isKillSelected = false;
|
||||
isTimeSelected = true; // Cash System uses timer
|
||||
isAISelected = true;
|
||||
isPlayerSelected = false;
|
||||
isFreeSelected = false;
|
||||
|
||||
// Set SelectionOptions flags
|
||||
SelectionOptions.Instance.isCashSystemSelected = true;
|
||||
SelectionOptions.Instance.isTimeSelected = true;
|
||||
SelectionOptions.Instance.isAISelected = true;
|
||||
SelectionOptions.Instance.isPlayerSelected = false;
|
||||
|
||||
selectedModesText.text = "Mode: Cash System";
|
||||
UpdateModeVisuals();
|
||||
}
|
||||
|
||||
public void SelectTournamentMode()
|
||||
{
|
||||
ShowLockedMode(GameMode.Tournament, "Tournament Mode is coming soon.");
|
||||
UpdateModeVisuals();
|
||||
}
|
||||
|
||||
private void ShowLockedMode(GameMode mode, string message)
|
||||
{
|
||||
if (lockedModePopup != null)
|
||||
{
|
||||
lockedModePopup.SetActive(true);
|
||||
if (lockedModeMessage != null) lockedModeMessage.text = message;
|
||||
}
|
||||
// Do not change currentMode if locked; user must select an available one (Practice).
|
||||
// Optionally still highlight the button briefly; keeping current stable behavior by not switching.
|
||||
}
|
||||
|
||||
private void SetButtonColor(Button btn, Color c)
|
||||
{
|
||||
if (btn == null) return;
|
||||
var img = btn.GetComponent<Image>();
|
||||
if (img != null) img.color = c;
|
||||
}
|
||||
|
||||
private void UpdateModeVisuals()
|
||||
{
|
||||
// Reset all to normal first
|
||||
SetButtonColor(practiceModeButton, normalColor);
|
||||
SetButtonColor(cashModeButton, tintLockedModes ? lockedColor : normalColor);
|
||||
SetButtonColor(tournamentModeButton, tintLockedModes ? lockedColor : normalColor);
|
||||
|
||||
switch (currentMode)
|
||||
{
|
||||
case GameMode.Practice:
|
||||
SetButtonColor(practiceModeButton, selectedColor);
|
||||
break;
|
||||
case GameMode.Cash:
|
||||
SetButtonColor(cashModeButton, selectedColor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetInitialFocus()
|
||||
{
|
||||
// Give keyboard/controller a starting focus without selecting a mode.
|
||||
if (EventSystem.current != null)
|
||||
{
|
||||
if (practiceModeButton != null)
|
||||
EventSystem.current.SetSelectedGameObject(practiceModeButton.gameObject);
|
||||
else if (cashModeButton != null)
|
||||
EventSystem.current.SetSelectedGameObject(cashModeButton.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
private void ConfigureNavigation()
|
||||
{
|
||||
// Ensure the three buttons navigate horizontally (or vertically) between each other.
|
||||
ConfigureButtonNavigation(practiceModeButton, cashModeButton, tournamentModeButton);
|
||||
ConfigureButtonNavigation(cashModeButton, tournamentModeButton, practiceModeButton);
|
||||
ConfigureButtonNavigation(tournamentModeButton, practiceModeButton, cashModeButton);
|
||||
}
|
||||
|
||||
private void ConfigureButtonNavigation(Button current, Button next, Button prev)
|
||||
{
|
||||
if (current == null) return;
|
||||
var nav = current.navigation;
|
||||
nav.mode = Navigation.Mode.Explicit;
|
||||
nav.selectOnRight = next; // or Down for vertical layouts
|
||||
nav.selectOnLeft = prev; // or Up for vertical layouts
|
||||
current.navigation = nav;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------- //
|
||||
|
||||
// (Removed legacy multi-select helper methods)
|
||||
|
||||
public void OnConfirm()
|
||||
{
|
||||
// Block confirmation if no mode chosen
|
||||
if (currentMode == GameMode.None)
|
||||
{
|
||||
// Provide soft feedback; rely on existing locked popup if assigned.
|
||||
if (lockedModePopup != null && !lockedModePopup.activeSelf)
|
||||
{
|
||||
lockedModePopup.SetActive(true);
|
||||
if (lockedModeMessage != null) lockedModeMessage.text = "Please select a mode.";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentMode == GameMode.Practice)
|
||||
{
|
||||
LaunchPracticeMode();
|
||||
return;
|
||||
}
|
||||
|
||||
// Cash System mode launch
|
||||
if (currentMode == GameMode.Cash)
|
||||
{
|
||||
LaunchCashSystemMode();
|
||||
return;
|
||||
}
|
||||
|
||||
// Tournament mode still locked
|
||||
if (currentMode == GameMode.Tournament)
|
||||
{
|
||||
if (lockedModePopup != null && !lockedModePopup.activeSelf)
|
||||
{
|
||||
lockedModePopup.SetActive(true);
|
||||
if (lockedModeMessage != null) lockedModeMessage.text = "Tournament mode is coming soon.";
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void LaunchCashSystemMode()
|
||||
{
|
||||
Debug.Log("[ModeSelectionManager] Launching Cash System Mode");
|
||||
|
||||
// Cash System = team selection, timer mode, AI opponents
|
||||
SelectionOptions.Instance.isCashSystemSelected = true;
|
||||
SelectionOptions.Instance.isTimeSelected = true;
|
||||
SelectionOptions.Instance.isAISelected = true;
|
||||
SelectionOptions.Instance.isPlayerSelected = false;
|
||||
SelectionOptions.Instance.isKillSelected = false;
|
||||
|
||||
// Navigate to character selection for Cash System - use 3v3 graphic
|
||||
gameObject.SetActive(false);
|
||||
|
||||
// Hide other graphics and show 3v3
|
||||
homescreen.modeSelectionScript.graphic1v1.SetActive(false);
|
||||
homescreen.modeSelectionScript.graphic1v1ai.SetActive(false);
|
||||
homescreen.modeSelectionScript.graphic2v2.SetActive(false);
|
||||
homescreen.modeSelectionScript.graphic3v3.SetActive(true);
|
||||
|
||||
// Select first button in 3v3 mode
|
||||
if (homescreen.modeSelectionScript.playerButtons3v3 != null &&
|
||||
homescreen.modeSelectionScript.playerButtons3v3.Length > 0)
|
||||
{
|
||||
homescreen.modeSelectionScript.playerButtons3v3[0].Select();
|
||||
}
|
||||
|
||||
homescreen.ActivateScreen(homescreen.modeScreen);
|
||||
|
||||
// Configure navigation for 3v3 confirm button if available
|
||||
if (homescreen.modeSelectionScript.confirmButton != null &&
|
||||
homescreen.modeSelectionScript.playerButtons3v3 != null &&
|
||||
homescreen.modeSelectionScript.playerButtons3v3.Length > 0)
|
||||
{
|
||||
Navigation navigation = homescreen.modeSelectionScript.confirmButton.navigation;
|
||||
navigation.mode = Navigation.Mode.Explicit;
|
||||
navigation.selectOnUp = homescreen.modeSelectionScript.playerButtons3v3[homescreen.modeSelectionScript.playerButtons3v3.Length - 1];
|
||||
homescreen.modeSelectionScript.confirmButton.navigation = navigation;
|
||||
}
|
||||
}
|
||||
|
||||
private void LaunchPracticeMode()
|
||||
{
|
||||
// Practice = 1v1 + Kill + AI branch (reuse existing logic block for that combination)
|
||||
// Ensure flags are coherent (some external code may depend on them after confirm).
|
||||
is1v1Selected = true;
|
||||
isKillSelected = true; SelectionOptions.Instance.isKillSelected = true; SelectionOptions.Instance.isTimeSelected = false;
|
||||
isAISelected = true; SelectionOptions.Instance.isAISelected = true; SelectionOptions.Instance.isPlayerSelected = false;
|
||||
isTimeSelected = false; isPlayerSelected = false; isFreeSelected = false;
|
||||
|
||||
// Reuse the existing AI + 1v1 + Kill flow (mirrors legacy condition block)
|
||||
gameObject.SetActive(false);
|
||||
homescreen.modeSelectionScript.graphic1v1ai.SetActive(true);
|
||||
homescreen.modeSelectionScript.graphic1v1.SetActive(false);
|
||||
homescreen.modeSelectionScript.SelectFirstAIButton();
|
||||
homescreen.ActivateScreen(homescreen.modeScreen);
|
||||
|
||||
// Configure navigation (copied from legacy block for AI path)
|
||||
Navigation navigation = homescreen.modeSelectionScript.confirmButtonAI.navigation;
|
||||
navigation.mode = Navigation.Mode.Explicit;
|
||||
navigation.selectOnUp = homescreen.modeSelectionScript.playerButtons1v1ai[1];
|
||||
homescreen.modeSelectionScript.confirmButtonAI.navigation = navigation;
|
||||
}
|
||||
|
||||
public void BackButton()
|
||||
{
|
||||
gameObject.SetActive(false);
|
||||
homescreen.primaryButton.Select();
|
||||
homescreen.ActivateScreen(homescreen.gameObject);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 221ca54e589f66849b74f9b482c837af
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
43
Assets/Scripts/Character Selection System/PlayerButton.cs
Normal file
43
Assets/Scripts/Character Selection System/PlayerButton.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.InputSystem;
|
||||
//using static UnityEditor.Experimental.GraphView.GraphView;
|
||||
|
||||
public class PlayerButton : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private bool isAvailable = true;
|
||||
public bool IsAvailable { get => isAvailable; set => isAvailable = value; }
|
||||
|
||||
[SerializeField] private Button button;
|
||||
|
||||
// Reference to the associated PlayerInput
|
||||
public PlayerInput playerInput;
|
||||
|
||||
// Reference to the associated InputDevice
|
||||
[HideInInspector] public InputDevice device;
|
||||
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
button = GetComponent<Button>();
|
||||
playerInput = GetComponent<PlayerInput>();
|
||||
}
|
||||
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
|
||||
}
|
||||
private void Update()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/*player1 = PlayerInput.Instantiate(playerPrefab, controlScheme: "Arrows", pairWithDevice: Keyboard.current);
|
||||
player2 = PlayerInput.Instantiate(playerPrefab, controlScheme: "WASD", pairWithDevice: Keyboard.current);*/
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c2ccb3df1dfc58b4c985ce7f80583b88
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
928
Assets/Scripts/Character Selection System/SelectionOptions.cs
Normal file
928
Assets/Scripts/Character Selection System/SelectionOptions.cs
Normal file
@@ -0,0 +1,928 @@
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.InputSystem;
|
||||
using static ModeSelection;
|
||||
using UnityEngine.InputSystem.Users;
|
||||
using Unity.VisualScripting;
|
||||
using Cinemachine;
|
||||
using System.Collections;
|
||||
using System;
|
||||
using TMPro;
|
||||
using UnityEngine.InputSystem.UI;
|
||||
using static UnityEngine.AudioSettings;
|
||||
|
||||
public class SelectionOptions : MonoBehaviour
|
||||
{
|
||||
private static SelectionOptions instance;
|
||||
public static SelectionOptions Instance { get { return instance; } }
|
||||
//public ModeSelection modeSelection;
|
||||
public Dictionary<string, PlayerInfo> selectedPlayerDevice;
|
||||
public Dictionary<string, string> selectedPlayersAI;
|
||||
public InputActionAsset existingInputAsset;
|
||||
public InputDevice activeDeviceforAI;
|
||||
public string controlSchemeforAI;
|
||||
private int count;
|
||||
|
||||
public GameObject eventSytem;
|
||||
|
||||
public bool is1v1Selected;
|
||||
public bool isKillSelected;
|
||||
public bool isTimeSelected;
|
||||
public bool isPlayerSelected;
|
||||
public bool isAISelected;
|
||||
public bool isCashSystemSelected;
|
||||
private bool isMobile;
|
||||
|
||||
// Cash System team data
|
||||
public string[] playerTeam = new string[3]; // 3 characters for player team
|
||||
public string[] enemyTeam = new string[3]; // 3 characters for enemy team
|
||||
public int captainIndex = 0; // Index of player-controlled character
|
||||
public int currentControlledIndex = 0; // Index of currently controlled character (for switching)
|
||||
|
||||
// Character portrait sprites — stored before scene transition so Game scene can use them
|
||||
[System.NonSerialized] public Sprite[] playerTeamSprites;
|
||||
[System.NonSerialized] public Sprite[] enemyTeamSprites;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (instance != null && instance != this)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
return;
|
||||
}
|
||||
instance = this;
|
||||
DontDestroyOnLoad(gameObject);
|
||||
|
||||
is1v1Selected = false;
|
||||
isKillSelected = false;
|
||||
isTimeSelected = false;
|
||||
isPlayerSelected = false;
|
||||
isAISelected = false;
|
||||
isCashSystemSelected = false;
|
||||
|
||||
|
||||
}
|
||||
public Dictionary<string, PlayerInfo> GetSelectedPlayerDevice()
|
||||
{
|
||||
return selectedPlayerDevice;
|
||||
//return modeSelection.selectedPlayerDevice;
|
||||
}
|
||||
public Dictionary<string, string> GetSelectedPlayersAI()
|
||||
{
|
||||
return selectedPlayersAI;
|
||||
//return modeSelection.selectedPlayerDevice;
|
||||
}
|
||||
public Transform FindGrandchildByName(Transform parent, string name)
|
||||
{
|
||||
foreach (Transform child in parent)
|
||||
{
|
||||
foreach (Transform grandchild in child)
|
||||
{
|
||||
if (grandchild.name == name)
|
||||
{
|
||||
return grandchild;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private void DeterminePlatform()
|
||||
{
|
||||
if (UnityEngine.Application.platform == RuntimePlatform.Android ||
|
||||
UnityEngine.Application.platform == RuntimePlatform.IPhonePlayer)
|
||||
{
|
||||
isMobile = true;
|
||||
}
|
||||
}
|
||||
private GameObject LoadPrefab(string playerName, string playerMode)
|
||||
{
|
||||
bool isAI = playerMode == "AI";
|
||||
GameObject prefab = CharacterPrefabManager.Instance.GetCharacterPrefab(playerName, isAI);
|
||||
|
||||
if (prefab == null)
|
||||
{
|
||||
Debug.LogError($"Failed to load prefab for character {playerName} (AI: {isAI})");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Ensure prefab has required components
|
||||
if (prefab.GetComponent<PlayerInput>() == null)
|
||||
{
|
||||
Debug.LogWarning($"Adding missing PlayerInput component to prefab {playerName}");
|
||||
prefab.AddComponent<PlayerInput>();
|
||||
}
|
||||
}
|
||||
|
||||
return prefab;
|
||||
}
|
||||
|
||||
private GameObject LoadPlayerPrefab(string playerName)
|
||||
{
|
||||
return CharacterPrefabManager.Instance.GetCharacterPrefab(playerName, false);
|
||||
}
|
||||
|
||||
private void SetUpPlayerInput(GameObject playerPrefab, string playerMode)
|
||||
{
|
||||
if (playerPrefab == null)
|
||||
{
|
||||
Debug.LogError("Player prefab is null in SetUpPlayerInput");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the prefab has a PlayerInput component
|
||||
if (playerPrefab.GetComponent<PlayerInput>() == null)
|
||||
{
|
||||
Debug.LogError($"Prefab {playerPrefab.name} does not have a PlayerInput component.");
|
||||
// Add PlayerInput component if it doesn't exist
|
||||
playerPrefab.AddComponent<PlayerInput>();
|
||||
}
|
||||
|
||||
PlayerInput playerInput = null;
|
||||
PlayerScript playerScript = null;
|
||||
GameObject player = null;
|
||||
|
||||
if (playerMode == "AI")
|
||||
{
|
||||
try {
|
||||
playerInput = PlayerInput.Instantiate(playerPrefab, controlScheme: controlSchemeforAI, pairWithDevices: activeDeviceforAI);
|
||||
player = playerInput.gameObject;
|
||||
player.tag = "Enemy";
|
||||
|
||||
// === NEW: Configure as EnemyAI using ControlType system ===
|
||||
TeamMember teamMember = player.GetComponent<TeamMember>();
|
||||
if (teamMember == null) teamMember = player.AddComponent<TeamMember>();
|
||||
teamMember.CurrentTeam = TeamMember.Team.EnemyTeam;
|
||||
teamMember.SetControlType(TeamMember.ControlType.EnemyAI);
|
||||
|
||||
if (CameraManager.Instance != null)
|
||||
{
|
||||
CameraManager.Instance.RegisterTeamMember(teamMember);
|
||||
}
|
||||
|
||||
Debug.Log($"[SelectionOptions] SetUpPlayerInput: Spawned {player.name} as EnemyAI");
|
||||
|
||||
} catch (Exception e) {
|
||||
Debug.LogError($"Error instantiating AI player: {e.Message}");
|
||||
// Fallback to regular instantiation
|
||||
player = Instantiate(playerPrefab);
|
||||
player.tag = "Enemy";
|
||||
}
|
||||
}
|
||||
else if (playerMode == "PLAYER")
|
||||
{
|
||||
try {
|
||||
playerInput = PlayerInput.Instantiate(playerPrefab, controlScheme: controlSchemeforAI, pairWithDevices: activeDeviceforAI);
|
||||
player = playerInput.gameObject;
|
||||
player.tag = "Player";
|
||||
playerScript = player.GetComponent<PlayerScript>();
|
||||
|
||||
// === NEW: Configure as HumanControlled using ControlType system ===
|
||||
TeamMember teamMember = player.GetComponent<TeamMember>();
|
||||
if (teamMember == null) teamMember = player.AddComponent<TeamMember>();
|
||||
teamMember.CurrentTeam = TeamMember.Team.PlayerTeam;
|
||||
teamMember.SetControlType(TeamMember.ControlType.HumanControlled);
|
||||
|
||||
if (CameraManager.Instance != null)
|
||||
{
|
||||
CameraManager.Instance.RegisterTeamMember(teamMember);
|
||||
CameraManager.Instance.SetTarget(teamMember);
|
||||
Debug.Log($"[SelectionOptions] SetUpPlayerInput: Set camera target to {player.name}");
|
||||
}
|
||||
|
||||
Debug.Log($"[SelectionOptions] SetUpPlayerInput: Spawned {player.name} as HumanControlled");
|
||||
|
||||
if (playerInput != null && playerScript != null)
|
||||
{
|
||||
playerInput.neverAutoSwitchControlSchemes = true;
|
||||
playerInput.defaultActionMap = "Player Controls";
|
||||
|
||||
// Use the TryBindAction method to safely bind to actions only if they exist
|
||||
TryBindAction(playerInput, "Move", playerScript.OnMove);
|
||||
|
||||
// For actions that might be canceled
|
||||
if (playerInput.currentActionMap != null && playerInput.currentActionMap.FindAction("Move") != null)
|
||||
{
|
||||
playerInput.currentActionMap["Move"].canceled += playerScript.OnMove;
|
||||
}
|
||||
|
||||
// Punches
|
||||
TryBindAction(playerInput, "Jab", playerScript.OnJab);
|
||||
TryBindAction(playerInput, "Right", playerScript.OnRight);
|
||||
TryBindAction(playerInput, "LeftHook", playerScript.OnLeftHook);
|
||||
TryBindAction(playerInput, "RightHook", playerScript.OnRightHook);
|
||||
TryBindAction(playerInput, "LeftElbow", playerScript.OnLeftElbow);
|
||||
TryBindAction(playerInput, "RightElbow", playerScript.OnRightElbow);
|
||||
TryBindAction(playerInput, "RightBody", playerScript.OnRightBody);
|
||||
TryBindAction(playerInput, "PowerPunchLeft", playerScript.OnPowerPunchLeft);
|
||||
TryBindAction(playerInput, "SupermanPunch", playerScript.OnSupermanPunch);
|
||||
|
||||
// Kicks
|
||||
TryBindAction(playerInput, "LegKickRight", playerScript.OnLegKickRight);
|
||||
TryBindAction(playerInput, "BodyKickRight", playerScript.OnBodyKickRight);
|
||||
TryBindAction(playerInput, "KneeRight", playerScript.OnKneeRight);
|
||||
TryBindAction(playerInput, "BackSideKick", playerScript.OnBackSideKick);
|
||||
TryBindAction(playerInput, "FrontKickRight", playerScript.OnFrontKickRight);
|
||||
TryBindAction(playerInput, "LegPowerKickRight", playerScript.OnLegPowerKickRight);
|
||||
|
||||
// Dodges
|
||||
TryBindAction(playerInput, "JumpBack", playerScript.OnJumpBack);
|
||||
TryBindAction(playerInput, "JumpLeft", playerScript.OnJumpLeft);
|
||||
TryBindAction(playerInput, "JumpRight", playerScript.OnJumpRight);
|
||||
|
||||
// Blocks
|
||||
TryBindAction(playerInput, "BlockStepBack", playerScript.OnBlockStepBack);
|
||||
TryBindAction(playerInput, "BlockBodyLeft", playerScript.OnBlockBodyLeft);
|
||||
TryBindAction(playerInput, "BlockLeg", playerScript.OnBlockLeg);
|
||||
|
||||
// Pause
|
||||
TryBindAction(playerInput, "Pause", player.GetComponent<HealthNew>().OnPause);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"Player {player.name} is missing required components: PlayerInput={playerInput != null}, PlayerScript={playerScript != null}");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Debug.LogError($"Error instantiating Player: {e.Message}");
|
||||
// Fallback to regular instantiation
|
||||
player = Instantiate(playerPrefab);
|
||||
player.gameObject.tag = "Player";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SetUpPlayerInputAI(GameObject playerPrefab, string playerMode)
|
||||
{
|
||||
// Spawn the character
|
||||
var character = Instantiate(playerPrefab);
|
||||
|
||||
// Add or get TeamMember component
|
||||
TeamMember teamMember = character.GetComponent<TeamMember>();
|
||||
if (teamMember == null)
|
||||
{
|
||||
teamMember = character.AddComponent<TeamMember>();
|
||||
}
|
||||
|
||||
if (playerMode == "AI")
|
||||
{
|
||||
// Configure as enemy AI using the unified ControlType system
|
||||
teamMember.CurrentTeam = TeamMember.Team.EnemyTeam;
|
||||
teamMember.SetControlType(TeamMember.ControlType.EnemyAI);
|
||||
character.gameObject.tag = "Enemy";
|
||||
|
||||
Debug.Log($"[SelectionOptions] Spawned {character.name} as EnemyAI");
|
||||
}
|
||||
else if (playerMode == "PLAYER")
|
||||
{
|
||||
// Configure as human-controlled player
|
||||
teamMember.CurrentTeam = TeamMember.Team.PlayerTeam;
|
||||
teamMember.SetControlType(TeamMember.ControlType.HumanControlled);
|
||||
character.gameObject.tag = "Player";
|
||||
|
||||
Debug.Log($"[SelectionOptions] Spawned {character.name} as HumanControlled");
|
||||
|
||||
// DIRECTLY set camera target for the player character
|
||||
if (CameraManager.Instance != null)
|
||||
{
|
||||
CameraManager.Instance.SetTarget(teamMember);
|
||||
Debug.Log($"[SelectionOptions] Set CameraManager target to {character.name}");
|
||||
}
|
||||
}
|
||||
|
||||
// Register with CameraManager for automatic camera updates
|
||||
if (CameraManager.Instance != null)
|
||||
{
|
||||
CameraManager.Instance.RegisterTeamMember(teamMember);
|
||||
}
|
||||
}
|
||||
|
||||
// private void SetUpCamera()
|
||||
// {
|
||||
// //print("user after pairing: " + inputUser);
|
||||
// GameObject camera = GameObject.Find("CinemachineCamera");
|
||||
|
||||
// var vcam = camera.GetComponent<CinemachineFreeLook>();
|
||||
// if (vcam != null)
|
||||
// {
|
||||
// var targets = GameObject.FindGameObjectsWithTag("Player");
|
||||
// Transform headTransform = transform;
|
||||
// if (targets[0].name == "Cheetah 2")
|
||||
// {
|
||||
// //Transform firstTarget = targets[0].transform;
|
||||
// headTransform = targets[0].transform.GetChild(9).GetChild(6).GetChild(1);
|
||||
// }
|
||||
// else if (targets[0].name == "Rabbit 2")
|
||||
// {
|
||||
// headTransform = targets[0].transform.GetChild(7).GetChild(6).GetChild(1);
|
||||
// }
|
||||
// else if (targets[0].name == "Eagle")
|
||||
// {
|
||||
// headTransform = targets[0].transform.GetChild(7).GetChild(6).GetChild(1);
|
||||
// }
|
||||
// else if (targets[0].name == "Hyena")
|
||||
// {
|
||||
// headTransform = targets[0].transform.GetChild(7).GetChild(6).GetChild(1);
|
||||
// }
|
||||
// else if (targets[0].name == "HM")
|
||||
// {
|
||||
// headTransform = targets[0].transform.GetChild(7).GetChild(6).GetChild(1);
|
||||
// }
|
||||
// else if (targets[0].name == "Cat")
|
||||
// {
|
||||
// headTransform = targets[0].transform.GetChild(7).GetChild(6).GetChild(1);
|
||||
// }
|
||||
// if (headTransform != null)
|
||||
// {
|
||||
// vcam.LookAt = vcam.Follow = GameObject.Find("mixamorig:Head").transform;
|
||||
// //vcam.LookAt = vcam.Follow = GameObject.Find("BUILD-WALL").transform;
|
||||
// //vcam.m_Lens.FieldOfView = 43;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
private void SetUpCamera()
|
||||
{
|
||||
if (isPlayerSelected) // Local multiplayer mode
|
||||
{
|
||||
SetupSplitScreenCameras();
|
||||
}
|
||||
else // Single player or AI mode
|
||||
{
|
||||
SetupSingleCamera();
|
||||
}
|
||||
}
|
||||
|
||||
private void SetupSplitScreenCameras()
|
||||
{
|
||||
Camera mainCamera1 = GameObject.Find("MainCamera")?.GetComponent<Camera>();
|
||||
Camera mainCamera2 = GameObject.Find("MainCamera2")?.GetComponent<Camera>();
|
||||
|
||||
if (mainCamera1 && mainCamera2)
|
||||
{
|
||||
// Set viewport rects
|
||||
mainCamera1.rect = new Rect(0, 0, 0.5f, 1);
|
||||
mainCamera2.rect = new Rect(0.5f, 0, 0.5f, 1);
|
||||
|
||||
// Configure comprehensive layer masks for both cameras
|
||||
int commonLayers = LayerMask.GetMask("Default", "TransparentFX", "Water", "UI", "PostProcessing", "Ground");
|
||||
|
||||
// Camera 1: Everything + Player One specific layers
|
||||
mainCamera1.cullingMask = commonLayers | LayerMask.GetMask("Player One");
|
||||
|
||||
// Camera 2: Everything + Player Two specific layers
|
||||
mainCamera2.cullingMask = commonLayers | LayerMask.GetMask("Player Two");
|
||||
|
||||
SetupVirtualCameras();
|
||||
}
|
||||
}
|
||||
|
||||
private void SetupVirtualCameras()
|
||||
{
|
||||
var cinemachine1 = GameObject.Find("CinemachineCamera")?.GetComponent<CinemachineFreeLook>();
|
||||
var cinemachine2 = GameObject.Find("CinemachineCamera2")?.GetComponent<CinemachineFreeLook>();
|
||||
|
||||
if (cinemachine1 && cinemachine2)
|
||||
{
|
||||
// Ensure both virtual cameras are active
|
||||
cinemachine1.gameObject.SetActive(true);
|
||||
cinemachine2.gameObject.SetActive(true);
|
||||
|
||||
// Configure input providers
|
||||
var input1 = cinemachine1.GetComponent<CinemachineInputProvider>();
|
||||
var input2 = cinemachine2.GetComponent<CinemachineInputProvider>();
|
||||
|
||||
if (input1) input1.PlayerIndex = 0;
|
||||
if (input2) input2.PlayerIndex = 1;
|
||||
|
||||
// Assign players to cameras
|
||||
var player = GameObject.FindGameObjectWithTag("Player");
|
||||
var enemy = GameObject.FindGameObjectWithTag("Enemy");
|
||||
|
||||
if (player && enemy)
|
||||
{
|
||||
// Set camera targets with correct Follow/LookAt separation
|
||||
// Follow = root (orbit center), LookAt = head (aim point)
|
||||
cinemachine1.Follow = player.transform;
|
||||
cinemachine1.LookAt = FindCharacterHead(player);
|
||||
cinemachine2.Follow = enemy.transform;
|
||||
cinemachine2.LookAt = FindCharacterHead(enemy);
|
||||
|
||||
// Set player layers
|
||||
SetLayerRecursively(player, LayerMask.NameToLayer("Player One"));
|
||||
SetLayerRecursively(enemy, LayerMask.NameToLayer("Player Two"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SetLayerRecursively(GameObject obj, int layer)
|
||||
{
|
||||
if (obj == null) return;
|
||||
|
||||
obj.layer = layer;
|
||||
foreach (Transform child in obj.transform)
|
||||
{
|
||||
SetLayerRecursively(child.gameObject, layer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void SetupSingleCamera()
|
||||
{
|
||||
GameObject camera = GameObject.Find("CinemachineCamera");
|
||||
var vcam = camera?.GetComponent<CinemachineFreeLook>();
|
||||
if (vcam != null)
|
||||
{
|
||||
var player = GameObject.FindGameObjectWithTag("Player");
|
||||
Debug.Log($"[SelectionOptions] SetupSingleCamera - Found player: {(player != null ? player.name : "NULL")}");
|
||||
|
||||
if (player != null)
|
||||
{
|
||||
// Use root for Follow (stable orbit center)
|
||||
Transform followTransform = player.transform;
|
||||
// Use head for LookAt (camera points at upper body)
|
||||
Transform lookAtTransform = FindCharacterHead(player);
|
||||
|
||||
vcam.Follow = followTransform;
|
||||
vcam.LookAt = lookAtTransform;
|
||||
|
||||
Debug.Log($"[SelectionOptions] Camera - Follow: {followTransform.name}, LookAt: {lookAtTransform.name}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("[SelectionOptions] No player with tag 'Player' found for camera setup!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("[SelectionOptions] CinemachineCamera not found in scene!");
|
||||
}
|
||||
}
|
||||
|
||||
private Transform FindCharacterHead(GameObject character)
|
||||
{
|
||||
if (character == null) return null;
|
||||
|
||||
string characterName = character.name;
|
||||
Transform headTransform = null;
|
||||
|
||||
// First, try to find head by common bone names (more reliable)
|
||||
string[] headBoneNames = { "mixamorig:Head", "Head", "head", "Bip001 Head", "Bone_Head" };
|
||||
foreach (string boneName in headBoneNames)
|
||||
{
|
||||
headTransform = FindChildRecursive(character.transform, boneName);
|
||||
if (headTransform != null)
|
||||
{
|
||||
Debug.Log($"[SelectionOptions] Found head bone '{boneName}' for {characterName}");
|
||||
return headTransform;
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to character-specific hardcoded paths
|
||||
try
|
||||
{
|
||||
switch (characterName)
|
||||
{
|
||||
case var _ when characterName.Contains("Cheetah"):
|
||||
headTransform = character.transform.GetChild(9)?.GetChild(6)?.GetChild(1);
|
||||
break;
|
||||
case var _ when characterName.Contains("Rabbit"):
|
||||
case var _ when characterName.Contains("Eagle"):
|
||||
case var _ when characterName.Contains("Hyena"):
|
||||
case var _ when characterName.Contains("HM"):
|
||||
case var _ when characterName.Contains("Cat"):
|
||||
case var _ when characterName.Contains("CAT N"):
|
||||
headTransform = character.transform.GetChild(7)?.GetChild(6)?.GetChild(1);
|
||||
break;
|
||||
}
|
||||
|
||||
if (headTransform != null)
|
||||
{
|
||||
Debug.Log($"[SelectionOptions] Found head via hardcoded path for {characterName}: {headTransform.name}");
|
||||
return headTransform;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogWarning($"Error finding head for character {characterName}: {e.Message}");
|
||||
}
|
||||
|
||||
// Final fallback: return root (will show legs like the user experienced)
|
||||
Debug.LogWarning($"[SelectionOptions] Could not find head bone for {characterName}, using root transform");
|
||||
return character.transform;
|
||||
}
|
||||
|
||||
private Transform FindChildRecursive(Transform parent, string name)
|
||||
{
|
||||
if (parent.name == name) return parent;
|
||||
|
||||
foreach (Transform child in parent)
|
||||
{
|
||||
Transform result = FindChildRecursive(child, name);
|
||||
if (result != null) return result;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
public void SpawnPlayers()
|
||||
{
|
||||
// Skip spawning for Cash System mode - CashSystemManager handles its own team spawning
|
||||
if (isCashSystemSelected)
|
||||
{
|
||||
Debug.Log("[SelectionOptions] SpawnPlayers skipped - Cash System mode uses CashSystemManager.SpawnTeams");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
isMobile = false;
|
||||
DeterminePlatform();
|
||||
|
||||
// Initialize dictionaries if they're null
|
||||
if (selectedPlayerDevice == null)
|
||||
{
|
||||
selectedPlayerDevice = new Dictionary<string, PlayerInfo>();
|
||||
}
|
||||
|
||||
if (selectedPlayersAI == null)
|
||||
{
|
||||
selectedPlayersAI = new Dictionary<string, string>();
|
||||
}
|
||||
|
||||
if (!isMobile)
|
||||
{
|
||||
if (isPlayerSelected)
|
||||
{
|
||||
if (selectedPlayerDevice == null)
|
||||
{
|
||||
selectedPlayerDevice = SelectionOptions.Instance.GetSelectedPlayerDevice();
|
||||
}
|
||||
|
||||
// Setup split screen immediately after spawning players
|
||||
SetupSplitScreenCameras();
|
||||
|
||||
// Setup split screen cameras
|
||||
var camera1 = GameObject.Find("MainCamera");
|
||||
var camera2 = GameObject.Find("MainCamera2");
|
||||
|
||||
if (camera1 != null && camera2 != null)
|
||||
{
|
||||
camera1.GetComponent<Camera>().rect = new Rect(0, 0, 0.5f, 1);
|
||||
camera2.GetComponent<Camera>().rect = new Rect(0.5f, 0, 0.5f, 1);
|
||||
}
|
||||
|
||||
foreach (var kvp in selectedPlayerDevice)
|
||||
{
|
||||
string playerName = kvp.Key;
|
||||
PlayerInfo playerInfo = kvp.Value;
|
||||
GameObject playerPrefab = LoadPlayerPrefab(playerName);
|
||||
|
||||
if (playerPrefab != null)
|
||||
{
|
||||
PlayerInput playerInput = PlayerInput.Instantiate(playerPrefab, controlScheme: playerInfo.ControlScheme, pairWithDevices: playerInfo.Device);
|
||||
GameObject player = playerInput.gameObject;
|
||||
|
||||
player.tag = "Player";
|
||||
if (count == 0)
|
||||
{
|
||||
player.layer = LayerMask.NameToLayer("Player One");
|
||||
}
|
||||
|
||||
ConfigurePlayerInput(player);
|
||||
|
||||
foreach (var pair in selectedPlayerDevice)
|
||||
{
|
||||
if (pair.Key == playerName)
|
||||
{
|
||||
count++;
|
||||
if (count == 2)
|
||||
{
|
||||
player.tag = "Enemy";
|
||||
player.layer = LayerMask.NameToLayer("Player Two");
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SetUpCamera();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (isAISelected)
|
||||
{
|
||||
// Disable split screen for AI mode
|
||||
var camera2 = GameObject.Find("MainCamera2");
|
||||
if (camera2 != null)
|
||||
{
|
||||
camera2.SetActive(false);
|
||||
}
|
||||
|
||||
if (selectedPlayersAI == null)
|
||||
{
|
||||
selectedPlayersAI = SelectionOptions.Instance.GetSelectedPlayersAI();
|
||||
}
|
||||
|
||||
foreach (var kvp in selectedPlayersAI)
|
||||
{
|
||||
string playerName = kvp.Key;
|
||||
string playerMode = kvp.Value;
|
||||
GameObject playerPrefab = LoadPrefab(playerName, playerMode);
|
||||
|
||||
if (playerPrefab != null)
|
||||
{
|
||||
SetUpPlayerInput(playerPrefab, playerMode);
|
||||
SetUpCamera();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isAISelected)
|
||||
{
|
||||
var camera2 = GameObject.Find("MainCamera2");
|
||||
if (camera2 != null)
|
||||
{
|
||||
camera2.SetActive(false);
|
||||
}
|
||||
|
||||
if (selectedPlayersAI == null)
|
||||
{
|
||||
selectedPlayersAI = SelectionOptions.Instance.GetSelectedPlayersAI();
|
||||
}
|
||||
|
||||
foreach (var kvp in selectedPlayersAI)
|
||||
{
|
||||
string playerName = kvp.Key;
|
||||
string playerMode = kvp.Value;
|
||||
GameObject playerPrefab = LoadPrefab(playerName, playerMode);
|
||||
|
||||
if (playerPrefab != null)
|
||||
{
|
||||
SetUpPlayerInputAI(playerPrefab, playerMode);
|
||||
Debug.Log($"[SelectionOptions] Spawned {playerName} as {playerMode}");
|
||||
}
|
||||
}
|
||||
|
||||
// Set up camera AFTER all characters are spawned
|
||||
// This ensures the Player tag is properly assigned before camera targets
|
||||
SetUpCamera();
|
||||
Debug.Log("[SelectionOptions] Camera setup complete after all spawns");
|
||||
}
|
||||
}
|
||||
} // Close try block
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogError($"Error in SpawnPlayers: {ex.Message}\n{ex.StackTrace}");
|
||||
}
|
||||
}
|
||||
|
||||
private void ConfigurePlayerInput(GameObject player)
|
||||
{
|
||||
PlayerInput playerInput = player.GetComponent<PlayerInput>();
|
||||
PlayerScript playerScript = player.GetComponent<PlayerScript>();
|
||||
|
||||
// === NEW: Configure ControlType for local multiplayer ===
|
||||
TeamMember teamMember = player.GetComponent<TeamMember>();
|
||||
if (teamMember == null) teamMember = player.AddComponent<TeamMember>();
|
||||
teamMember.CurrentTeam = TeamMember.Team.PlayerTeam;
|
||||
teamMember.SetControlType(TeamMember.ControlType.HumanControlled);
|
||||
|
||||
if (CameraManager.Instance != null)
|
||||
{
|
||||
CameraManager.Instance.RegisterTeamMember(teamMember);
|
||||
// Note: In split screen, camera targets are handled differently via SetupVirtualCameras
|
||||
}
|
||||
|
||||
Debug.Log($"[SelectionOptions] ConfigurePlayerInput: Configured {player.name} as HumanControlled");
|
||||
|
||||
playerInput.neverAutoSwitchControlSchemes = true;
|
||||
playerInput.defaultActionMap = "Player Controls";
|
||||
|
||||
// Movement
|
||||
playerInput.currentActionMap["Move"].performed += playerScript.OnMove;
|
||||
playerInput.currentActionMap["Move"].canceled += playerScript.OnMove;
|
||||
|
||||
// Punches
|
||||
playerInput.currentActionMap["Jab"].performed += playerScript.OnJab;
|
||||
playerInput.currentActionMap["Right"].performed += playerScript.OnRight;
|
||||
playerInput.currentActionMap["LeftHook"].performed += playerScript.OnLeftHook;
|
||||
playerInput.currentActionMap["RightHook"].performed += playerScript.OnRightHook;
|
||||
playerInput.currentActionMap["LeftElbow"].performed += playerScript.OnLeftElbow;
|
||||
playerInput.currentActionMap["RightElbow"].performed += playerScript.OnRightElbow;
|
||||
playerInput.currentActionMap["RightBody"].performed += playerScript.OnRightBody;
|
||||
playerInput.currentActionMap["PowerPunchLeft"].performed += playerScript.OnPowerPunchLeft;
|
||||
playerInput.currentActionMap["SupermanPunch"].performed += playerScript.OnSupermanPunch;
|
||||
|
||||
// Kicks
|
||||
playerInput.currentActionMap["LegKickRight"].performed += playerScript.OnLegKickRight;
|
||||
playerInput.currentActionMap["BodyKickRight"].performed += playerScript.OnBodyKickRight;
|
||||
playerInput.currentActionMap["KneeRight"].performed += playerScript.OnKneeRight;
|
||||
playerInput.currentActionMap["BackSideKick"].performed += playerScript.OnBackSideKick;
|
||||
playerInput.currentActionMap["FrontKickRight"].performed += playerScript.OnFrontKickRight;
|
||||
playerInput.currentActionMap["LegPowerKickRight"].performed += playerScript.OnLegPowerKickRight;
|
||||
|
||||
// Dodges
|
||||
playerInput.currentActionMap["JumpBack"].performed += playerScript.OnJumpBack;
|
||||
playerInput.currentActionMap["JumpLeft"].performed += playerScript.OnJumpLeft;
|
||||
playerInput.currentActionMap["JumpRight"].performed += playerScript.OnJumpRight;
|
||||
|
||||
// Blocks
|
||||
TryBindAction(playerInput, "BlockStepBack", playerScript.OnBlockStepBack);
|
||||
TryBindAction(playerInput, "BlockBodyLeft", playerScript.OnBlockBodyLeft);
|
||||
TryBindAction(playerInput, "BlockLeg", playerScript.OnBlockLeg);
|
||||
|
||||
// NEW: Vicious Attacks - Make sure to add these to your input action asset
|
||||
TryBindAction(playerInput, "Chokeslam", playerScript.OnChokeslam);
|
||||
TryBindAction(playerInput, "Suplex", playerScript.OnSuplex);
|
||||
TryBindAction(playerInput, "GiantSwing", playerScript.OnGiantSwing);
|
||||
TryBindAction(playerInput, "DiamondCrusher", playerScript.OnDiamondCrusher);
|
||||
TryBindAction(playerInput, "SumoSlap", playerScript.OnSumoSlap);
|
||||
TryBindAction(playerInput, "JavelinTackle", playerScript.OnJavelinTackle);
|
||||
|
||||
// NEW: Special Finishers - Make sure to add these to your input action asset
|
||||
TryBindAction(playerInput, "RKO", playerScript.OnRKO);
|
||||
TryBindAction(playerInput, "Spear", playerScript.OnSpear);
|
||||
TryBindAction(playerInput, "RockBottom", playerScript.OnRockBottom);
|
||||
TryBindAction(playerInput, "F5", playerScript.OnF5);
|
||||
// SwantonBomb method doesn't exist in PlayerScript yet
|
||||
// TODO: Implement OnSwantonBomb in PlayerScript
|
||||
// TryBindAction(playerInput, "SwantonBomb", playerScript.OnSwantonBomb);
|
||||
|
||||
// Pause
|
||||
TryBindAction(playerInput, "Pause", player.GetComponent<HealthNew>().OnPause);
|
||||
}
|
||||
|
||||
// Helper method to safely bind an action if it exists in the action map
|
||||
private void TryBindAction(PlayerInput playerInput, string actionName, System.Action<InputAction.CallbackContext> callback)
|
||||
{
|
||||
InputAction action = playerInput.currentActionMap.FindAction(actionName);
|
||||
if (action != null)
|
||||
{
|
||||
action.performed += callback;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"Action '{actionName}' not found in current action map. Make sure to add it to your Input Actions asset.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// public void SpawnPlayers()
|
||||
// {
|
||||
// //return this mobile to false
|
||||
// isMobile = false;
|
||||
|
||||
// //determine platform
|
||||
// DeterminePlatform();
|
||||
|
||||
// //isAISelected boolean is switched in the ModeSelectionManager.cs
|
||||
// if (!isMobile)
|
||||
// {
|
||||
// if (isPlayerSelected)
|
||||
// {
|
||||
// if (selectedPlayerDevice == null)
|
||||
// {
|
||||
// selectedPlayerDevice = SelectionOptions.Instance.GetSelectedPlayerDevice();
|
||||
// }
|
||||
|
||||
// // Now you can iterate through playerDeviceDict and spawn players using the data
|
||||
|
||||
// foreach (var kvp in selectedPlayerDevice)
|
||||
// {
|
||||
// string playerName = kvp.Key;
|
||||
// PlayerInfo playerInfo = kvp.Value;
|
||||
// GameObject playerPrefab = gameObject; // Assuming your player prefab names match the player object names
|
||||
// if (playerName == "Windham")
|
||||
// {
|
||||
// playerPrefab = Resources.Load<GameObject>("Rabbit 2"); // Assuming your player prefab names match the player object names
|
||||
// }
|
||||
// else if (playerName == "Amira")
|
||||
// {
|
||||
// playerPrefab = Resources.Load<GameObject>("Cheetah 2"); // Assuming your player prefab names match the player object names
|
||||
// }
|
||||
// else if (playerName == "Bahman")
|
||||
// {
|
||||
// playerPrefab = Resources.Load<GameObject>("Eagle"); // Assuming your player prefab names match the player object names
|
||||
// }
|
||||
// else if (playerName == "Ziggy")
|
||||
// {
|
||||
// playerPrefab = Resources.Load<GameObject>("Cat"); // Assuming your player prefab names match the player object names
|
||||
// }
|
||||
// else if (playerName == "Imani")
|
||||
// {
|
||||
// playerPrefab = Resources.Load<GameObject>("Hyena"); // Assuming your player prefab names match the player object names
|
||||
// }
|
||||
// else if (playerName == "Amon")
|
||||
// {
|
||||
// playerPrefab = Resources.Load<GameObject>("Hammerhead"); // Assuming your player prefab names match the player object names
|
||||
// }
|
||||
// if (playerPrefab != null)
|
||||
// {
|
||||
// var player = PlayerInput.Instantiate(playerPrefab, controlScheme: playerInfo.ControlScheme, pairWithDevices: playerInfo.Device);
|
||||
// player.tag = "Player";
|
||||
// PlayerInput playerInput = player.GetComponent<PlayerInput>();
|
||||
// PlayerScript playerScript = player.GetComponent<PlayerScript>();
|
||||
// playerInput.neverAutoSwitchControlSchemes = true;
|
||||
// playerInput.defaultActionMap = "Player Controls";
|
||||
// playerInput.currentActionMap["Move"].performed += playerScript.OnMove;
|
||||
// playerInput.currentActionMap["Move"].canceled += playerScript.OnMove;
|
||||
// //punches
|
||||
// playerInput.currentActionMap["Jab"].performed += playerScript.OnJab;
|
||||
// playerInput.currentActionMap["Right"].performed += playerScript.OnRight;
|
||||
// playerInput.currentActionMap["LeftHook"].performed += playerScript.OnLeftHook;
|
||||
// playerInput.currentActionMap["RightHook"].performed += playerScript.OnRightHook;
|
||||
// playerInput.currentActionMap["LeftElbow"].performed += playerScript.OnLeftElbow;
|
||||
// playerInput.currentActionMap["RightElbow"].performed += playerScript.OnRightElbow;
|
||||
// playerInput.currentActionMap["RightBody"].performed += playerScript.OnRightBody;
|
||||
// playerInput.currentActionMap["PowerPunchLeft"].performed += playerScript.OnPowerPunchLeft;
|
||||
// playerInput.currentActionMap["SupermanPunch"].performed += playerScript.OnSupermanPunch;
|
||||
// //kicks
|
||||
// playerInput.currentActionMap["LegKickRight"].performed += playerScript.OnLegKickRight;
|
||||
// playerInput.currentActionMap["BodyKickRight"].performed += playerScript.OnBodyKickRight;
|
||||
// playerInput.currentActionMap["KneeRight"].performed += playerScript.OnKneeRight;
|
||||
// playerInput.currentActionMap["BackSideKick"].performed += playerScript.OnBackSideKick;
|
||||
// playerInput.currentActionMap["FrontKickRight"].performed += playerScript.OnFrontKickRight;
|
||||
// playerInput.currentActionMap["LegPowerKickRight"].performed += playerScript.OnLegPowerKickRight;
|
||||
// //dodges
|
||||
// playerInput.currentActionMap["JumpBack"].performed += playerScript.OnJumpBack;
|
||||
// playerInput.currentActionMap["JumpLeft"].performed += playerScript.OnJumpLeft;
|
||||
// playerInput.currentActionMap["JumpRight"].performed += playerScript.OnJumpRight;
|
||||
// //blocks
|
||||
// playerInput.currentActionMap["BlockStepBack"].performed += playerScript.OnBlockStepBack;
|
||||
// playerInput.currentActionMap["BlockBodyLeft"].performed += playerScript.OnBlockBodyLeft;
|
||||
// playerInput.currentActionMap["BlockLeg"].performed += playerScript.OnBlockLeg;
|
||||
|
||||
// playerInput.currentActionMap["Pause"].performed += player.GetComponent<HealthNew>().OnPause;
|
||||
// foreach (var pair in selectedPlayerDevice)
|
||||
// {
|
||||
// if (pair.Key == playerName)
|
||||
// {
|
||||
// count++;
|
||||
// if (count == 2)
|
||||
// {
|
||||
// player.gameObject.tag = "Enemy";
|
||||
// count = 0;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// SetUpCamera();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Debug.LogWarning($"Player prefab '{playerName}' not found in resources.");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// else if (isAISelected)
|
||||
// {
|
||||
// if (selectedPlayersAI == null)
|
||||
// {
|
||||
// selectedPlayersAI = SelectionOptions.Instance.GetSelectedPlayersAI();
|
||||
// }
|
||||
// foreach (var kvp in selectedPlayersAI)
|
||||
// {
|
||||
// string playerName = kvp.Key;
|
||||
// string playerMode = kvp.Value;
|
||||
// GameObject playerPrefab = gameObject;
|
||||
// playerPrefab = LoadPrefab(playerName, playerMode);
|
||||
// if (playerPrefab != null)
|
||||
// {
|
||||
// SetUpPlayerInput(playerPrefab, playerMode);
|
||||
// SetUpCamera();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Debug.LogWarning($"Player prefab '{playerName}' not found in resources.");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if (isAISelected)
|
||||
// {
|
||||
// if (selectedPlayersAI == null)
|
||||
// {
|
||||
// selectedPlayersAI = SelectionOptions.Instance.GetSelectedPlayersAI();
|
||||
// }
|
||||
// foreach (var kvp in selectedPlayersAI)
|
||||
// {
|
||||
// string playerName = kvp.Key;
|
||||
// string playerMode = kvp.Value;
|
||||
// GameObject playerPrefab = gameObject;
|
||||
// playerPrefab = LoadPrefab(playerName, playerMode);
|
||||
// if (playerPrefab != null)
|
||||
// {
|
||||
// SetUpPlayerInputAI(playerPrefab, playerMode);
|
||||
// SetUpCamera();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Debug.LogWarning($"Player prefab '{playerName}' not found in resources.");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6f83b90ca6e75da4dbaf889898a1779c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
36
Assets/Scripts/Character Selection System/ToggleAIPlayer.cs
Normal file
36
Assets/Scripts/Character Selection System/ToggleAIPlayer.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using TMPro;
|
||||
|
||||
public class ToggleAIPlayer : MonoBehaviour
|
||||
{
|
||||
public TMP_Text buttonText;
|
||||
|
||||
private string currentState = "AI"; // Default state is AI.
|
||||
|
||||
private void Start()
|
||||
{
|
||||
UpdateButtonText();
|
||||
buttonText.text = "AI";
|
||||
}
|
||||
|
||||
public void OnButtonClick()
|
||||
{
|
||||
// Toggle between 'AI' and 'Player'.
|
||||
if (currentState == "AI")
|
||||
{
|
||||
currentState = "LOCAL";
|
||||
}
|
||||
else if(currentState == "LOCAL")
|
||||
{
|
||||
currentState = "AI";
|
||||
}
|
||||
|
||||
UpdateButtonText();
|
||||
}
|
||||
|
||||
private void UpdateButtonText()
|
||||
{
|
||||
buttonText.text = currentState;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 519ac2f2cf6640b4e8a66767f0d37662
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user