UI update 02
This commit is contained in:
@@ -7,9 +7,7 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using DG.Tweening;
|
||||
using JetBrains.Annotations;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using Bansonic;
|
||||
@@ -17,26 +15,43 @@ using Bansonic;
|
||||
class UI_Panel_Character : MonoBehaviour
|
||||
{
|
||||
[SerializeField] float anim_Time = 0.5f;
|
||||
[SerializeField, Range(0f, 1f)] float illustrationFadeStartAlpha = 0.25f;
|
||||
float Anim_Speed => 1f / anim_Time;
|
||||
|
||||
[SerializeField] List<Animator> ui_Anim;
|
||||
[SerializeField] Transform content_Character_Slot;
|
||||
[SerializeField] Button button_Character_Slot_Prefab;
|
||||
[SerializeField] GameObject button_Character_Slot_Prefab;
|
||||
[SerializeField] Text text_Character_Name;
|
||||
[SerializeField] Text text_char_name;
|
||||
[SerializeField] Image Image_Character_Illustration;
|
||||
[SerializeField] Image Image_Character_Illustration_BG;
|
||||
|
||||
//[Header("")]
|
||||
|
||||
[Header("buttons")]
|
||||
public Button change_thisHero_skin;
|
||||
public Button thisHero_detail;
|
||||
public Button confirm_thisHero;
|
||||
|
||||
[Header("quit")]
|
||||
[SerializeField] Button quitButton;
|
||||
|
||||
[Header("Data Paths")]
|
||||
[Tooltip("Path relative to Resources folder for Editor mode")]
|
||||
public string editorResourcePath = "so/ally";
|
||||
[Tooltip("Path relative to Resources folder for Runtime mode")]
|
||||
public string runtimeResourcePath = "so/ally";
|
||||
|
||||
private List<AllyHero_SO> allyHeroList = new List<AllyHero_SO>();
|
||||
private readonly List<AllyHero_SO> allyHeroList = new List<AllyHero_SO>();
|
||||
private readonly List<uiui_character_displayPrefab> heroDisplayPrefabs = new List<uiui_character_displayPrefab>();
|
||||
private Vector2 originalIllustrationPos;
|
||||
private Vector2 originalIllustrationBGPos;
|
||||
private bool hasCachedPositions;
|
||||
private Coroutine c_Character_Illustration_Anim;
|
||||
private int previewCharacterIndex = -1;
|
||||
private CanvasGroup illustrationCanvasGroup;
|
||||
|
||||
private const string SAVED_HERO_ID_KEY = "SelectedMainHeroID";
|
||||
|
||||
private void Update()
|
||||
{
|
||||
@@ -45,135 +60,129 @@ class UI_Panel_Character : MonoBehaviour
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
private Vector2 originalIllustrationPos;
|
||||
private Vector2 originalIllustrationBGPos;
|
||||
private bool hasCachedPositions = false;
|
||||
private const string SAVED_HERO_ID_KEY = "SelectedMainHeroID";
|
||||
|
||||
void Start()
|
||||
{
|
||||
UnityEngine.Debug.Log($"[UI_Panel_Character] Start called. Illustration: {Image_Character_Illustration}");
|
||||
|
||||
// 初始化按钮监听
|
||||
if (change_thisHero_skin != null)
|
||||
change_thisHero_skin.onClick.AddListener(() => gNotice.warning.display("此版本未开放皮肤切换功能"));
|
||||
|
||||
change_thisHero_skin.onClick.AddListener(() => gNotice.warning.display("\u6b64\u7248\u672c\u672a\u5f00\u653e\u76ae\u80a4\u5207\u6362\u529f\u80fd"));
|
||||
|
||||
if (thisHero_detail != null)
|
||||
thisHero_detail.onClick.AddListener(() => gNotice.warning.display("此版本未开放详情查看功能"));
|
||||
|
||||
thisHero_detail.onClick.AddListener(() => gNotice.warning.display("\u6b64\u7248\u672c\u672a\u5f00\u653e\u8be6\u60c5\u67e5\u770b\u529f\u80fd"));
|
||||
|
||||
if (confirm_thisHero != null)
|
||||
confirm_thisHero.onClick.AddListener(OnConfirmHeroClicked);
|
||||
|
||||
if (quitButton != null)
|
||||
quitButton.onClick.AddListener(() => gameObject.SetActive(false));
|
||||
|
||||
if (Image_Character_Illustration != null)
|
||||
{
|
||||
// 设置为图示的数值:Pos X: 376, Pos Y: -306
|
||||
Image_Character_Illustration.rectTransform.anchoredPosition = new Vector2(376, -306);
|
||||
|
||||
originalIllustrationPos = Image_Character_Illustration.rectTransform.anchoredPosition;
|
||||
if (Image_Character_Illustration.transform.parent.TryGetComponent(out CanvasGroup canvasGroup))
|
||||
|
||||
if (Image_Character_Illustration.transform.parent != null &&
|
||||
Image_Character_Illustration.transform.parent.TryGetComponent(out CanvasGroup canvasGroup))
|
||||
{
|
||||
canvasGroup.alpha = 0;
|
||||
illustrationCanvasGroup = canvasGroup;
|
||||
illustrationCanvasGroup.alpha = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (Image_Character_Illustration_BG != null)
|
||||
{
|
||||
// 设置运行时 X 值为 376
|
||||
Vector2 pos = Image_Character_Illustration_BG.rectTransform.anchoredPosition;
|
||||
pos.x = 376;
|
||||
Image_Character_Illustration_BG.rectTransform.anchoredPosition = pos;
|
||||
|
||||
originalIllustrationBGPos = Image_Character_Illustration_BG.rectTransform.anchoredPosition;
|
||||
}
|
||||
|
||||
hasCachedPositions = true;
|
||||
|
||||
foreach (var item in ui_Anim)
|
||||
{
|
||||
if (item != null) item.speed = Anim_Speed;
|
||||
if (item != null)
|
||||
item.speed = Anim_Speed;
|
||||
}
|
||||
|
||||
|
||||
if (content_Character_Slot != null)
|
||||
content_Character_Slot.Get_Childrens_Component<UI_Button_Character_Head_Slot>(true, true);
|
||||
|
||||
// Load AllyHero_SO data
|
||||
string path = Application.isEditor ? editorResourcePath : runtimeResourcePath;
|
||||
var loadedData = Resources.LoadAll<AllyHero_SO>(path);
|
||||
allyHeroList = new List<AllyHero_SO>(loadedData);
|
||||
|
||||
UnityEngine.Debug.Log($"[UI_Panel_Character] Loaded {allyHeroList.Count} heroes from {path}");
|
||||
var loadedData = RuntimeResourcesCache.LoadAllAllyHeroes();
|
||||
allyHeroList.Clear();
|
||||
allyHeroList.AddRange(loadedData);
|
||||
heroDisplayPrefabs.Clear();
|
||||
|
||||
UnityEngine.Debug.Log($"[UI_Panel_Character] Loaded {allyHeroList.Count} heroes");
|
||||
|
||||
// Ensure consistent order with UI_Panel_Main
|
||||
allyHeroList.Sort((a, b) => a.ally_heroID.CompareTo(b.ally_heroID));
|
||||
|
||||
// 读取保存的角色 ID
|
||||
int savedHeroID = PlayerPrefs.GetInt(SAVED_HERO_ID_KEY, -1);
|
||||
int initialIndex = 0;
|
||||
|
||||
for (int i = 0; i < allyHeroList.Count; i++)
|
||||
{
|
||||
var obj = Instantiate(button_Character_Slot_Prefab, content_Character_Slot);
|
||||
|
||||
// Register UI sounds for the newly instantiated button
|
||||
UISystemBootstrap.RegisterHierarchy(obj.gameObject);
|
||||
var slotObject = Instantiate(button_Character_Slot_Prefab, content_Character_Slot);
|
||||
var displayPrefab = slotObject.GetComponent<uiui_character_displayPrefab>();
|
||||
var slotButton = displayPrefab != null ? displayPrefab.characterProfileButton : slotObject.GetComponent<Button>();
|
||||
if (slotButton == null && slotObject.transform.parent != null)
|
||||
{
|
||||
slotButton = slotObject.transform.parent.GetComponent<Button>();
|
||||
}
|
||||
|
||||
UISystemBootstrap.RegisterHierarchy(slotObject);
|
||||
|
||||
var data = allyHeroList[i];
|
||||
|
||||
// 如果 ID 匹配,设置初始索引
|
||||
if (savedHeroID != -1 && data.ally_heroID == savedHeroID)
|
||||
{
|
||||
initialIndex = i;
|
||||
}
|
||||
|
||||
if (obj.image != null)
|
||||
if (displayPrefab != null)
|
||||
{
|
||||
obj.image.sprite = data.ally_heroSelectIcon;
|
||||
obj.image.preserveAspect = true; // 保持比例,防止拉伸变形
|
||||
obj.image.type = Image.Type.Simple; // 确保是普通显示模式
|
||||
|
||||
// 确保 RectTransform 撑满父物体并居中
|
||||
obj.image.rectTransform.anchorMin = Vector2.zero;
|
||||
obj.image.rectTransform.anchorMax = Vector2.one;
|
||||
obj.image.rectTransform.sizeDelta = Vector2.zero;
|
||||
obj.image.rectTransform.anchoredPosition = Vector2.zero;
|
||||
displayPrefab.SetDisplay(data.ally_heroSelectIcon, data.ally_heroID);
|
||||
}
|
||||
heroDisplayPrefabs.Add(displayPrefab);
|
||||
|
||||
if (obj.TryGetComponent(out UI_Button_Character_Head_Slot head_Slot))
|
||||
if (slotObject.TryGetComponent(out UI_Button_Character_Head_Slot head_Slot))
|
||||
{
|
||||
head_Slot.index = i;
|
||||
int capturedIndex = i;
|
||||
obj.onClick.AddListener(() => Set_Character_Index(capturedIndex));
|
||||
if (slotButton != null)
|
||||
{
|
||||
slotButton.onClick.AddListener(() => Set_Character_Index(capturedIndex));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 应用初始索引(来自保存的 ID 或默认 0)
|
||||
|
||||
previewCharacterIndex = initialIndex;
|
||||
UI_Panel_Main.Singleton.Character_Index = initialIndex;
|
||||
|
||||
// Initial character display
|
||||
Set_Character();
|
||||
RefreshSelectedState(false);
|
||||
}
|
||||
|
||||
public void Set_Character_Index(int index)
|
||||
{
|
||||
if (UI_Panel_Main.Singleton.Character_Index == index) return;
|
||||
UI_Panel_Main.Singleton.Character_Index = index;
|
||||
if (previewCharacterIndex == index)
|
||||
return;
|
||||
|
||||
previewCharacterIndex = index;
|
||||
Set_Character();
|
||||
|
||||
// 人性化逻辑:点击头像即自动设为看板并保存,并显示提示内容
|
||||
SaveCurrentCharacter(true);
|
||||
RefreshSelectedState(true);
|
||||
}
|
||||
|
||||
private void OnConfirmHeroClicked()
|
||||
{
|
||||
if (SaveCurrentCharacter(true))
|
||||
{
|
||||
// 确认按钮逻辑:保存后禁用自身物体(隐藏面板)
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
private bool SaveCurrentCharacter(bool showNotice)
|
||||
{
|
||||
int currentIndex = UI_Panel_Main.Singleton.Character_Index;
|
||||
int currentIndex = GetCurrentPreviewIndex();
|
||||
if (allyHeroList != null && currentIndex >= 0 && currentIndex < allyHeroList.Count)
|
||||
{
|
||||
int heroID = allyHeroList[currentIndex].ally_heroID;
|
||||
@@ -182,57 +191,104 @@ class UI_Panel_Character : MonoBehaviour
|
||||
|
||||
if (showNotice)
|
||||
{
|
||||
gNotice.alarm.display($"已将 {allyHeroList[currentIndex].ally_heroName} 设置为记录对象。");
|
||||
gNotice.alarm.display($"\u5df2\u5c06 {allyHeroList[currentIndex].ally_heroName} \u8bbe\u7f6e\u4e3a\u770b\u677f\u5bf9\u8c61\u3002");
|
||||
}
|
||||
|
||||
// 同步更新主面板的看板图
|
||||
previewCharacterIndex = currentIndex;
|
||||
UI_Panel_Main.Singleton.Character_Index = currentIndex;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
previewCharacterIndex = UI_Panel_Main.Singleton != null ? UI_Panel_Main.Singleton.Character_Index : previewCharacterIndex;
|
||||
Set_Character();
|
||||
RefreshSelectedState(false);
|
||||
}
|
||||
Coroutine c_Character_Illustration_Anim;
|
||||
|
||||
private void RefreshSelectedState(bool animated)
|
||||
{
|
||||
int selectedIndex = GetCurrentPreviewIndex();
|
||||
for (int i = 0; i < heroDisplayPrefabs.Count; i++)
|
||||
{
|
||||
if (heroDisplayPrefabs[i] != null)
|
||||
{
|
||||
heroDisplayPrefabs[i].SetSelected(i == selectedIndex, animated);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int GetCurrentPreviewIndex()
|
||||
{
|
||||
if (previewCharacterIndex >= 0 && previewCharacterIndex < allyHeroList.Count)
|
||||
{
|
||||
return previewCharacterIndex;
|
||||
}
|
||||
|
||||
if (UI_Panel_Main.Singleton != null)
|
||||
{
|
||||
return UI_Panel_Main.Singleton.Character_Index;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void Set_Character()
|
||||
{
|
||||
if (Image_Character_Illustration == null || illustrationCanvasGroup == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (c_Character_Illustration_Anim != null)
|
||||
{
|
||||
StopCoroutine(c_Character_Illustration_Anim);
|
||||
c_Character_Illustration_Anim = null;
|
||||
}
|
||||
if (Image_Character_Illustration.transform.parent.TryGetComponent(out CanvasGroup canvasGroup))
|
||||
{
|
||||
c_Character_Illustration_Anim = StartCoroutine(C_Character_Illustration_Anim(canvasGroup, Set_Character_Show));
|
||||
}
|
||||
|
||||
illustrationCanvasGroup.DOKill();
|
||||
Set_Character_Show();
|
||||
illustrationCanvasGroup.alpha = illustrationFadeStartAlpha;
|
||||
illustrationCanvasGroup.DOFade(1f, anim_Time * 0.6f)
|
||||
.SetEase(Ease.OutCubic)
|
||||
.SetLink(illustrationCanvasGroup.gameObject);
|
||||
}
|
||||
|
||||
public void Set_Character_Show()
|
||||
{
|
||||
int index = UI_Panel_Main.Singleton.Character_Index;
|
||||
if (allyHeroList == null || index < 0 || index >= allyHeroList.Count) return;
|
||||
int index = GetCurrentPreviewIndex();
|
||||
if (allyHeroList.Count == 0 || index < 0 || index >= allyHeroList.Count)
|
||||
return;
|
||||
|
||||
// 停止之前的 Tween 以防冲突
|
||||
Image_Character_Illustration.rectTransform.DOKill();
|
||||
Image_Character_Illustration_BG.rectTransform.DOKill();
|
||||
text_Character_Name.DOKill();
|
||||
if (text_char_name != null)
|
||||
{
|
||||
text_char_name.DOKill();
|
||||
}
|
||||
|
||||
var data = allyHeroList[index];
|
||||
|
||||
// 使用初始缓存的坐标,防止频繁点击导致的偏移累积
|
||||
Vector2 targetPos1 = hasCachedPositions ? originalIllustrationPos : Image_Character_Illustration.rectTransform.anchoredPosition;
|
||||
|
||||
Vector2 targetPos1 = hasCachedPositions
|
||||
? originalIllustrationPos
|
||||
: Image_Character_Illustration.rectTransform.anchoredPosition;
|
||||
Image_Character_Illustration.sprite = data.ally_hero_HD_image;
|
||||
|
||||
// 动画:从左侧 200 像素滑入到目标位置
|
||||
|
||||
float startX1 = targetPos1.x - 200;
|
||||
Image_Character_Illustration.rectTransform.anchoredPosition = new Vector2(startX1, targetPos1.y);
|
||||
Image_Character_Illustration.rectTransform.DOAnchorPos(targetPos1, anim_Time)
|
||||
.SetEase(Ease.OutCubic)
|
||||
.SetLink(Image_Character_Illustration.gameObject);
|
||||
|
||||
Vector2 targetPosBG = hasCachedPositions ? originalIllustrationBGPos : Image_Character_Illustration_BG.rectTransform.anchoredPosition;
|
||||
Vector2 targetPosBG = hasCachedPositions
|
||||
? originalIllustrationBGPos
|
||||
: Image_Character_Illustration_BG.rectTransform.anchoredPosition;
|
||||
Image_Character_Illustration_BG.sprite = data.ally_hero_HD_image;
|
||||
|
||||
|
||||
float startXBG = targetPosBG.x - 200;
|
||||
Image_Character_Illustration_BG.rectTransform.anchoredPosition = new Vector2(startXBG, targetPosBG.y);
|
||||
Image_Character_Illustration_BG.rectTransform.DOAnchorPos(targetPosBG, anim_Time)
|
||||
@@ -246,19 +302,13 @@ class UI_Panel_Character : MonoBehaviour
|
||||
text_Character_Name.DOText(text, anim_Time)
|
||||
.SetEase(Ease.Linear)
|
||||
.SetLink(text_Character_Name.gameObject);
|
||||
}
|
||||
IEnumerator C_Character_Illustration_Anim(CanvasGroup canvasGroup, Action onHide)
|
||||
{
|
||||
while (canvasGroup.alpha > 0)
|
||||
|
||||
if (text_char_name != null)
|
||||
{
|
||||
canvasGroup.alpha -= Anim_Speed * Time.deltaTime;
|
||||
yield return null;
|
||||
}
|
||||
onHide?.Invoke();
|
||||
while (canvasGroup.alpha < 1)
|
||||
{
|
||||
canvasGroup.alpha += Anim_Speed * Time.deltaTime;
|
||||
yield return null;
|
||||
text_char_name.text = string.Empty;
|
||||
text_char_name.DOText(text, anim_Time)
|
||||
.SetEase(Ease.Linear)
|
||||
.SetLink(text_char_name.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user