2025-09-19 19:43:49 +05:00
using System.Collections ;
2025-09-19 14:56:58 +05:00
using System.Collections.Generic ;
using TMPro ;
using UnityEngine ;
using UnityEngine.Events ;
using UnityEngine.UI ;
namespace BulletHellTemplate
{
/// <summary>
2025-09-19 19:43:49 +05:00
/// Manages the profile menu UI, including displaying player information (name, icon, frame), favorite character data,
/// audio sliders, localized status messages, and *toggleable* icon / frame selection panels.
/// <para>Buttons that previously called <see cref="LoadIcons"/> or <see cref="LoadFrames"/> directly can remain wired the same way: each method now behaves as a toggle. If the requested content is already visible, the call will close the container; otherwise it will open the container and (re)build the corresponding entries.</para>
/// <para>The container now starts <b>closed</b> every time the menu is enabled.</para>
2025-09-19 14:56:58 +05:00
/// </summary>
public class UIProfileMenu : MonoBehaviour
{
2025-09-19 19:43:49 +05:00
/*────────────────────────────────────────────────────────────────────────────*/
#region Inspector Fields
2025-09-19 14:56:58 +05:00
[Header("UI Elements")]
[Tooltip("Text component to display the player's name.")]
public TextMeshProUGUI playerName ;
2025-09-19 19:43:49 +05:00
2025-09-19 14:56:58 +05:00
[Tooltip("Image component to display the player's icon.")]
public Image playerIcon ;
2025-09-19 19:43:49 +05:00
2025-09-19 14:56:58 +05:00
[Tooltip("Image component to display the player's frame.")]
public Image playerFrame ;
[Header("UI Prefabs")]
[Tooltip("Prefab for creating icon entries.")]
public IconsEntry iconsEntryPrefab ;
2025-09-19 19:43:49 +05:00
2025-09-19 14:56:58 +05:00
[Tooltip("Prefab for creating frame entries.")]
public FramesEntry framesEntryPrefab ;
2025-09-19 19:43:49 +05:00
2025-09-19 14:56:58 +05:00
[Tooltip("Container to hold dynamically created icon and frame entries.")]
public Transform container ;
2025-09-19 19:43:49 +05:00
2025-09-19 14:56:58 +05:00
[Tooltip("Container GameObject for icons/frames.")]
public GameObject containerPref ;
2025-09-19 19:43:49 +05:00
[Tooltip("UI passEntryPrefab for the name change input screen.")]
2025-09-19 14:56:58 +05:00
public GameObject changeNamePref ;
2025-09-19 19:43:49 +05:00
2025-09-19 14:56:58 +05:00
[Tooltip("Input field for entering a new name.")]
public TMP_InputField changeNameInput ;
2025-09-19 19:43:49 +05:00
2025-09-19 14:56:58 +05:00
[Tooltip("UI component to display status messages (success/error).")]
public TextMeshProUGUI statusText ;
[Header("Favorite character")]
[Tooltip("Image to display mastery icon of the favorite character.")]
public Image masteryIcon ;
2025-09-19 19:43:49 +05:00
2025-09-19 14:56:58 +05:00
[Tooltip("Image fill component to display mastery progress.")]
public Image masteryProgressBar ;
2025-09-19 19:43:49 +05:00
2025-09-19 14:56:58 +05:00
[Tooltip("UI text to display current mastery experience.")]
public TextMeshProUGUI currentMasteryExp ;
2025-09-19 19:43:49 +05:00
2025-09-19 14:56:58 +05:00
[Tooltip("UI text to display the mastery level name.")]
public TextMeshProUGUI masteryName ;
2025-09-19 19:43:49 +05:00
2025-09-19 14:56:58 +05:00
[Tooltip("Container to hold the temporary favorite character model.")]
public Transform tempCharacterContainer ;
[Header("UI Translations")]
[Tooltip("Fallback message when there are not enough tickets to change the name.")]
public string notEnoughTickets = "Not enough tickets to change the name." ;
[Tooltip("Translations for the message when there are not enough tickets to change the name.")]
public NameTranslatedByLanguage [ ] notEnoughTicketsTranslated ;
[Tooltip("Fallback message when name length is invalid.")]
public string nameLengthError = "Name must be between 3 and 14 characters." ;
[Tooltip("Translations for the message when name length is invalid.")]
public NameTranslatedByLanguage [ ] nameLengthErrorTranslated ;
[Tooltip("Fallback message when the name is already taken.")]
public string nameAlreadyTaken = "Name already taken." ;
[Tooltip("Translations for the message when the name is already taken.")]
public NameTranslatedByLanguage [ ] nameAlreadyTakenTranslated ;
[Tooltip("Fallback message when the name is changed successfully.")]
public string nameChangeSuccess = "Name changed successfully." ;
[Tooltip("Translations for the message when the name is changed successfully.")]
public NameTranslatedByLanguage [ ] nameChangeSuccessTranslated ;
[Tooltip("Fallback message when there's an error changing the name.")]
public string nameChangeFail = "Error changing name." ;
[Tooltip("Translations for the message when there's an error changing the name.")]
public NameTranslatedByLanguage [ ] nameChangeFailTranslated ;
[Header("Events")]
[Tooltip("Event invoked when the menu is opened.")]
public UnityEvent OnOpenMenu ;
[Tooltip("Event invoked when the menu is closed.")]
public UnityEvent OnCloseMenu ;
[Tooltip("Event invoked when the nickname is successfully changed.")]
public UnityEvent OnChangeNickname ;
[Tooltip("Event invoked when the icon is successfully changed.")]
public UnityEvent OnChangeIcon ;
[Tooltip("Event invoked when the frame is successfully changed.")]
public UnityEvent OnChangeFrame ;
[Tooltip("Event invoked when a coupon is redeemed successfully.")]
public UnityEvent OnRedeemCoupon ;
[Header("Audio Settings")]
[Tooltip("Slider for adjusting master volume.")]
public Slider masterVolumeSlider ;
2025-09-19 19:43:49 +05:00
2025-09-19 14:56:58 +05:00
[Tooltip("Slider for adjusting VFX volume.")]
public Slider vfxVolumeSlider ;
2025-09-19 19:43:49 +05:00
2025-09-19 14:56:58 +05:00
[Tooltip("Slider for adjusting ambience volume.")]
public Slider ambienceVolumeSlider ;
2025-09-19 19:43:49 +05:00
#endregion
/*────────────────────────────────────────────────────────────────────────────*/
/*────────────────────────────────────────────────────────────────────────────*/
#region Private Runtime State
2025-09-19 14:56:58 +05:00
private string currentLang ;
2025-09-19 19:43:49 +05:00
private readonly List < IconsEntry > iconsEntries = new ( ) ;
private readonly List < FramesEntry > framesEntries = new ( ) ;
public static UIProfileMenu Singleton ; // maintained for legacy usages
2025-09-19 14:56:58 +05:00
/// <summary>
2025-09-19 19:43:49 +05:00
/// Runtime state for the dynamic selection container.
2025-09-19 14:56:58 +05:00
/// </summary>
2025-09-19 19:43:49 +05:00
private enum ContentState { Closed , Icons , Frames }
private ContentState _contentState = ContentState . Closed ;
#endregion
/*────────────────────────────────────────────────────────────────────────────*/
#region Unity Lifecycle
2025-09-19 14:56:58 +05:00
private void Awake ( )
{
LanguageManager . LanguageManager . onLanguageChanged + = UpdateText ;
Singleton = this ;
}
private void OnDestroy ( )
{
LanguageManager . LanguageManager . onLanguageChanged - = UpdateText ;
}
private void OnEnable ( )
{
currentLang = LanguageManager . LanguageManager . Instance . GetCurrentLanguage ( ) ;
2025-09-19 19:43:49 +05:00
OnOpenMenu ? . Invoke ( ) ;
2025-09-19 14:56:58 +05:00
DestroyTemporaryModel ( ) ;
LoadProfile ( ) ;
LoadFavoriteCharacter ( ) ;
2025-09-19 19:43:49 +05:00
UpdateText ( ) ;
2025-09-19 14:56:58 +05:00
SetupSliders ( ) ;
2025-09-19 19:43:49 +05:00
// Ensure the selection container starts closed when menu opens.
HideContainer ( ) ;
2025-09-19 14:56:58 +05:00
}
private void OnDisable ( )
{
DestroyTemporaryModel ( ) ;
2025-09-19 19:43:49 +05:00
HideContainer ( ) ;
OnCloseMenu ? . Invoke ( ) ;
if ( UIMainMenu . Singleton ! = null )
UIMainMenu . Singleton . LoadPlayerInfo ( ) ;
2025-09-19 14:56:58 +05:00
}
2025-09-19 19:43:49 +05:00
#endregion
2025-09-19 14:56:58 +05:00
2025-09-19 19:43:49 +05:00
#region Language & Localization
2025-09-19 14:56:58 +05:00
private void UpdateText ( )
{
currentLang = LanguageManager . LanguageManager . Instance . GetCurrentLanguage ( ) ;
LoadFavoriteCharacter ( ) ;
}
2025-09-19 19:43:49 +05:00
#endregion
2025-09-19 14:56:58 +05:00
2025-09-19 19:43:49 +05:00
#region Profile Loading
2025-09-19 14:56:58 +05:00
/// <summary>
2025-09-19 19:43:49 +05:00
/// Loads and displays the player's profile information (name, icon, frame).
/// NOTE: No longer toggles the icon/frame container; that behavior is handled
/// by <see cref="LoadIcons"/> / <see cref="LoadFrames"/> toggle methods.
2025-09-19 14:56:58 +05:00
/// </summary>
public void LoadProfile ( )
{
string name = PlayerSave . GetPlayerName ( ) ;
2025-09-19 19:43:49 +05:00
if ( playerName ! = null )
playerName . text = ! string . IsNullOrEmpty ( name ) ? name : "Unknown Player" ;
2025-09-19 14:56:58 +05:00
string iconId = PlayerSave . GetPlayerIcon ( ) ;
string frameId = PlayerSave . GetPlayerFrame ( ) ;
SetPlayerIcon ( iconId ) ;
SetPlayerFrame ( frameId ) ;
}
2025-09-19 19:43:49 +05:00
#endregion
2025-09-19 14:56:58 +05:00
2025-09-19 19:43:49 +05:00
#region Audio Sliders
2025-09-19 14:56:58 +05:00
/// <summary>
2025-09-19 19:43:49 +05:00
/// Initialize sliders from persisted audio values and hook change events.
/// Uses <see cref="AudioManager"/> setters (which also persist changes).
2025-09-19 14:56:58 +05:00
/// </summary>
private void SetupSliders ( )
{
2025-09-19 19:43:49 +05:00
var am = AudioManager . Singleton ;
if ( am = = null )
return ;
2025-09-19 14:56:58 +05:00
if ( masterVolumeSlider ! = null )
{
masterVolumeSlider . onValueChanged . RemoveAllListeners ( ) ;
2025-09-19 19:43:49 +05:00
masterVolumeSlider . SetValueWithoutNotify ( am . masterVolume ) ; // start from saved
2025-09-19 14:56:58 +05:00
masterVolumeSlider . onValueChanged . AddListener ( OnMasterVolumeChanged ) ;
}
if ( vfxVolumeSlider ! = null )
{
vfxVolumeSlider . onValueChanged . RemoveAllListeners ( ) ;
2025-09-19 19:43:49 +05:00
vfxVolumeSlider . SetValueWithoutNotify ( am . vfxVolume ) ; // start from saved
2025-09-19 14:56:58 +05:00
vfxVolumeSlider . onValueChanged . AddListener ( OnVFXVolumeChanged ) ;
}
if ( ambienceVolumeSlider ! = null )
{
ambienceVolumeSlider . onValueChanged . RemoveAllListeners ( ) ;
2025-09-19 19:43:49 +05:00
ambienceVolumeSlider . SetValueWithoutNotify ( am . ambienceVolume ) ; // start from saved
2025-09-19 14:56:58 +05:00
ambienceVolumeSlider . onValueChanged . AddListener ( OnAmbienceVolumeChanged ) ;
}
}
2025-09-19 19:43:49 +05:00
/// <summary>Called by Master slider – forwards to <see cref="AudioManager.SetMasterVolume"/>.</summary>
2025-09-19 14:56:58 +05:00
public void OnMasterVolumeChanged ( float value )
{
2025-09-19 19:43:49 +05:00
var am = AudioManager . Singleton ;
if ( am ! = null )
am . SetMasterVolume ( value ) ;
2025-09-19 14:56:58 +05:00
}
2025-09-19 19:43:49 +05:00
/// <summary>Called by VFX slider – forwards to <see cref="AudioManager.SetVFXVolume"/>.</summary>
2025-09-19 14:56:58 +05:00
public void OnVFXVolumeChanged ( float value )
{
2025-09-19 19:43:49 +05:00
var am = AudioManager . Singleton ;
if ( am ! = null )
am . SetVFXVolume ( value ) ;
2025-09-19 14:56:58 +05:00
}
2025-09-19 19:43:49 +05:00
/// <summary>Called by Ambience slider – forwards to <see cref="AudioManager.SetAmbienceVolume"/>.</summary>
2025-09-19 14:56:58 +05:00
public void OnAmbienceVolumeChanged ( float value )
{
2025-09-19 19:43:49 +05:00
var am = AudioManager . Singleton ;
if ( am ! = null )
am . SetAmbienceVolume ( value ) ;
2025-09-19 14:56:58 +05:00
}
2025-09-19 19:43:49 +05:00
#endregion
2025-09-19 14:56:58 +05:00
2025-09-19 19:43:49 +05:00
/*────────────────────────────────────────────────────────────────────────────*/
#region Toggle Container API ( Call These From Buttons )
2025-09-19 14:56:58 +05:00
/// <summary>
2025-09-19 19:43:49 +05:00
/// Toggle the icon selection panel. If icons are visible, closes the panel.
/// If closed or currently showing frames, shows icons.
2025-09-19 14:56:58 +05:00
/// </summary>
public void LoadIcons ( )
{
2025-09-19 19:43:49 +05:00
if ( _contentState = = ContentState . Icons & & containerPref ! = null & & containerPref . activeSelf )
2025-09-19 14:56:58 +05:00
{
2025-09-19 19:43:49 +05:00
HideContainer ( ) ;
return ;
2025-09-19 14:56:58 +05:00
}
2025-09-19 19:43:49 +05:00
ShowIcons ( ) ;
}
2025-09-19 14:56:58 +05:00
2025-09-19 19:43:49 +05:00
/// <summary>
/// Toggle the frame selection panel. If frames are visible, closes the panel.
/// If closed or currently showing icons, shows frames.
/// </summary>
public void LoadFrames ( )
{
if ( _contentState = = ContentState . Frames & & containerPref ! = null & & containerPref . activeSelf )
{
HideContainer ( ) ;
return ;
}
ShowFrames ( ) ;
}
#endregion
#region Internal Build Helpers
private void ShowIcons ( )
{
ClearContainer ( ) ;
if ( containerPref ! = null )
containerPref . SetActive ( true ) ;
BuildIcons ( ) ;
_contentState = ContentState . Icons ;
}
private void ShowFrames ( )
{
ClearContainer ( ) ;
if ( containerPref ! = null )
containerPref . SetActive ( true ) ;
BuildFrames ( ) ;
_contentState = ContentState . Frames ;
}
private void HideContainer ( )
{
ClearContainer ( ) ;
if ( containerPref ! = null & & containerPref . activeSelf )
containerPref . SetActive ( false ) ;
_contentState = ContentState . Closed ;
}
private void ClearContainer ( )
{
iconsEntries . Clear ( ) ;
framesEntries . Clear ( ) ;
if ( container = = null )
return ;
for ( int i = container . childCount - 1 ; i > = 0 ; - - i )
{
Destroy ( container . GetChild ( i ) . gameObject ) ;
}
}
/// <summary>
/// Build icon entry UI elements into the container (assumes container active/cleared).
/// </summary>
private void BuildIcons ( )
{
if ( container = = null | | iconsEntryPrefab = = null | | GameInstance . Singleton = = null )
return ;
2025-09-19 14:56:58 +05:00
foreach ( IconItem item in GameInstance . Singleton . iconItems )
{
2025-09-19 19:43:49 +05:00
if ( PlayerSave . IsIconPurchased ( item . iconId ) | | item . isUnlocked )
2025-09-19 14:56:58 +05:00
{
IconsEntry iconEntry = Instantiate ( iconsEntryPrefab , container ) ;
iconEntry . SetIconInfo ( item . iconId ) ;
iconEntry . icon . sprite = item . icon ;
string iconNameTranslatedName = GetTranslatedString ( item . iconNameTranslated , item . iconName , currentLang ) ;
iconEntry . iconName . text = iconNameTranslatedName ;
iconsEntries . Add ( iconEntry ) ;
}
}
}
/// <summary>
2025-09-19 19:43:49 +05:00
/// Build frame entry UI elements into the container (assumes container active/cleared).
2025-09-19 14:56:58 +05:00
/// </summary>
2025-09-19 19:43:49 +05:00
private void BuildFrames ( )
2025-09-19 14:56:58 +05:00
{
2025-09-19 19:43:49 +05:00
if ( container = = null | | framesEntryPrefab = = null | | GameInstance . Singleton = = null )
return ;
2025-09-19 14:56:58 +05:00
foreach ( FrameItem item in GameInstance . Singleton . frameItems )
{
2025-09-19 19:43:49 +05:00
if ( PlayerSave . IsFramePurchased ( item . frameId ) | | item . isUnlocked )
2025-09-19 14:56:58 +05:00
{
FramesEntry frameEntry = Instantiate ( framesEntryPrefab , container ) ;
frameEntry . SetFrameInfo ( item . frameId ) ;
2025-09-19 19:43:49 +05:00
string frameNameTranslatedName = GetTranslatedString ( item . frameNameTranslated , item . frameName , currentLang ) ;
2025-09-19 14:56:58 +05:00
frameEntry . icon . sprite = item . icon ;
frameEntry . frameName . text = frameNameTranslatedName ;
framesEntries . Add ( frameEntry ) ;
}
}
}
2025-09-19 19:43:49 +05:00
#endregion
2025-09-19 14:56:58 +05:00
2025-09-19 19:43:49 +05:00
/*────────────────────────────────────────────────────────────────────────────*/
#region Favorite Character
2025-09-19 14:56:58 +05:00
public void LoadFavoriteCharacter ( )
{
int favouriteCharacterId = PlayerSave . GetFavouriteCharacter ( ) ;
int currentMasteryLevel = PlayerSave . GetCharacterMasteryLevel ( favouriteCharacterId ) ;
int currMasteryExp = PlayerSave . GetCharacterCurrentMasteryExp ( favouriteCharacterId ) ;
CharacterMasteryLevel masteryInfo = GameInstance . Singleton . GetMasteryLevel ( currentMasteryLevel ) ;
string masteryTranslatedName = GetTranslatedString ( masteryInfo . masteryNameTranslated , masteryInfo . masteryName , currentLang ) ;
if ( masteryName ! = null ) masteryName . text = masteryTranslatedName ;
if ( masteryIcon ! = null ) masteryIcon . sprite = masteryInfo . masteryIcon ;
if ( currentMasteryLevel < GameInstance . Singleton . characterMastery . maxMasteryLevel )
{
int requiredMasteryExp = GameInstance . Singleton . GetMasteryExpForLevel ( currentMasteryLevel ) ;
if ( currentMasteryExp ! = null ) currentMasteryExp . text = $"{currMasteryExp}/{requiredMasteryExp}" ;
if ( masteryProgressBar ! = null ) masteryProgressBar . fillAmount = ( float ) currMasteryExp / requiredMasteryExp ;
}
else
{
if ( currentMasteryExp ! = null ) currentMasteryExp . text = $"{currMasteryExp}/MAX" ;
if ( masteryProgressBar ! = null ) masteryProgressBar . fillAmount = 1f ;
}
2025-09-19 19:43:49 +05:00
// Rebuild the temporary model visual
DestroyTemporaryModel ( ) ;
2025-09-19 14:56:58 +05:00
CharacterData cd = GetCharacterDataById ( favouriteCharacterId ) ;
if ( cd ! = null & & tempCharacterContainer ! = null )
{
int skinIndex = PlayerSave . GetCharacterSkin ( cd . characterId ) ;
if ( cd . characterSkins ! = null & & cd . characterSkins . Length > 0 & & skinIndex > = 0 & & skinIndex < cd . characterSkins . Length )
{
CharacterSkin skin = cd . characterSkins [ skinIndex ] ;
if ( skin . skinCharacterModel ! = null )
Instantiate ( skin . skinCharacterModel , tempCharacterContainer ) ;
}
else if ( cd . characterModel ! = null )
{
Instantiate ( cd . characterModel , tempCharacterContainer ) ;
}
}
}
2025-09-19 19:43:49 +05:00
#endregion
2025-09-19 14:56:58 +05:00
2025-09-19 19:43:49 +05:00
/*────────────────────────────────────────────────────────────────────────────*/
#region Name Change Flow
2025-09-19 14:56:58 +05:00
public void OnClickChangeName ( )
{
2025-09-19 19:43:49 +05:00
if ( GameInstance . Singleton . needTicket & & MonetizationManager . GetCurrency ( GameInstance . Singleton . changeNameTick ) < GameInstance . Singleton . ticketsToChange )
2025-09-19 14:56:58 +05:00
{
DisplayStatusMessage ( GetTranslatedString ( notEnoughTicketsTranslated , notEnoughTickets , currentLang ) , Color . red ) ;
return ;
}
2025-09-19 19:43:49 +05:00
if ( changeNamePref ! = null )
changeNamePref . SetActive ( true ) ;
2025-09-19 14:56:58 +05:00
}
2025-09-19 19:43:49 +05:00
public async void ProcessChangeName ( )
2025-09-19 14:56:58 +05:00
{
string newName = changeNameInput . text ;
2025-09-19 19:43:49 +05:00
RequestResult res = await BackendManager . Service . ChangePlayerNameAsync ( newName ) ;
2025-09-19 14:56:58 +05:00
2025-09-19 19:43:49 +05:00
string msg ;
Color color ;
2025-09-19 14:56:58 +05:00
2025-09-19 19:43:49 +05:00
if ( res . Success )
2025-09-19 14:56:58 +05:00
{
2025-09-19 19:43:49 +05:00
msg = GetTranslatedString ( nameChangeSuccessTranslated , nameChangeSuccess , currentLang ) ;
color = Color . white ;
2025-09-19 14:56:58 +05:00
2025-09-19 19:43:49 +05:00
if ( playerName ! = null )
2025-09-19 14:56:58 +05:00
playerName . text = newName ;
2025-09-19 19:43:49 +05:00
if ( UIMainMenu . Singleton ! = null )
2025-09-19 14:56:58 +05:00
UIMainMenu . Singleton . LoadPlayerInfo ( ) ;
2025-09-19 19:43:49 +05:00
OnChangeNickname ? . Invoke ( ) ;
if ( changeNamePref ! = null )
2025-09-19 14:56:58 +05:00
changeNamePref . SetActive ( false ) ;
2025-09-19 19:43:49 +05:00
}
else
{
( msg , color ) = res . Reason switch
2025-09-19 14:56:58 +05:00
{
2025-09-19 19:43:49 +05:00
"0" = > ( GetTranslatedString ( nameLengthErrorTranslated , nameLengthError , currentLang ) , Color . red ) ,
"1" = > ( GetTranslatedString ( notEnoughTicketsTranslated , notEnoughTickets , currentLang ) , Color . red ) ,
"2" = > ( GetTranslatedString ( nameAlreadyTakenTranslated , nameAlreadyTaken , currentLang ) , Color . red ) ,
_ = > ( GetTranslatedString ( nameChangeFailTranslated , nameChangeFail , currentLang ) , Color . red )
} ;
2025-09-19 14:56:58 +05:00
}
2025-09-19 19:43:49 +05:00
DisplayStatusMessage ( msg , color ) ;
2025-09-19 14:56:58 +05:00
}
2025-09-19 19:43:49 +05:00
#endregion
2025-09-19 14:56:58 +05:00
2025-09-19 19:43:49 +05:00
/*────────────────────────────────────────────────────────────────────────────*/
#region Utility Helpers
2025-09-19 14:56:58 +05:00
private CharacterData GetCharacterDataById ( int characterId )
{
if ( GameInstance . Singleton = = null | | GameInstance . Singleton . characterData = = null )
return null ;
foreach ( CharacterData item in GameInstance . Singleton . characterData )
2025-09-19 19:43:49 +05:00
{
2025-09-19 14:56:58 +05:00
if ( item . characterId = = characterId )
return item ;
2025-09-19 19:43:49 +05:00
}
2025-09-19 14:56:58 +05:00
return null ;
}
private void DestroyTemporaryModel ( )
{
if ( tempCharacterContainer = = null ) return ;
for ( int i = tempCharacterContainer . childCount - 1 ; i > = 0 ; i - - )
Destroy ( tempCharacterContainer . GetChild ( i ) . gameObject ) ;
}
private string GetTranslatedString ( NameTranslatedByLanguage [ ] translations , string fallback , string currentLang )
{
if ( translations ! = null )
{
foreach ( var translation in translations )
{
2025-09-19 19:43:49 +05:00
if ( ! string . IsNullOrEmpty ( translation . LanguageId ) & &
translation . LanguageId . Equals ( currentLang ) & &
! string . IsNullOrEmpty ( translation . Translate ) )
2025-09-19 14:56:58 +05:00
{
return translation . Translate ;
}
}
}
return fallback ;
}
2025-09-19 19:43:49 +05:00
public void DisplayStatusMessage ( string message , Color color )
2025-09-19 14:56:58 +05:00
{
2025-09-19 19:43:49 +05:00
if ( statusText = = null )
return ;
2025-09-19 14:56:58 +05:00
statusText . text = message ;
statusText . color = color ;
StartCoroutine ( HideStatusMessageAfterDelay ( statusText , 2f ) ) ;
}
2025-09-19 19:43:49 +05:00
private IEnumerator HideStatusMessageAfterDelay ( TextMeshProUGUI txt , float delay )
2025-09-19 14:56:58 +05:00
{
yield return new WaitForSeconds ( delay ) ;
2025-09-19 19:43:49 +05:00
if ( txt ! = null )
txt . text = string . Empty ;
2025-09-19 14:56:58 +05:00
}
private void SetPlayerIcon ( string iconId )
{
2025-09-19 19:43:49 +05:00
if ( playerIcon = = null | | GameInstance . Singleton = = null )
return ;
2025-09-19 14:56:58 +05:00
foreach ( IconItem item in GameInstance . Singleton . iconItems )
{
if ( item . iconId = = iconId )
{
playerIcon . sprite = item . icon ;
break ;
}
}
}
private void SetPlayerFrame ( string frameId )
{
2025-09-19 19:43:49 +05:00
if ( playerFrame = = null | | GameInstance . Singleton = = null )
return ;
2025-09-19 14:56:58 +05:00
foreach ( FrameItem item in GameInstance . Singleton . frameItems )
{
if ( item . frameId = = frameId )
{
playerFrame . sprite = item . icon ;
break ;
}
}
}
2025-09-19 19:43:49 +05:00
#endregion
2025-09-19 14:56:58 +05:00
}
}