TH1/Unity/Assets/Scripts/TH1_UI/View/Top/UITopTopBarView.cs
daixiawu 491503a06d bug修复
1.修复了部分会导致船只出现在陆地的bug
2.修复了部分会导致已经死亡的单位图像错误残留的bug
3.修复了[车]职阶英雄在敌方城市中心能获得要塞防御加成的bug
4.修复了[车]职阶英雄在被动移动时也会产生溅射伤害的bug
5.修复了移动溅射在被动移动(如被挤开)也会生效的bug,完善了描述
6.修复了勇仪推人致死结果贴图错误
7.修复了洩矢诹访子创造御射宫司大人时会重置和平奇观计数的bug
8.优化了顶部信息栏金币显示排版问题
9.优化了多个窗口重叠时,快捷键“右键”及"Esc"关闭窗口的顺序
10.修复了间谍攻击隐身单位占据的城市中心时出错(反复播放攻击动画)的bug
11.修复了城墙建造后城市中心的单位没有立刻刷新状态的bug
2026-06-07 00:15:12 +08:00

358 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using RuntimeData;
using TH1_Logic.Core;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace TH1_UI.View.Top
{
public class UITopTopBarView : Base.View
{
private const string TopBarAnimTimerMessage = "UITopTopBarView TopBarAnim";
private const float CoinSelfCheckInterval = 0.5f;
private int _topBarAnimVersion;
private bool _coinAnimActive;
private float _coinAnimEndTime;
private float _nextCoinSelfCheckTime;
//public Button closeButton;
public ViDelegateAssisstant.Dele OnBtnCloseClick;
public TextMeshProUGUI Faith;
public TextMeshProUGUI Turn;
public TextMeshProUGUI Coin;
public TextMeshProUGUI CoinPerTurn;
public Transform CoinTransform;
public Transform FaithTransform;
public TextMeshProUGUI Tech;
public TextMeshProUGUI TechPerTurn;
public Transform TechTransform;
public TextMeshProUGUI Culture;
public TextMeshProUGUI CulturePerTurn;
public Transform CultureTransform;
public RectTransform FatherPanel;
public GameObject PerfectTime;
public enum TopBarPanelType
{
Coin,
Faith,
Tech,
Culture
}
protected override void OnInit()
{
base.OnInit();
//closeButton.onClick.RemoveAllListeners();
//closeButton.onClick.AddListener(() => { OnBtnCloseClick.Invoke(); });
//CheckPanel.InitStart(RefreshStatus);
// 确保所有Transform初始时都是active的等待数据显示逻辑来控制
// 这样可以防止Prefab中误设为inactive导致无法显示
if (CultureTransform != null)
CultureTransform.gameObject.SetActive(true);
if (TechTransform != null)
TechTransform.gameObject.SetActive(true);
}
//通常一局只会set一次,每次都是完全清空,然后绑定新的一个对局的按钮
public void SetContent()
{
UpdateAllInstant();
// 首次SetContent时强制重建布局确保所有Panel的位置和大小正确
RebuildCoinPanelLayout();
}
public void UpdateAllInstant()
{
//注意 开局首次调用本函数所有city都是空percoin和pertech perculture都是0需要controller里的每个update函数来刷新的
if (Main.MapData?.PlayerMap?.SelfPlayerData == null) return;
CancelTopBarAnim();
// PerfectTime仅在Perfect模式下显示
if (PerfectTime != null)
PerfectTime.SetActive(Main.MapData.MapConfig.GameMode == GameMode.PERFECT);
Turn.text = (Main.MapData.PlayerMap.SelfPlayerData.Turn + 1).ToString();
Faith.text = Main.MapData.PlayerMap.SelfPlayerData.PlayerScore.ToString();
SetCoinText(Main.MapData.PlayerMap.SelfPlayerData.PlayerCoin);
CoinPerTurn.text =
"<color=yellow>" +
Main.PlayerLogic.GetPlayerCoinPerTurn(Main.MapData,Main.MapData.PlayerMap.SelfPlayerData.Id)
+ "</color>";
RebuildCoinPanelLayout();
var techPerTurn =
Main.PlayerLogic.GetPlayerTechPointPerTurn(Main.MapData, Main.MapData.PlayerMap.SelfPlayerData.Id);
// 强制根据数据显示/隐藏Tech模块
bool techNeedShow = (techPerTurn > 0 || Main.MapData.PlayerMap.SelfPlayerData.PlayerTechPoint > 0);
if (TechTransform != null)
{
bool wasActive = TechTransform.gameObject.activeSelf;
TechTransform.gameObject.SetActive(techNeedShow);
if (wasActive != techNeedShow)
{
LayoutRebuilder.ForceRebuildLayoutImmediate(FatherPanel);
}
if (techNeedShow)
{
Tech.text = Main.MapData.PlayerMap.SelfPlayerData.PlayerTechPoint.ToString();
TechPerTurn.text = "<color=lightblue>" + techPerTurn + "</color>";
}
}
var culturePerTurn =
Main.PlayerLogic.GetPlayerCulturePointPerTurn(Main.MapData, Main.MapData.PlayerMap.SelfPlayerData.Id);
// 强制根据数据显示/隐藏Culture模块
bool cultureNeedShow = (culturePerTurn > 0 || Main.MapData.PlayerMap.SelfPlayerData.PlayerCultureInfo.PlayerCulture > 0);
//cultureNeedShow = true;
if (CultureTransform != null)
{
bool wasActive = CultureTransform.gameObject.activeSelf;
CultureTransform.gameObject.SetActive(cultureNeedShow);
if (wasActive != cultureNeedShow)
{
LayoutRebuilder.ForceRebuildLayoutImmediate(FatherPanel);
}
if (cultureNeedShow)
{
Culture.text = Main.MapData.PlayerMap.SelfPlayerData.PlayerCultureInfo.PlayerCulture.ToString();
CulturePerTurn.text = "<color=#B343C2>" + culturePerTurn + "</color>";
}
}
}
public void CloseView()
{
//AudioManager.Instance.StopMusic();
}
private void Update()
{
if (Time.time < _nextCoinSelfCheckTime) return;
_nextCoinSelfCheckTime = Time.time + CoinSelfCheckInterval;
SelfCheckCoinText();
}
public void UpdateTurn()
{
Turn.text = (Main.MapData.PlayerMap.SelfPlayerData.Turn + 1).ToString();
}
public void UpdateCoin()
{
if (Main.MapData?.PlayerMap?.SelfPlayerData == null) return;
CancelTopBarAnim();
if (!int.TryParse(Coin.text, out var old))
old = Main.MapData.PlayerMap.SelfPlayerData.PlayerCoin;
float delay = Table.Instance.AnimDataAssets.ProjectileCoinMoveTime;
if (old > Main.MapData.PlayerMap.SelfPlayerData.PlayerCoin) delay = 0f;
TopBarAnim(Coin,old,Main.MapData.PlayerMap.SelfPlayerData.PlayerCoin,delay,TopBarPanelType.Coin);
}
public void UpdateTech()
{
if (Main.MapData?.PlayerMap?.SelfPlayerData == null) return;
var techPerTurn =
Main.PlayerLogic.GetPlayerTechPointPerTurn(Main.MapData, Main.MapData.PlayerMap.SelfPlayerData.Id);
//如果techTransform应该显示的状态和实际状态不一致更新其显示状态
bool needShow = (techPerTurn > 0 || Main.MapData.PlayerMap.SelfPlayerData.PlayerTechPoint > 0);
if (needShow != TechTransform.gameObject.activeSelf)
{
TechTransform.gameObject.SetActive(techPerTurn > 0);
LayoutRebuilder.ForceRebuildLayoutImmediate(FatherPanel);
}
if (needShow)
{
Tech.text = Main.MapData.PlayerMap.SelfPlayerData.PlayerTechPoint.ToString();
TechPerTurn.text = "<color=lightblue>" + techPerTurn + "</color>";
}
}
public void UpdateCulture()
{
if (Main.MapData?.PlayerMap?.SelfPlayerData == null) return;
var culturePerTurn =
Main.PlayerLogic.GetPlayerCulturePointPerTurn(Main.MapData, Main.MapData.PlayerMap.SelfPlayerData.Id);
// 强制根据数据显示/隐藏Culture模块
bool needShow = (culturePerTurn > 0 || Main.MapData.PlayerMap.SelfPlayerData.PlayerCultureInfo.PlayerCulture > 0);
if (CultureTransform != null)
{
bool wasActive = CultureTransform.gameObject.activeSelf;
CultureTransform.gameObject.SetActive(needShow);
if (wasActive != needShow)
{
LayoutRebuilder.ForceRebuildLayoutImmediate(FatherPanel);
}
if (needShow)
{
Culture.text = Main.MapData.PlayerMap.SelfPlayerData.PlayerCultureInfo.PlayerCulture.ToString();
CulturePerTurn.text = "<color=#B343C2>" + culturePerTurn + "</color>";
}
}
}
public void UpdateFaith()
{
if (Main.MapData?.PlayerMap?.SelfPlayerData == null) return;
if (!int.TryParse(Faith.text, out var old)) return;
//不允许脱离action逻辑修改mapData
//Main.PlayerLogic.CalcAllPlayerScore(Main.MapData);
Faith.text = Main.MapData.PlayerMap.SelfPlayerData.PlayerScore.ToString();
/*float delay = Table.Instance.AnimDataAssets.ProjectileCoinMoveTime;
if (old > Main.MapData.PlayerMap.SelfPlayerData.PlayerScore) delay = 0f;
TopBarAnim(Faith,old,Main.MapData.PlayerMap.SelfPlayerData.PlayerScore,delay);
*/
}
private void TopBarAnim(TextMeshProUGUI targetText, int oldValue,int targetValue,float startDelay,TopBarPanelType panelType)
{
var animVersion = _topBarAnimVersion;
int maxTime = 100;
int now = oldValue;
int time = Mathf.Abs(targetValue - oldValue);
int step = targetValue > oldValue ? 1 : -1;
if (time > maxTime)
{
time = maxTime;
step = (targetValue - oldValue) / time;
}
if (time == 0)
{
SetTopBarAnimText(targetText, targetValue, panelType);
return;
}
if (panelType == TopBarPanelType.Coin)
{
_coinAnimActive = true;
_coinAnimEndTime = Time.time + Mathf.Max(0f, startDelay) + (time - 1) * 0.03f + 0.1f;
}
for (int s = 0; s < time; s++)
{
now += step;
//如果时长太长,直接跳到结果
//final Check用来在最后一帧强制对其真实数值coin 或者faith
bool finalCheck = false;
if (s == time - 1)
{
now = targetValue;
finalCheck = true;
}
var panel = panelType;
var text = targetText;
var tmp = now;
var tmps = Mathf.Min(s,200);
Timer.Instance.TimerRegister(this, () =>
{
if (animVersion != _topBarAnimVersion) return;
SetTopBarAnimText(text, tmp, panel);
if (finalCheck)
{
if(panel == TopBarPanelType.Coin && Main.MapData != null)
{
SetTopBarAnimText(text, Main.MapData.PlayerMap.SelfPlayerData.PlayerCoin, panel);
_coinAnimActive = false;
}
}
},tmps * 0.03f + startDelay , TopBarAnimTimerMessage);
}
}
private void CancelTopBarAnim()
{
_topBarAnimVersion++;
_coinAnimActive = false;
Timer.Instance?.CancelByMessage(TopBarAnimTimerMessage);
}
private void SelfCheckCoinText()
{
if (Main.MapData?.PlayerMap?.SelfPlayerData == null || Coin == null) return;
if (_coinAnimActive)
{
if (Time.time <= _coinAnimEndTime) return;
CancelTopBarAnim();
}
var realCoin = Main.MapData.PlayerMap.SelfPlayerData.PlayerCoin;
if (int.TryParse(Coin.text, out var showCoin) && showCoin == realCoin) return;
CancelTopBarAnim();
SetCoinText(realCoin);
}
public void UpdateCoinPerTurn()
{
if (Main.MapData?.PlayerMap?.SelfPlayerData == null) return;
CoinPerTurn.text = "<color=yellow>" + Main.PlayerLogic.GetPlayerCoinPerTurn(Main.MapData,Main.MapData.PlayerMap.SelfPlayerData.Id) + "</color>";
RebuildCoinPanelLayout();
}
private void RebuildCoinPanelLayout()
{
RebuildTopBarLayout(
Coin != null ? Coin.rectTransform : null,
CoinPerTurn != null ? CoinPerTurn.rectTransform : null,
CoinTransform as RectTransform);
}
private void SetTopBarAnimText(TextMeshProUGUI targetText, int value, TopBarPanelType panelType)
{
if (panelType == TopBarPanelType.Coin)
{
SetCoinText(value);
return;
}
if (targetText == null) return;
targetText.text = value.ToString();
}
private void SetCoinText(int value)
{
if (Coin == null) return;
Coin.text = value.ToString();
Coin.ForceMeshUpdate();
RebuildTopBarLayout(Coin.rectTransform, CoinTransform as RectTransform);
}
private void RebuildTopBarLayout(params RectTransform[] rebuildRoots)
{
foreach (var root in rebuildRoots)
{
if (root != null)
LayoutRebuilder.ForceRebuildLayoutImmediate(root);
}
if (FatherPanel != null)
LayoutRebuilder.ForceRebuildLayoutImmediate(FatherPanel);
}
}
}