chunk 1: core gameplay scripts scenes runtime assets

This commit is contained in:
2026-04-06 11:02:34 +03:00
parent fa0388bc79
commit 0d11a097d8
703 changed files with 2292651 additions and 0 deletions

View 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();
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 455a81dec040e964c8798d5e4ca4744d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 47a6ca989d901a74ab4ffd5e1b3b30bd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 221ca54e589f66849b74f9b482c837af
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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);*/

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c2ccb3df1dfc58b4c985ce7f80583b88
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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.");
// }
// }
// }
// }
// }
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6f83b90ca6e75da4dbaf889898a1779c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 519ac2f2cf6640b4e8a66767f0d37662
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: