chunk 1: core gameplay scripts scenes runtime assets
This commit is contained in:
465
Assets/Scripts/CashSystem/CashSystemCharacterSelection.cs
Normal file
465
Assets/Scripts/CashSystem/CashSystemCharacterSelection.cs
Normal file
@@ -0,0 +1,465 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.SceneManagement;
|
||||
using TMPro;
|
||||
|
||||
/// <summary>
|
||||
/// CashSystemCharacterSelection - Handles 3v3 team selection for Cash System mode.
|
||||
/// User can select any/all team members, or let the game auto-fill.
|
||||
/// Uses existing CharacterSelection data - no duplication.
|
||||
/// </summary>
|
||||
public class CashSystemCharacterSelection : MonoBehaviour
|
||||
{
|
||||
[Header("Team Slots - Assign the button GameObjects (3.1, 3.2, 3.3)")]
|
||||
[SerializeField] private Button[] teamSlotButtons; // All 3 slot buttons
|
||||
|
||||
[Header("Slot UI Components - Arrays aligned with teamSlotButtons")]
|
||||
[SerializeField] private Image[] slotImages; // Character images for each slot
|
||||
[SerializeField] private GameObject[] slotAddIcons; // "+" icons for each slot
|
||||
[SerializeField] private TextMeshProUGUI[] slotTexts; // Text labels
|
||||
|
||||
[Header("Confirm Button")]
|
||||
[SerializeField] private Button confirmButton;
|
||||
|
||||
[Header("References - Use existing systems")]
|
||||
[SerializeField] private ModeSelection modeSelection;
|
||||
|
||||
// Available characters - matches CharacterSelection order
|
||||
private readonly string[] allCharacters = { "Windham", "Amira", "Bahman", "Ziggy", "Amon", "Imani" };
|
||||
|
||||
// Team selection state
|
||||
private string[] playerTeam = new string[3];
|
||||
private string[] enemyTeam = new string[3];
|
||||
private int currentSlotSelecting = -1; // Which slot is currently being selected
|
||||
private int captainIndex = 0; // First selected becomes captain
|
||||
private bool captainChosen = false;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
// Only activate for Cash System mode
|
||||
if (SelectionOptions.Instance == null || !SelectionOptions.Instance.isCashSystemSelected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Only reset if we haven't started selecting yet
|
||||
// Don't reset if we're returning from character selection with a character chosen
|
||||
if (!captainChosen && string.IsNullOrEmpty(playerTeam[0]))
|
||||
{
|
||||
Debug.Log("[CashSystemCharacterSelection] Initializing 3v3 selection (first time)");
|
||||
ResetSelection();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("[CashSystemCharacterSelection] Returning to 3v3 selection (preserving state)");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reset all slots to initial state (show add icons, hide character images)
|
||||
/// </summary>
|
||||
public void ResetSelection()
|
||||
{
|
||||
captainChosen = false;
|
||||
captainIndex = 0;
|
||||
playerTeam = new string[3];
|
||||
enemyTeam = new string[3];
|
||||
currentSlotSelecting = -1;
|
||||
|
||||
// Reset all slots
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (i < slotImages.Length && slotImages[i] != null)
|
||||
slotImages[i].gameObject.SetActive(false);
|
||||
|
||||
if (i < slotAddIcons.Length && slotAddIcons[i] != null)
|
||||
slotAddIcons[i].SetActive(true);
|
||||
|
||||
if (i < slotTexts.Length && slotTexts[i] != null)
|
||||
slotTexts[i].text = i == 0 ? "CAPTAIN" : "TEAMMATE";
|
||||
}
|
||||
|
||||
// Disable confirm until at least captain is selected
|
||||
if (confirmButton != null) confirmButton.interactable = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when ANY slot button is clicked - opens character selection for that slot
|
||||
/// </summary>
|
||||
public void OnSlotClicked(int slotIndex)
|
||||
{
|
||||
if (slotIndex < 0 || slotIndex >= 3) return;
|
||||
|
||||
Debug.Log($"[CashSystemCharacterSelection] Slot {slotIndex + 1} clicked - opening character selection");
|
||||
|
||||
currentSlotSelecting = slotIndex;
|
||||
|
||||
// Navigate to character selection screen using existing ModeSelection
|
||||
if (modeSelection != null && modeSelection.selectionScreen != null)
|
||||
{
|
||||
// Hide 3v3 graphic temporarily
|
||||
modeSelection.graphic3v3.SetActive(false);
|
||||
|
||||
// Hide mode selection screen (parent screen that may be covering)
|
||||
if (modeSelection.modeSelectionScreen != null)
|
||||
{
|
||||
modeSelection.modeSelectionScreen.SetActive(false);
|
||||
}
|
||||
|
||||
// Show character selection screen
|
||||
modeSelection.selectionScreen.SetActive(true);
|
||||
|
||||
// Add listeners using existing system
|
||||
if (modeSelection.CharacterSelectionScript != null)
|
||||
{
|
||||
var charSelect = modeSelection.CharacterSelectionScript;
|
||||
|
||||
if (charSelect.selectCharacterButton != null)
|
||||
{
|
||||
charSelect.selectCharacterButton.onClick.AddListener(modeSelection.onSelectionScreenSelectClick);
|
||||
}
|
||||
|
||||
if (charSelect.backButton != null)
|
||||
{
|
||||
charSelect.backButton.onClick.AddListener(OnCharacterSelectionBack);
|
||||
}
|
||||
|
||||
// Select first character button
|
||||
if (charSelect.buttons != null && charSelect.buttons.Length > 0)
|
||||
{
|
||||
charSelect.buttons[0].Select();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convenience methods for button OnClick - call OnSlotClicked with correct index
|
||||
public void OnSlot1Clicked() => OnSlotClicked(0);
|
||||
public void OnSlot2Clicked() => OnSlotClicked(1);
|
||||
public void OnSlot3Clicked() => OnSlotClicked(2);
|
||||
|
||||
/// <summary>
|
||||
/// Called when a character is selected from the character selection screen
|
||||
/// </summary>
|
||||
public void OnCharacterSelected(string characterName)
|
||||
{
|
||||
Debug.Log($"[CashSystemCharacterSelection] OnCharacterSelected called with: {characterName}, currentSlotSelecting: {currentSlotSelecting}");
|
||||
|
||||
if (currentSlotSelecting < 0 || currentSlotSelecting >= 3)
|
||||
{
|
||||
Debug.LogWarning("[CashSystemCharacterSelection] No slot was being selected!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if character is already selected in another slot
|
||||
for (int i = 0; i < playerTeam.Length; i++)
|
||||
{
|
||||
if (playerTeam[i] == characterName && i != currentSlotSelecting)
|
||||
{
|
||||
Debug.LogWarning($"[CashSystemCharacterSelection] {characterName} already selected in slot {i + 1}");
|
||||
// Could show a warning UI here
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Log($"[CashSystemCharacterSelection] Slot {currentSlotSelecting + 1} selected: {characterName}");
|
||||
|
||||
// Set the character for this slot
|
||||
playerTeam[currentSlotSelecting] = characterName;
|
||||
|
||||
// First selection becomes captain - auto-fill other slots immediately
|
||||
if (!captainChosen)
|
||||
{
|
||||
captainIndex = currentSlotSelecting;
|
||||
captainChosen = true;
|
||||
Debug.Log($"[CashSystemCharacterSelection] Captain set to slot {captainIndex + 1}");
|
||||
|
||||
// Auto-fill other slots immediately after captain selection
|
||||
AutoFillEmptySlots();
|
||||
}
|
||||
|
||||
// Update slot UI - use existing CharacterSelection sprites
|
||||
Debug.Log($"[CashSystemCharacterSelection] Calling UpdateSlotUI for slot {currentSlotSelecting}");
|
||||
UpdateSlotUI(currentSlotSelecting, characterName);
|
||||
|
||||
// Enable confirm button since at least captain is selected
|
||||
if (confirmButton != null) confirmButton.interactable = true;
|
||||
|
||||
int slotThatWasSelected = currentSlotSelecting;
|
||||
currentSlotSelecting = -1;
|
||||
|
||||
Debug.Log($"[CashSystemCharacterSelection] Character selection complete for slot {slotThatWasSelected + 1}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update a slot's UI with the selected character - uses existing CharacterSelection data
|
||||
/// </summary>
|
||||
private void UpdateSlotUI(int slotIndex, string characterName)
|
||||
{
|
||||
Debug.Log($"[CashSystemCharacterSelection] UpdateSlotUI - slotIndex: {slotIndex}, characterName: {characterName}");
|
||||
|
||||
if (slotIndex < 0 || slotIndex >= 3) return;
|
||||
|
||||
// Hide add icon
|
||||
if (slotIndex < slotAddIcons.Length && slotAddIcons[slotIndex] != null)
|
||||
{
|
||||
slotAddIcons[slotIndex].SetActive(false);
|
||||
Debug.Log($"[CashSystemCharacterSelection] Hidden add icon for slot {slotIndex + 1}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"[CashSystemCharacterSelection] slotAddIcons not assigned for index {slotIndex}");
|
||||
}
|
||||
|
||||
// Show and set character image - get from existing CharacterSelection
|
||||
if (slotIndex < slotImages.Length && slotImages[slotIndex] != null)
|
||||
{
|
||||
slotImages[slotIndex].gameObject.SetActive(true);
|
||||
|
||||
// Get sprite from CharacterSelection
|
||||
Sprite characterSprite = GetCharacterSprite(characterName);
|
||||
if (characterSprite != null)
|
||||
{
|
||||
slotImages[slotIndex].sprite = characterSprite;
|
||||
Debug.Log($"[CashSystemCharacterSelection] Set sprite for slot {slotIndex + 1}: {characterSprite.name}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"[CashSystemCharacterSelection] Could not find sprite for {characterName}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"[CashSystemCharacterSelection] slotImages not assigned for index {slotIndex}. Array length: {slotImages?.Length ?? 0}");
|
||||
}
|
||||
|
||||
// Update text
|
||||
if (slotIndex < slotTexts.Length && slotTexts[slotIndex] != null)
|
||||
{
|
||||
string label = characterName.ToUpper();
|
||||
if (slotIndex == captainIndex)
|
||||
{
|
||||
label += " ★"; // Mark captain
|
||||
}
|
||||
slotTexts[slotIndex].text = label;
|
||||
Debug.Log($"[CashSystemCharacterSelection] Set text for slot {slotIndex + 1}: {label}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"[CashSystemCharacterSelection] slotTexts not assigned for index {slotIndex}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get character sprite from existing CharacterSelection - no duplication
|
||||
/// </summary>
|
||||
private Sprite GetCharacterSprite(string characterName)
|
||||
{
|
||||
if (modeSelection == null || modeSelection.CharacterSelectionScript == null)
|
||||
return null;
|
||||
|
||||
var charSelect = modeSelection.CharacterSelectionScript;
|
||||
|
||||
// Find character index
|
||||
for (int i = 0; i < charSelect.characterNames.Length; i++)
|
||||
{
|
||||
if (charSelect.characterNames[i].Equals(characterName, System.StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (i < charSelect.characterImages.Length)
|
||||
{
|
||||
return charSelect.characterImages[i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when back is pressed in character selection
|
||||
/// </summary>
|
||||
private void OnCharacterSelectionBack()
|
||||
{
|
||||
currentSlotSelecting = -1;
|
||||
|
||||
if (modeSelection != null)
|
||||
{
|
||||
// Hide selection screen
|
||||
modeSelection.selectionScreen.SetActive(false);
|
||||
|
||||
// Show mode selection screen again
|
||||
if (modeSelection.modeSelectionScreen != null)
|
||||
{
|
||||
modeSelection.modeSelectionScreen.SetActive(true);
|
||||
}
|
||||
|
||||
// Show 3v3 graphic again
|
||||
modeSelection.graphic3v3.SetActive(true);
|
||||
|
||||
// Remove listeners
|
||||
if (modeSelection.CharacterSelectionScript != null)
|
||||
{
|
||||
var charSelect = modeSelection.CharacterSelectionScript;
|
||||
charSelect.selectCharacterButton.onClick.RemoveListener(modeSelection.onSelectionScreenSelectClick);
|
||||
charSelect.backButton.onClick.RemoveListener(OnCharacterSelectionBack);
|
||||
}
|
||||
|
||||
// Select the slot that was being edited
|
||||
if (teamSlotButtons != null && teamSlotButtons.Length > 0)
|
||||
{
|
||||
teamSlotButtons[0].Select();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when Confirm button is clicked - auto-fill empty slots and start game
|
||||
/// </summary>
|
||||
public void OnConfirmClicked()
|
||||
{
|
||||
Debug.Log("[CashSystemCharacterSelection] OnConfirmClicked called!");
|
||||
|
||||
if (!captainChosen)
|
||||
{
|
||||
Debug.LogWarning("[CashSystemCharacterSelection] Cannot confirm - no captain selected!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Auto-fill any empty slots with random characters (should already be filled)
|
||||
AutoFillEmptySlots();
|
||||
|
||||
// Generate enemy team
|
||||
GenerateEnemyTeam();
|
||||
|
||||
Debug.Log($"[CashSystemCharacterSelection] Final Player Team: {string.Join(", ", playerTeam)}");
|
||||
Debug.Log($"[CashSystemCharacterSelection] Final Enemy Team: {string.Join(", ", enemyTeam)}");
|
||||
Debug.Log($"[CashSystemCharacterSelection] Captain Index: {captainIndex}");
|
||||
|
||||
// Save team data to SelectionOptions
|
||||
if (SelectionOptions.Instance != null)
|
||||
{
|
||||
SelectionOptions.Instance.playerTeam = playerTeam;
|
||||
SelectionOptions.Instance.enemyTeam = enemyTeam;
|
||||
SelectionOptions.Instance.captainIndex = captainIndex;
|
||||
SelectionOptions.Instance.currentControlledIndex = captainIndex;
|
||||
|
||||
// Store portrait sprites so the Game scene can display them
|
||||
SelectionOptions.Instance.playerTeamSprites = new Sprite[3];
|
||||
SelectionOptions.Instance.enemyTeamSprites = new Sprite[3];
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
SelectionOptions.Instance.playerTeamSprites[i] = GetCharacterSprite(playerTeam[i]);
|
||||
SelectionOptions.Instance.enemyTeamSprites[i] = GetCharacterSprite(enemyTeam[i]);
|
||||
}
|
||||
|
||||
Debug.Log("[CashSystemCharacterSelection] Saved team data + sprites to SelectionOptions");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("[CashSystemCharacterSelection] SelectionOptions.Instance is null!");
|
||||
}
|
||||
|
||||
// Set game mode
|
||||
if (SelectionOptions.Instance != null)
|
||||
{
|
||||
SelectionOptions.Instance.isCashSystemSelected = true;
|
||||
Debug.Log("[CashSystemCharacterSelection] Set isCashSystemSelected = true");
|
||||
}
|
||||
|
||||
if (GameManager.Instance != null)
|
||||
{
|
||||
GameManager.Instance.currentGameMode = GameMode.CashSystem;
|
||||
Debug.Log("[CashSystemCharacterSelection] Set game mode to CashSystem");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("[CashSystemCharacterSelection] GameManager.Instance is null!");
|
||||
}
|
||||
|
||||
// Load game scene
|
||||
Debug.Log("[CashSystemCharacterSelection] Loading Game scene...");
|
||||
SceneManager.LoadScene("Game");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Auto-fill any empty player team slots with random available characters
|
||||
/// </summary>
|
||||
private void AutoFillEmptySlots()
|
||||
{
|
||||
// Get list of available characters (not already selected)
|
||||
var available = new System.Collections.Generic.List<string>(allCharacters);
|
||||
foreach (string selected in playerTeam)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(selected))
|
||||
{
|
||||
available.Remove(selected);
|
||||
}
|
||||
}
|
||||
|
||||
// Shuffle available
|
||||
for (int i = available.Count - 1; i > 0; i--)
|
||||
{
|
||||
int j = Random.Range(0, i + 1);
|
||||
string temp = available[i];
|
||||
available[i] = available[j];
|
||||
available[j] = temp;
|
||||
}
|
||||
|
||||
// Fill empty slots
|
||||
int availableIndex = 0;
|
||||
for (int i = 0; i < playerTeam.Length; i++)
|
||||
{
|
||||
if (string.IsNullOrEmpty(playerTeam[i]) && availableIndex < available.Count)
|
||||
{
|
||||
playerTeam[i] = available[availableIndex];
|
||||
UpdateSlotUI(i, playerTeam[i]);
|
||||
availableIndex++;
|
||||
Debug.Log($"[CashSystemCharacterSelection] Auto-filled slot {i + 1} with {playerTeam[i]}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate enemy team from remaining characters
|
||||
/// </summary>
|
||||
private void GenerateEnemyTeam()
|
||||
{
|
||||
// Get characters not in player team
|
||||
var available = new System.Collections.Generic.List<string>(allCharacters);
|
||||
foreach (string selected in playerTeam)
|
||||
{
|
||||
available.Remove(selected);
|
||||
}
|
||||
|
||||
// Shuffle and assign
|
||||
for (int i = available.Count - 1; i > 0; i--)
|
||||
{
|
||||
int j = Random.Range(0, i + 1);
|
||||
string temp = available[i];
|
||||
available[i] = available[j];
|
||||
available[j] = temp;
|
||||
}
|
||||
|
||||
for (int i = 0; i < enemyTeam.Length && i < available.Count; i++)
|
||||
{
|
||||
enemyTeam[i] = available[i];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when Back button in 3v3 screen is clicked
|
||||
/// </summary>
|
||||
public void OnBackClicked()
|
||||
{
|
||||
ResetSelection();
|
||||
SelectionOptions.Instance.isCashSystemSelected = false;
|
||||
|
||||
// Navigate back to mode selection
|
||||
if (modeSelection != null)
|
||||
{
|
||||
modeSelection.graphic3v3.SetActive(false);
|
||||
// Return to home or mode selection
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user