474 lines
18 KiB
C#
474 lines
18 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using Animancer;
|
|
using Logic.Multilingual;
|
|
using RuntimeData;
|
|
using TH1_UI.HintUI;
|
|
using TH1Resource;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
namespace TH1_UI.View.Outside
|
|
{
|
|
public class UIOutsideLibraryHeroPanelMono : MonoBehaviour
|
|
{
|
|
|
|
public TextMeshProUGUI TopTitle;
|
|
public Image Illustration;
|
|
public TextMeshProUGUI Name;
|
|
public TextMeshProUGUI CivName;
|
|
public Image CivBG;
|
|
public RectTransform CivRect;
|
|
public TextMeshProUGUI Desc;
|
|
public TextMeshProUGUI Dialogue;
|
|
public Image DialogueAvatar;
|
|
public List<UIOutsideLibraryAchieveItemMono> AchieveItems;
|
|
public Button SettingTabButton;
|
|
public Button BattleTabButton;
|
|
public Image SettingTabBG;
|
|
public Image BattleTabBG;
|
|
public RectTransform SettingContentRoot;
|
|
public RectTransform BattleContentRoot;
|
|
public Sprite TabButtonSprite;
|
|
|
|
public Button CloseButton;
|
|
public Button LeftButton;
|
|
public Button RightButton;
|
|
public AnimancerComponent Animancer;
|
|
|
|
private const string HeroHintPanelPath = "Prefab/UI/Hint/HeroHintPanel";
|
|
private const string TabButtonSpritePath = "TH1UI/Common/CommonButton/ItemButtonBG";
|
|
private static readonly Color SelectedTabColor = new Color(0.42f, 0.22f, 0.42f, 1f);
|
|
private static readonly Color NormalTabColor = new Color(1f, 1f, 1f, 0.88f);
|
|
private static readonly Color SelectedTabTextColor = Color.white;
|
|
private static readonly Color NormalTabTextColor = new Color(0.25f, 0.23f, 0.42f, 1f);
|
|
|
|
private GiantType _currentGiantType = GiantType.None;
|
|
private HeroHintPanel _battlePanel;
|
|
|
|
private enum HeroPanelTab
|
|
{
|
|
Setting,
|
|
Battle
|
|
}
|
|
|
|
|
|
public void Init(Action onStartClick)
|
|
{
|
|
EnsureTabStructure();
|
|
BindTabButtons();
|
|
}
|
|
|
|
public bool SetContent(GiantType giantType)
|
|
{
|
|
if (!ContentGate.CanShowHeroIntroduction(giantType)) return false;
|
|
if (!Table.Instance.LibraryDataAssets.GetLibraryInfoByGiant(giantType, out var info)) return false;
|
|
if (!Table.Instance.UnitTypeDataAssets.GetUnitTypeInfo(new UnitFullType(UnitType.Giant, giantType, 1),
|
|
out var unitInfo)) return false;
|
|
var empire = unitInfo.GiantEmpire;
|
|
if (!Table.Instance.PlayerDataAssets.GetPlayerInfo(empire, out var playerInfo)) return false;
|
|
|
|
_currentGiantType = giantType;
|
|
EnsureTabStructure();
|
|
BindTabButtons();
|
|
|
|
SetUITextOrRaw(TopTitle,info.Name);
|
|
Illustration.sprite = info.Illust;
|
|
SetUITextOrRaw(Name,info.Name);
|
|
SetUITextOrRaw(CivName,playerInfo.CivName);
|
|
CivBG.color = playerInfo.Color;
|
|
SetUITextOrRaw(Desc,info.Desc);
|
|
SetUITextOrRaw(Dialogue,info.Diag);
|
|
DialogueAvatar.sprite = unitInfo.Sprite;
|
|
|
|
//Step #3 设定成就
|
|
SetAchieveItems(giantType);
|
|
|
|
|
|
CloseButton.onClick.RemoveAllListeners();
|
|
CloseButton.onClick.AddListener(Hide);
|
|
SelectTab(HeroPanelTab.Setting);
|
|
return true;
|
|
|
|
}
|
|
|
|
private void BindTabButtons()
|
|
{
|
|
if (SettingTabButton != null)
|
|
{
|
|
SettingTabButton.onClick.RemoveAllListeners();
|
|
SettingTabButton.onClick.AddListener(() => SelectTab(HeroPanelTab.Setting));
|
|
}
|
|
|
|
if (BattleTabButton != null)
|
|
{
|
|
BattleTabButton.onClick.RemoveAllListeners();
|
|
BattleTabButton.onClick.AddListener(() => SelectTab(HeroPanelTab.Battle));
|
|
}
|
|
}
|
|
|
|
private void EnsureTabStructure()
|
|
{
|
|
if (SettingTabButton != null &&
|
|
BattleTabButton != null &&
|
|
SettingContentRoot != null &&
|
|
BattleContentRoot != null)
|
|
{
|
|
SettingTabBG ??= SettingTabButton.GetComponent<Image>();
|
|
BattleTabBG ??= BattleTabButton.GetComponent<Image>();
|
|
return;
|
|
}
|
|
|
|
var infoRoot = Name != null ? Name.transform.parent as RectTransform : null;
|
|
if (infoRoot == null) return;
|
|
|
|
var tabRoot = EnsureRect(infoRoot, "TabRoot");
|
|
tabRoot.SetAsFirstSibling();
|
|
tabRoot.anchorMin = new Vector2(0f, 1f);
|
|
tabRoot.anchorMax = new Vector2(0f, 1f);
|
|
tabRoot.pivot = new Vector2(0f, 1f);
|
|
tabRoot.anchoredPosition = new Vector2(40f, -76f);
|
|
tabRoot.sizeDelta = new Vector2(316f, 52f);
|
|
ConfigureHorizontalLayout(tabRoot, 12f);
|
|
ConfigureIgnoredLayoutElement(tabRoot.gameObject);
|
|
|
|
SettingTabButton = EnsureTabButton(tabRoot, "SettingTabButton", "设定", true);
|
|
BattleTabButton = EnsureTabButton(tabRoot, "BattleTabButton", "战斗", false);
|
|
SettingTabBG = SettingTabButton.GetComponent<Image>();
|
|
BattleTabBG = BattleTabButton.GetComponent<Image>();
|
|
|
|
SettingContentRoot = EnsureRect(infoRoot, "SettingContentRoot");
|
|
SettingContentRoot.SetSiblingIndex(1);
|
|
ConfigureVerticalLayout(SettingContentRoot);
|
|
ConfigureLayoutElement(SettingContentRoot.gameObject, 0f, -1f, 1f);
|
|
|
|
BattleContentRoot = EnsureRect(infoRoot, "BattleContentRoot");
|
|
BattleContentRoot.SetSiblingIndex(2);
|
|
ConfigureVerticalLayout(BattleContentRoot);
|
|
ConfigureLayoutElement(BattleContentRoot.gameObject, 0f, -1f, 1f);
|
|
BattleContentRoot.gameObject.SetActive(false);
|
|
|
|
MoveIntoSettingRoot(infoRoot, "Name");
|
|
MoveIntoSettingRoot(infoRoot, "CivName");
|
|
MoveIntoSettingRoot(infoRoot, "DescTitle");
|
|
MoveIntoSettingRoot(infoRoot, "DescText");
|
|
MoveIntoSettingRoot(infoRoot, "DialogGroup");
|
|
MoveIntoSettingRoot(infoRoot, "AchieveTitle");
|
|
MoveIntoSettingRoot(infoRoot, "AchieveGroup");
|
|
}
|
|
|
|
private RectTransform EnsureRect(Transform parent, string objectName)
|
|
{
|
|
var existing = parent.Find(objectName) as RectTransform;
|
|
if (existing != null) return existing;
|
|
|
|
var go = new GameObject(objectName, typeof(RectTransform));
|
|
go.layer = parent.gameObject.layer;
|
|
var rect = go.GetComponent<RectTransform>();
|
|
rect.SetParent(parent, false);
|
|
rect.anchorMin = Vector2.zero;
|
|
rect.anchorMax = Vector2.one;
|
|
rect.pivot = new Vector2(0.5f, 0.5f);
|
|
rect.anchoredPosition = Vector2.zero;
|
|
rect.sizeDelta = Vector2.zero;
|
|
return rect;
|
|
}
|
|
|
|
private Button EnsureTabButton(RectTransform parent, string objectName, string label, bool selected)
|
|
{
|
|
var rect = EnsureRect(parent, objectName);
|
|
rect.gameObject.SetActive(true);
|
|
ConfigureLayoutElement(rect.gameObject, 142f, 46f, -1f);
|
|
|
|
TabButtonSprite ??= ResourceLoader.Load<Sprite>(TabButtonSpritePath);
|
|
var image = rect.GetComponent<Image>();
|
|
if (image == null) image = rect.gameObject.AddComponent<Image>();
|
|
image.sprite = TabButtonSprite;
|
|
image.type = image.sprite != null && image.sprite.border != Vector4.zero
|
|
? Image.Type.Sliced
|
|
: Image.Type.Simple;
|
|
image.color = selected ? SelectedTabColor : NormalTabColor;
|
|
image.raycastTarget = true;
|
|
|
|
var button = rect.GetComponent<Button>();
|
|
if (button == null) button = rect.gameObject.AddComponent<Button>();
|
|
button.transition = Selectable.Transition.ColorTint;
|
|
button.targetGraphic = image;
|
|
|
|
var textRect = EnsureRect(rect, "Text");
|
|
textRect.anchorMin = Vector2.zero;
|
|
textRect.anchorMax = Vector2.one;
|
|
textRect.offsetMin = Vector2.zero;
|
|
textRect.offsetMax = Vector2.zero;
|
|
|
|
var text = textRect.GetComponent<TextMeshProUGUI>();
|
|
if (text == null) text = textRect.gameObject.AddComponent<TextMeshProUGUI>();
|
|
text.text = label;
|
|
if (Name != null && Name.font != null) text.font = Name.font;
|
|
text.fontSize = 26f;
|
|
text.color = selected ? SelectedTabTextColor : NormalTabTextColor;
|
|
text.alignment = TextAlignmentOptions.Center;
|
|
text.raycastTarget = false;
|
|
|
|
var multilingual = textRect.GetComponent<MultilingualTextMono>();
|
|
if (multilingual == null) multilingual = textRect.gameObject.AddComponent<MultilingualTextMono>();
|
|
multilingual.Ban = true;
|
|
multilingual.NoExport = true;
|
|
multilingual.FontBan = true;
|
|
multilingual.ID = 0;
|
|
|
|
return button;
|
|
}
|
|
|
|
private void MoveIntoSettingRoot(RectTransform infoRoot, string childName)
|
|
{
|
|
if (SettingContentRoot == null) return;
|
|
var child = infoRoot.Find(childName);
|
|
if (child == null || child == SettingContentRoot) return;
|
|
child.SetParent(SettingContentRoot, false);
|
|
}
|
|
|
|
private static void ConfigureHorizontalLayout(RectTransform rect, float spacing)
|
|
{
|
|
var layout = rect.GetComponent<HorizontalLayoutGroup>();
|
|
if (layout == null) layout = rect.gameObject.AddComponent<HorizontalLayoutGroup>();
|
|
layout.padding = new RectOffset(0, 0, 0, 0);
|
|
layout.childAlignment = TextAnchor.MiddleLeft;
|
|
layout.spacing = spacing;
|
|
layout.childControlWidth = false;
|
|
layout.childControlHeight = false;
|
|
layout.childForceExpandWidth = false;
|
|
layout.childForceExpandHeight = false;
|
|
}
|
|
|
|
private static void ConfigureVerticalLayout(RectTransform rect)
|
|
{
|
|
var layout = rect.GetComponent<VerticalLayoutGroup>();
|
|
if (layout == null) layout = rect.gameObject.AddComponent<VerticalLayoutGroup>();
|
|
layout.padding = new RectOffset(0, 0, 0, 0);
|
|
layout.childAlignment = TextAnchor.UpperLeft;
|
|
layout.spacing = 0f;
|
|
layout.childControlWidth = true;
|
|
layout.childControlHeight = false;
|
|
layout.childForceExpandWidth = true;
|
|
layout.childForceExpandHeight = false;
|
|
}
|
|
|
|
private static void ConfigureLayoutElement(GameObject go, float preferredWidth, float preferredHeight, float flexibleHeight)
|
|
{
|
|
var element = go.GetComponent<LayoutElement>();
|
|
if (element == null) element = go.AddComponent<LayoutElement>();
|
|
element.ignoreLayout = false;
|
|
element.preferredWidth = preferredWidth;
|
|
element.preferredHeight = preferredHeight;
|
|
element.flexibleHeight = flexibleHeight;
|
|
}
|
|
|
|
private static void ConfigureIgnoredLayoutElement(GameObject go)
|
|
{
|
|
var element = go.GetComponent<LayoutElement>();
|
|
if (element == null) element = go.AddComponent<LayoutElement>();
|
|
element.ignoreLayout = true;
|
|
}
|
|
|
|
private void SelectTab(HeroPanelTab tab)
|
|
{
|
|
if (SettingContentRoot != null) SettingContentRoot.gameObject.SetActive(tab == HeroPanelTab.Setting);
|
|
if (BattleContentRoot != null) BattleContentRoot.gameObject.SetActive(tab == HeroPanelTab.Battle);
|
|
|
|
SetTabVisual(SettingTabBG, tab == HeroPanelTab.Setting);
|
|
SetTabVisual(BattleTabBG, tab == HeroPanelTab.Battle);
|
|
SetTabTextVisual(SettingTabButton, tab == HeroPanelTab.Setting);
|
|
SetTabTextVisual(BattleTabButton, tab == HeroPanelTab.Battle);
|
|
|
|
if (tab == HeroPanelTab.Battle) RefreshBattlePanel();
|
|
}
|
|
|
|
private static void SetTabVisual(Image image, bool selected)
|
|
{
|
|
if (image == null) return;
|
|
image.color = selected ? SelectedTabColor : NormalTabColor;
|
|
}
|
|
|
|
private static void SetTabTextVisual(Button button, bool selected)
|
|
{
|
|
if (button == null) return;
|
|
var text = button.GetComponentInChildren<TextMeshProUGUI>(true);
|
|
if (text == null) return;
|
|
text.color = selected ? SelectedTabTextColor : NormalTabTextColor;
|
|
}
|
|
|
|
private void RefreshBattlePanel()
|
|
{
|
|
if (_currentGiantType == GiantType.None || BattleContentRoot == null) return;
|
|
|
|
if (_battlePanel == null)
|
|
{
|
|
var prefab = ResourceLoader.Load<GameObject>(HeroHintPanelPath);
|
|
if (prefab == null) return;
|
|
|
|
var go = Instantiate(prefab, BattleContentRoot, false);
|
|
go.name = "BattleHeroHintPanel";
|
|
_battlePanel = go.GetComponent<HeroHintPanel>();
|
|
if (_battlePanel == null) return;
|
|
|
|
_battlePanel.SetEmbeddedMode(true, true);
|
|
var rect = go.GetComponent<RectTransform>();
|
|
if (rect != null)
|
|
{
|
|
rect.anchorMin = new Vector2(0f, 1f);
|
|
rect.anchorMax = new Vector2(0f, 1f);
|
|
rect.pivot = new Vector2(0f, 1f);
|
|
rect.anchoredPosition = Vector2.zero;
|
|
rect.localScale = Vector3.one;
|
|
}
|
|
}
|
|
|
|
_battlePanel.gameObject.SetActive(true);
|
|
_battlePanel.SetEmbeddedMode(true, true);
|
|
_battlePanel.SetHeroInfo(_currentGiantType);
|
|
}
|
|
|
|
public void SetNavigationButtons(bool canMoveLeft, bool canMoveRight, Action onLeftClick, Action onRightClick)
|
|
{
|
|
EnsureNavigationButtons();
|
|
SetNavigationButton(LeftButton, canMoveLeft, onLeftClick);
|
|
SetNavigationButton(RightButton, canMoveRight, onRightClick);
|
|
}
|
|
|
|
private void EnsureNavigationButtons()
|
|
{
|
|
if (LeftButton == null)
|
|
{
|
|
LeftButton = FindNavigationButton("LeftButton");
|
|
}
|
|
|
|
if (RightButton == null)
|
|
{
|
|
RightButton = FindNavigationButton("RightButton");
|
|
}
|
|
}
|
|
|
|
private Button FindNavigationButton(string buttonName)
|
|
{
|
|
var buttons = GetComponentsInChildren<Button>(true);
|
|
for (int i = 0; i < buttons.Length; i++)
|
|
{
|
|
if (buttons[i] != null && buttons[i].name == buttonName) return buttons[i];
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private static void SetNavigationButton(Button button, bool active, Action onClick)
|
|
{
|
|
if (button == null) return;
|
|
button.gameObject.SetActive(active);
|
|
button.onClick.RemoveAllListeners();
|
|
if (active && onClick != null) button.onClick.AddListener(() => onClick.Invoke());
|
|
}
|
|
|
|
private static void SetUITextOrRaw(TextMeshProUGUI text, string value)
|
|
{
|
|
if (text == null) return;
|
|
|
|
var multilingual = text.gameObject.GetComponent<MultilingualTextMono>();
|
|
if (string.IsNullOrEmpty(value))
|
|
{
|
|
if (multilingual != null)
|
|
{
|
|
multilingual.ID = 0;
|
|
multilingual.Ban = true;
|
|
}
|
|
|
|
text.text = string.Empty;
|
|
return;
|
|
}
|
|
|
|
if (uint.TryParse(value, out _))
|
|
{
|
|
if (multilingual != null) multilingual.Ban = false;
|
|
MultilingualManager.Instance.SetUIText(text, value);
|
|
}
|
|
else
|
|
{
|
|
if (multilingual != null)
|
|
{
|
|
multilingual.ID = 0;
|
|
multilingual.Ban = true;
|
|
}
|
|
|
|
text.text = value;
|
|
}
|
|
}
|
|
|
|
|
|
private void SetAchieveItems(GiantType giantType)
|
|
{
|
|
if (AchieveItems.Count != 3) return;
|
|
if (!UIOutsideLibraryAchievementVisibility.ShouldShowHeroAchievements(giantType))
|
|
{
|
|
SetAchievementSectionActive(false);
|
|
return;
|
|
}
|
|
|
|
if (!AchievementDataManager.Instance.GetSmallIdByGiantType(giantType, out var smallid))
|
|
{
|
|
SetAchievementSectionActive(false);
|
|
return;
|
|
}
|
|
|
|
SetAchievementSectionActive(true);
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
AchieveItems[i].gameObject.SetActive(true);
|
|
AchieveItems[i].SetContent(2,smallid,(uint)i + 1);
|
|
}
|
|
}
|
|
|
|
private void SetAchievementSectionActive(bool active)
|
|
{
|
|
Transform group = null;
|
|
if (AchieveItems.Count > 0 && AchieveItems[0] != null)
|
|
group = AchieveItems[0].transform.parent;
|
|
|
|
if (group != null)
|
|
{
|
|
group.gameObject.SetActive(active);
|
|
var title = group.parent != null ? group.parent.Find("AchieveTitle") : null;
|
|
if (title != null) title.gameObject.SetActive(active);
|
|
}
|
|
|
|
for (int i = 0; i < AchieveItems.Count; i++)
|
|
{
|
|
if (AchieveItems[i] != null) AchieveItems[i].gameObject.SetActive(active);
|
|
}
|
|
}
|
|
public void Show()
|
|
{
|
|
gameObject.SetActive(true);
|
|
LayoutRebuilder.ForceRebuildLayoutImmediate(CivRect);
|
|
Animancer.Play(ResourceCache.Instance.AnimCache.UICommonPanelFadeIn);
|
|
|
|
|
|
}
|
|
|
|
public void Hide()
|
|
{
|
|
var state = Animancer.Play(ResourceCache.Instance.AnimCache.UICommonPanelFadeOut);
|
|
state.Events.OnEnd = () => { gameObject.SetActive(false); };
|
|
}
|
|
void Start()
|
|
{
|
|
|
|
}
|
|
|
|
// Update is called once per frame
|
|
void Update()
|
|
{
|
|
|
|
}
|
|
}
|
|
}
|