mirror of
http://47.107.252.169:3000/Roguelite-Game-Developing-Team/Gen_Hack-and-Slash-Roguelite.git
synced 2025-11-20 01:17:12 +08:00
(client) feat:添加基地界面到游玩界面的过程,添加存档管理,技能树变得可用 (#58)
Co-authored-by: m0_75251201 <m0_75251201@noreply.gitcode.com> Reviewed-on: http://47.107.252.169:3000/Roguelite-Game-Developing-Team/Gen_Hack-and-Slash-Roguelite/pulls/58
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Entity;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
|
||||
@@ -7,10 +8,21 @@ namespace UI
|
||||
public class CoinCountUI:MonoBehaviour
|
||||
{
|
||||
public TMP_Text text;
|
||||
public int coinCount;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
|
||||
text.text = coinCount.ToString();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
var playerEntity = Program.Instance.FocusedEntity as Character;
|
||||
if (!playerEntity || playerEntity.Coin == null)
|
||||
return;
|
||||
if (coinCount == playerEntity.Coin.Quantity) return;
|
||||
coinCount = playerEntity.Coin.Quantity;
|
||||
text.text = coinCount.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -176,9 +176,11 @@ namespace UI
|
||||
|
||||
private void GenerateEntityCallback(EntityDef entityDef)
|
||||
{
|
||||
if(entityDef==null)
|
||||
return;
|
||||
entityPlacementUI.currentAction = () =>
|
||||
{
|
||||
Managers.EntityManager.Instance.GenerateEntity(Program.Instance.FocusedDimensionId, entityDef, Utils.MousePosition.GetWorldPosition());
|
||||
Managers.EntityManager.Instance.GenerateCharacterEntity(Program.Instance.FocusedDimensionId, entityDef, Utils.MousePosition.GetWorldPosition());
|
||||
};
|
||||
entityPlacementUI.Prompt = $"当前生成器:\n名称:{entityDef.label}\n描述:{entityDef.description}";
|
||||
entityPlacementUI.snapEnabled = false;
|
||||
@@ -186,6 +188,8 @@ namespace UI
|
||||
}
|
||||
private void GenerateMonsterEntityCallback(MonsterDef monsterDef)
|
||||
{
|
||||
if(monsterDef==null)
|
||||
return;
|
||||
entityPlacementUI.currentAction = () =>
|
||||
{
|
||||
Managers.EntityManager.Instance.GenerateMonsterEntity(Program.Instance.FocusedDimensionId, monsterDef, Utils.MousePosition.GetWorldPosition());
|
||||
@@ -196,6 +200,8 @@ namespace UI
|
||||
}
|
||||
private void GenerateBuildingCallback(BuildingDef def)
|
||||
{
|
||||
if(def==null)
|
||||
return;
|
||||
entityPlacementUI.currentAction = () =>
|
||||
{
|
||||
Managers.EntityManager.Instance.GenerateBuildingEntity(Program.Instance.FocusedDimensionId, def, Utils.MousePosition.GetSnappedWorldPosition());
|
||||
@@ -206,6 +212,8 @@ namespace UI
|
||||
}
|
||||
private void GeneratePickupCallback(ItemDef itemDef)
|
||||
{
|
||||
if(itemDef==null)
|
||||
return;
|
||||
entityPlacementUI.currentAction = () =>
|
||||
{
|
||||
Managers.EntityManager.Instance.GeneratePickupEntity(Program.Instance.FocusedDimensionId, itemDef, Utils.MousePosition.GetWorldPosition());
|
||||
|
||||
@@ -22,8 +22,6 @@ namespace UI
|
||||
}
|
||||
public void TickUI()
|
||||
{
|
||||
if (!IsVisible)
|
||||
return;
|
||||
if (Input.GetKeyDown(KeyCode.Escape))
|
||||
{
|
||||
Base.UIInputControl.Instance.Hide(this);
|
||||
@@ -48,12 +46,14 @@ namespace UI
|
||||
{
|
||||
base.Show();
|
||||
focusBox.SetActive(true);
|
||||
Clock.AddTickUI(this);
|
||||
}
|
||||
|
||||
override public void Hide()
|
||||
public override void Hide()
|
||||
{
|
||||
base.Hide();
|
||||
focusBox.SetActive(false);
|
||||
Clock.RemoveTickUI(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,9 +37,9 @@ namespace UI
|
||||
Program.Instance.OnFocusedEntityChanged -= FocusEntityChanged;
|
||||
}
|
||||
// 如果聚焦实体及其背包存在,则取消订阅背包改变事件。
|
||||
if (focusedEntity != null && focusedEntity.Inventory != null)
|
||||
if (focusedEntity != null && focusedEntity.PlayerInventory != null)
|
||||
{
|
||||
focusedEntity.Inventory.OnInventoryChanged -= UpdateUI;
|
||||
focusedEntity.PlayerInventory.OnInventoryChanged -= UpdateUI;
|
||||
}
|
||||
Clock.RemoveTick(this);
|
||||
}
|
||||
@@ -72,7 +72,7 @@ namespace UI
|
||||
// 如果存在旧的聚焦实体,则先取消订阅其背包改变事件。
|
||||
if (focusedEntity)
|
||||
{
|
||||
focusedEntity.Inventory.OnInventoryChanged -= UpdateUI;
|
||||
focusedEntity.PlayerInventory.OnInventoryChanged -= UpdateUI;
|
||||
}
|
||||
|
||||
// 设置新的聚焦实体,并尝试将其转换为 Character 类型。
|
||||
@@ -81,7 +81,7 @@ namespace UI
|
||||
// 如果新的聚焦实体存在且是 Character 类型,则订阅其背包改变事件。
|
||||
if (focusedEntity)
|
||||
{
|
||||
focusedEntity.Inventory.OnInventoryChanged += UpdateUI;
|
||||
focusedEntity.PlayerInventory.OnInventoryChanged += UpdateUI;
|
||||
}
|
||||
|
||||
// 聚焦实体改变后更新 UI 显示。
|
||||
@@ -102,7 +102,7 @@ namespace UI
|
||||
// 遍历角色的前三个装备槽(假设物品栏只显示前3个槽位)。
|
||||
for (var i = 0; i < 3; i++)
|
||||
{
|
||||
var slot = focusedEntity.Inventory.GetSlot(i);
|
||||
var slot = focusedEntity.PlayerInventory.GetSlot(i);
|
||||
|
||||
if (i == currentSelectedIndex)
|
||||
{
|
||||
|
||||
@@ -15,7 +15,6 @@ namespace UI
|
||||
private void OnEnable()
|
||||
{
|
||||
Clock.AddTickUI(this);
|
||||
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
@@ -25,8 +24,6 @@ namespace UI
|
||||
|
||||
public virtual void TickUI()
|
||||
{
|
||||
if(!IsVisible)
|
||||
return;
|
||||
if (Input.GetKeyDown(KeyCode.Escape) || Input.GetKeyDown(actionButton))
|
||||
UIInputControl.Instance.Hide(this);
|
||||
}
|
||||
|
||||
24
Client/Assets/Scripts/UI/MapViewUI.cs
Normal file
24
Client/Assets/Scripts/UI/MapViewUI.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using Data;
|
||||
using Managers;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
public class MapViewUI:MonoBehaviour
|
||||
{
|
||||
public TMP_Text text;
|
||||
public Image icon;
|
||||
public DimensionDef DimensionDefine;
|
||||
|
||||
public void Init(DimensionDef dimensionDef)
|
||||
{
|
||||
if (dimensionDef == null) return;
|
||||
text.text = $"<color=yellow>{dimensionDef.label}</color>\n{dimensionDef.description}";
|
||||
if (!string.IsNullOrEmpty(dimensionDef.icon))
|
||||
icon.sprite = PackagesImageManager.Instance.GetSprite(dimensionDef.icon);
|
||||
DimensionDefine=dimensionDef;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Client/Assets/Scripts/UI/MapViewUI.cs.meta
Normal file
3
Client/Assets/Scripts/UI/MapViewUI.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a17823520b234a3297fea4642b69a4d7
|
||||
timeCreated: 1759363251
|
||||
@@ -6,7 +6,7 @@ using UnityEngine;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
public class PlayerStateUI : MonoBehaviour, Base.ITick
|
||||
public class PlayerStateUI : MonoBehaviour, ITick
|
||||
{
|
||||
[SerializeField] private BarUI focusedEntityHP;
|
||||
[SerializeField] private BarUI lastEntityHP;
|
||||
@@ -17,14 +17,14 @@ namespace UI
|
||||
[SerializeField] private BuffIconListUI focuseEntityBuffIconList;
|
||||
[SerializeField] private BuffIconListUI lastEntityBuffIconList;
|
||||
[SerializeField] private AttackModeUI attackMode;
|
||||
|
||||
|
||||
public void Tick()
|
||||
{
|
||||
var focusedEntity = Program.Instance.FocusedEntity;
|
||||
if (focusedEntity && focusedEntity.entityDef != null)
|
||||
{
|
||||
focusedEntityHP.Progress =
|
||||
(float)focusedEntity.attributes.health / focusedEntity.entityDef.attributes.health;
|
||||
(float)focusedEntity.AttributesNow.health / focusedEntity.entityDef.attributes.health;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@ namespace UI
|
||||
focuseEntityBuffIconList.gameObject.SetActive(true);
|
||||
lastEntityBuffIconList.gameObject.SetActive(true);
|
||||
attackMode.gameObject.SetActive(true);
|
||||
|
||||
Clock.AddTick(this);
|
||||
}
|
||||
|
||||
public void Hide()
|
||||
@@ -52,11 +54,14 @@ namespace UI
|
||||
focuseEntityBuffIconList.gameObject.SetActive(false);
|
||||
lastEntityBuffIconList.gameObject.SetActive(false);
|
||||
attackMode.gameObject.SetActive(false);
|
||||
|
||||
Clock.RemoveTick(this);
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
UIInputControl.Instance.OnWindowVisibilityChanged += UIChange;
|
||||
Clock.AddTick(this);
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
|
||||
@@ -238,7 +238,7 @@ namespace UI
|
||||
}
|
||||
|
||||
gameObject.SetActive(false);
|
||||
Program.Instance.PlayGame(SelectedCharacter);
|
||||
Program.Instance.SelectCharacterPlayGame(SelectedCharacter);
|
||||
}
|
||||
}
|
||||
}
|
||||
62
Client/Assets/Scripts/UI/SkillTreeNodeInformationUI.cs
Normal file
62
Client/Assets/Scripts/UI/SkillTreeNodeInformationUI.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
using System.Linq;
|
||||
using Base;
|
||||
using Data;
|
||||
using Managers;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
public class SkillTreeNodeInformationUI:UIBase
|
||||
{
|
||||
public TMP_Text label;
|
||||
public TMP_Text description;
|
||||
public TMP_Text coin;
|
||||
public Button purchaseButton;
|
||||
|
||||
public SkillTreeNodeUI currentLink;
|
||||
public SkillTreeDef SkillTreeDef => currentLink.SkillTreeDefine;
|
||||
|
||||
public bool CanUnlock
|
||||
{
|
||||
get
|
||||
{
|
||||
if (SkillTreeDef.cost > Program.Instance.CoinCount)
|
||||
return false;
|
||||
var parent = SkillTreeManager.Instance.GetAllDirectParents(SkillTreeDef);
|
||||
return parent.All(p => SkillTreeManager.Instance.IsSkillTreeUnlocked(p.defName));
|
||||
}
|
||||
}
|
||||
|
||||
public void Init(SkillTreeNodeUI nodeUI)
|
||||
{
|
||||
currentLink = nodeUI;
|
||||
|
||||
label.text = SkillTreeDef.label;
|
||||
description.text = SkillTreeDef.description;
|
||||
coin.text = $"{SkillTreeDef.cost}/{Program.Instance.CoinCount}";
|
||||
if (CanUnlock)
|
||||
{
|
||||
coin.color = Color.white;
|
||||
purchaseButton.interactable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
coin.color = Color.red;
|
||||
purchaseButton.interactable = false;
|
||||
}
|
||||
}
|
||||
public void Purchase()
|
||||
{
|
||||
SkillTreeManager.Instance.UnlockSkillTree(SkillTreeDef.defName);
|
||||
OnHide();
|
||||
currentLink.Refresh();
|
||||
}
|
||||
|
||||
public void OnHide()
|
||||
{
|
||||
UIInputControl.Instance.Hide(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9440a85a9d4d43aab42d798468760e13
|
||||
timeCreated: 1759416081
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using Base;
|
||||
using Data;
|
||||
using Managers;
|
||||
using UnityEngine;
|
||||
@@ -52,7 +53,7 @@ namespace UI
|
||||
[SerializeField] private Color unlockedColor;
|
||||
[SerializeField] private Color lockedColor;
|
||||
[SerializeField] private GameObject shader;
|
||||
|
||||
|
||||
|
||||
public void Init(SkillTreeDef skillTreeDef)
|
||||
{
|
||||
@@ -163,16 +164,14 @@ namespace UI
|
||||
|
||||
public void OnPointerClick(PointerEventData eventData)
|
||||
{
|
||||
if (eventData.button == PointerEventData.InputButton.Left)
|
||||
if (eventData.button != PointerEventData.InputButton.Left) return;
|
||||
var window = UIInputControl.Instance.GetWindow("SkillTreeNodeInformation") as SkillTreeNodeInformationUI;
|
||||
if (!window)
|
||||
{
|
||||
SkillTreeManager.Instance.UnlockSkillTree(SkillTreeDefine.defName);
|
||||
Refresh();
|
||||
}
|
||||
else if (eventData.button == PointerEventData.InputButton.Right)
|
||||
{
|
||||
SkillTreeManager.Instance.LockSkillTree(SkillTreeDefine.defName);
|
||||
Refresh();
|
||||
return;
|
||||
}
|
||||
UIInputControl.Instance.Show(window);
|
||||
window.Init(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -524,7 +524,6 @@ namespace UI
|
||||
foreach (var node in layerNodes)
|
||||
{
|
||||
node.rectTransform.anchoredPosition = new Vector2(layerX, nodeY);
|
||||
Debug.Log($"{layerX},{nodeY}");
|
||||
nodeY += NODE_VERTICAL_SPACING +
|
||||
node.GetRequiredNodeHeight(Managers.SkillTreeManager.Instance
|
||||
.GetAllDirectParents(node.SkillTreeDefine).Count);
|
||||
|
||||
@@ -1,175 +1,70 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Managers;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
public class SkillTreeUI : FullScreenUI
|
||||
public class SkillTreeUI : FullScreenUI
|
||||
{
|
||||
public SkillTreePageUI skillTreePageUIPrefab;
|
||||
public Transform skillTreePageUIParent; // 用于承载 SkillTreePageUI 实例的 Transform
|
||||
|
||||
private List<SkillTreePageUI> _skillTreePageUIs = new List<SkillTreePageUI>();
|
||||
private int _currentPageIndex = 0; // 当前显示的页面索引
|
||||
// 动画相关
|
||||
private bool _isAnimating = false;
|
||||
private float _animationProgress = 0f; // 0到1的进度
|
||||
[SerializeField] private float _animationDuration = 0.3f; // 动画持续时间
|
||||
private int _animationDirection = 0; // -1:左翻页, 1:右翻页 (或0表示无动画)
|
||||
private SkillTreePageUI _currentMovingPage; // 当前正在移动的页面
|
||||
private SkillTreePageUI _targetMovingPage; // 正在移入的页面
|
||||
private float _pageWidth; // 页面的标准宽度,用于计算滑动位置
|
||||
|
||||
public List<SkillTreePageUI> skillTreePages = new List<SkillTreePageUI>();
|
||||
|
||||
private int _index = 0;
|
||||
|
||||
public int Index
|
||||
{
|
||||
get => _index;
|
||||
set
|
||||
{
|
||||
_index = value;
|
||||
if (skillTreePages.Count == 0)
|
||||
return;
|
||||
while (_index < 0)
|
||||
{
|
||||
_index += skillTreePages.Count;
|
||||
}
|
||||
|
||||
while (_index >= skillTreePageUIParent.childCount)
|
||||
{
|
||||
_index -= skillTreePageUIParent.childCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public SkillTreePageUI FocusedSkillTreePage => skillTreePages.Any() ? skillTreePages[Index] : null;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
// 获取所有技能树标签
|
||||
var allTags = Managers.SkillTreeManager.Instance.GetAllTag();
|
||||
if (allTags == null || allTags.Length == 0)
|
||||
{
|
||||
Debug.LogWarning("No skill tree tags found. SkillTreeUI will be empty.");
|
||||
// 可以在这里禁用翻页按钮或显示提示
|
||||
var pageList = SkillTreeManager.Instance.GetAllTag();
|
||||
if (pageList == null)
|
||||
return;
|
||||
}
|
||||
// [改进] 动态获取页面的宽度
|
||||
// 为了准确获取 prefab 的尺寸,最好在编辑器中设置好 prefab 的 RectTransform,
|
||||
// 或者在这里实例化一个临时对象来获取其 RectTransform 信息。
|
||||
var prefabRect = skillTreePageUIPrefab.GetComponent<RectTransform>();
|
||||
if (prefabRect != null)
|
||||
foreach (var page in pageList)
|
||||
{
|
||||
_pageWidth = prefabRect.rect.width;
|
||||
// 如果父级有LayoutGroup或者Canvas Scaler可能影响实际尺寸,需注意
|
||||
// 如果 prefab 是撑满 FullScreenUI 的,那 _pageWidth 应该等于 FullScreenUI 的宽度
|
||||
// 这里假设 SkillTreePageUI 会充满其父级,或者具有固定宽度。
|
||||
// 简单起见,我们也可以假设它充满父级,那么 _pageWidth = parent.GetComponent<RectTransform>().rect.width;
|
||||
if (skillTreePageUIParent != null)
|
||||
{
|
||||
_pageWidth = skillTreePageUIParent.GetComponent<RectTransform>().rect.width;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("SkillTreePageUI Prefab does not have a RectTransform!");
|
||||
_pageWidth = 1920; // fallback default
|
||||
}
|
||||
// 为每个标签实例化并初始化 SkillTreePageUI
|
||||
foreach (var tag in allTags)
|
||||
{
|
||||
var newPage = Instantiate(skillTreePageUIPrefab, skillTreePageUIParent);
|
||||
newPage.name = $"SkillTreePage_{tag}"; // 方便在 Hierarchy 中识别
|
||||
|
||||
// 设置 RectTransform 属性,确保页面正确布局
|
||||
var pageRectTransform = newPage.GetComponent<RectTransform>();
|
||||
pageRectTransform.anchorMin = Vector2.zero;
|
||||
pageRectTransform.anchorMax = Vector2.one;
|
||||
pageRectTransform.pivot = new Vector2(0.5f, 0.5f); // 中心
|
||||
pageRectTransform.anchoredPosition = Vector2.zero;
|
||||
pageRectTransform.sizeDelta = Vector2.zero; // 撑满父级
|
||||
newPage.GenerateAndLayoutAllSkillTrees(tag);
|
||||
_skillTreePageUIs.Add(newPage);
|
||||
// 初始状态下所有页面都先设为激活,通过位置控制显示
|
||||
newPage.gameObject.SetActive(true);
|
||||
}
|
||||
// 根据 _currentPageIndex 设置所有页面的初始位置
|
||||
// 只有当前页面在中央 (0,0),其他页面在屏幕外
|
||||
for (var i = 0; i < _skillTreePageUIs.Count; i++)
|
||||
{
|
||||
_skillTreePageUIs[i].GetComponent<RectTransform>().anchoredPosition =
|
||||
new Vector2(_pageWidth * (i - _currentPageIndex), 0);
|
||||
}
|
||||
// 确保当前页面在层级的最上方,防止被其他未隐藏的页面遮挡
|
||||
if (_skillTreePageUIs.Count > 0)
|
||||
{
|
||||
_skillTreePageUIs[_currentPageIndex].transform.SetAsLastSibling();
|
||||
var pageUI = Instantiate(skillTreePageUIPrefab, skillTreePageUIParent);
|
||||
pageUI.GenerateAndLayoutAllSkillTrees(page);
|
||||
skillTreePages.Add(pageUI);
|
||||
pageUI.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
FocusedSkillTreePage.gameObject.SetActive(true);
|
||||
}
|
||||
// 实现翻页动画
|
||||
public override void TickUI()
|
||||
|
||||
public void OnLeft()
|
||||
{
|
||||
base.TickUI();
|
||||
if (_isAnimating)
|
||||
{
|
||||
_animationProgress += Time.deltaTime / _animationDuration;
|
||||
_animationProgress = Mathf.Clamp01(_animationProgress);
|
||||
// 计算当前页面的目标位置:从 0 移动到 -_pageWidth * _animationDirection
|
||||
var currentX = Mathf.Lerp(0, -_pageWidth * _animationDirection, _animationProgress);
|
||||
_currentMovingPage.GetComponent<RectTransform>().anchoredPosition = new Vector2(currentX, 0);
|
||||
// 计算目标页面的目标位置:从 _pageWidth * _animationDirection 移动到 0
|
||||
var targetX = Mathf.Lerp(_pageWidth * _animationDirection, 0, _animationProgress);
|
||||
_targetMovingPage.GetComponent<RectTransform>().anchoredPosition = new Vector2(targetX, 0);
|
||||
if (_animationProgress >= 1f)
|
||||
{
|
||||
// 动画结束
|
||||
_isAnimating = false;
|
||||
_animationDirection = 0; // 重置动画方向
|
||||
// 更新当前页面索引 (使用 _targetMovingPage 的索引)
|
||||
_currentPageIndex = _skillTreePageUIs.IndexOf(_targetMovingPage);
|
||||
// 确保新的当前页面在正确位置 (0,0)
|
||||
_targetMovingPage.GetComponent<RectTransform>().anchoredPosition = Vector2.zero;
|
||||
// 隐藏所有非当前页面,将其放置到屏幕外,减少渲染负担
|
||||
for (var i = 0; i < _skillTreePageUIs.Count; i++)
|
||||
{
|
||||
if (i != _currentPageIndex)
|
||||
{
|
||||
// 将非当前页面放置到正确的位置,以便下次翻页时能从正确位置移入
|
||||
_skillTreePageUIs[i].GetComponent<RectTransform>().anchoredPosition =
|
||||
new Vector2(_pageWidth * (i - _currentPageIndex), 0);
|
||||
}
|
||||
}
|
||||
// 确保新的当前页面在层级最上方
|
||||
_skillTreePageUIs[_currentPageIndex].transform.SetAsLastSibling();
|
||||
}
|
||||
}
|
||||
FocusedSkillTreePage.gameObject.SetActive(false);
|
||||
Index--;
|
||||
FocusedSkillTreePage.gameObject.SetActive(true);
|
||||
}
|
||||
/// <summary>
|
||||
/// 控制切换到上一页。
|
||||
/// </summary>
|
||||
public void TurnPageLeft()
|
||||
|
||||
public void OnRight()
|
||||
{
|
||||
if (_isAnimating) return; // 动画进行中,忽略新的翻页请求
|
||||
// 检查是否已经到达第一页
|
||||
if (_currentPageIndex <= 0)
|
||||
{
|
||||
Debug.Log("SkillTreeUI: Already at the first page.");
|
||||
return;
|
||||
}
|
||||
_animationDirection = -1; // 左翻页方向
|
||||
StartPageTurnAnimation(_currentPageIndex - 1);
|
||||
FocusedSkillTreePage.gameObject.SetActive(false);
|
||||
Index++;
|
||||
FocusedSkillTreePage.gameObject.SetActive(true);
|
||||
}
|
||||
/// <summary>
|
||||
/// 控制切换到下一页。
|
||||
/// </summary>
|
||||
public void TurnPageRight()
|
||||
{
|
||||
if (_isAnimating) return; // 动画进行中,忽略新的翻页请求
|
||||
// 检查是否已经到达最后一页
|
||||
if (_currentPageIndex >= _skillTreePageUIs.Count - 1)
|
||||
{
|
||||
Debug.Log("SkillTreeUI: Already at the last page.");
|
||||
return;
|
||||
}
|
||||
_animationDirection = 1; // 右翻页方向
|
||||
StartPageTurnAnimation(_currentPageIndex + 1);
|
||||
}
|
||||
/// <summary>
|
||||
/// 启动翻页动画的内部方法。
|
||||
/// </summary>
|
||||
/// <param name="targetPageIndex">目标页面的索引。</param>
|
||||
private void StartPageTurnAnimation(int targetPageIndex)
|
||||
{
|
||||
_isAnimating = true;
|
||||
_animationProgress = 0f; // 重置动画进度
|
||||
_currentMovingPage = _skillTreePageUIs[_currentPageIndex];
|
||||
_targetMovingPage = _skillTreePageUIs[targetPageIndex];
|
||||
// 确保参与动画的两个页面都是激活状态
|
||||
_currentMovingPage.gameObject.SetActive(true);
|
||||
_targetMovingPage.gameObject.SetActive(true);
|
||||
// 将目标页面初始位置设置在当前页的左侧或右侧
|
||||
// 例如,如果向右翻页 (_animationDirection = 1),目标页从右边 (_pageWidth) 滑入
|
||||
_targetMovingPage.GetComponent<RectTransform>().anchoredPosition =
|
||||
new Vector2(_pageWidth * _animationDirection, 0);
|
||||
// 确保目标页面在当前页面之上,以便在滑动时覆盖旧页面
|
||||
_targetMovingPage.transform.SetAsLastSibling();
|
||||
}
|
||||
// 可以添加一个 GoToPage(int pageIndex) 方法来直接跳转到某一页
|
||||
// 这里为了简化,只实现了左右翻页
|
||||
}
|
||||
}
|
||||
83
Client/Assets/Scripts/UI/StartPlayUI.cs
Normal file
83
Client/Assets/Scripts/UI/StartPlayUI.cs
Normal file
@@ -0,0 +1,83 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Data;
|
||||
using Managers;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
public class StartPlayUI:FullScreenUI
|
||||
{
|
||||
public Transform iconList;
|
||||
|
||||
private int _currentIndex;
|
||||
|
||||
public int CurrentDimensionIndex
|
||||
{
|
||||
get => _currentIndex;
|
||||
set
|
||||
{
|
||||
_currentIndex = value;
|
||||
if (_currentIndex < 0)
|
||||
{
|
||||
_currentIndex += mapViewUIList.Count;
|
||||
}
|
||||
else if (_currentIndex >= mapViewUIList.Count)
|
||||
{
|
||||
_currentIndex %= mapViewUIList.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public DimensionDef CurrentDimension => mapViewUIList[CurrentDimensionIndex].DimensionDefine;
|
||||
|
||||
public MapViewUI mapViewUIPrefab;
|
||||
public List<MapViewUI> mapViewUIList = new List<MapViewUI>();
|
||||
|
||||
private void Start()
|
||||
{
|
||||
var dimensionDefs = DefineManager.Instance.QueryDefinesByType<DimensionDef>();
|
||||
if(dimensionDefs==null)
|
||||
return;
|
||||
foreach (var d in dimensionDefs)
|
||||
{
|
||||
if(!d.canSelect)
|
||||
continue;
|
||||
var newObj=Instantiate(mapViewUIPrefab,iconList);
|
||||
mapViewUIList.Add(newObj);
|
||||
newObj.Init(d);
|
||||
newObj.gameObject.SetActive(false);
|
||||
newObj.transform.localPosition = Vector3.zero;
|
||||
}
|
||||
|
||||
UpdateUI();
|
||||
}
|
||||
|
||||
public void UpdateUI()
|
||||
{
|
||||
if (mapViewUIList == null)
|
||||
return;
|
||||
for (var i = 0; i < mapViewUIList.Count; i++)
|
||||
{
|
||||
mapViewUIList[i].gameObject.SetActive(i == CurrentDimensionIndex);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnStartGame()
|
||||
{
|
||||
Program.Instance.StartPlayGame(CurrentDimension);
|
||||
}
|
||||
|
||||
public void OnLeft()
|
||||
{
|
||||
CurrentDimensionIndex-=1;
|
||||
UpdateUI();
|
||||
}
|
||||
|
||||
public void OnRight()
|
||||
{
|
||||
CurrentDimensionIndex+=1;
|
||||
UpdateUI();
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Client/Assets/Scripts/UI/StartPlayUI.cs.meta
Normal file
3
Client/Assets/Scripts/UI/StartPlayUI.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 39c9e270bf6946c0a9fc963ce048ee32
|
||||
timeCreated: 1759334581
|
||||
55
Client/Assets/Scripts/UI/WaitStartUI.cs
Normal file
55
Client/Assets/Scripts/UI/WaitStartUI.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
public class WaitStartUI:MonoBehaviour
|
||||
{
|
||||
public TMP_Text text;
|
||||
public string baseText;
|
||||
|
||||
public int dotCount = 3;
|
||||
public int dotCounter = 0;
|
||||
|
||||
public float updateTime = 1;
|
||||
private float timer = 0;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if(string.IsNullOrEmpty(baseText))
|
||||
{
|
||||
baseText = text.text;
|
||||
}
|
||||
else
|
||||
{
|
||||
text.text = baseText;
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
timer+=Time.deltaTime;
|
||||
if (this.timer >= updateTime)
|
||||
{
|
||||
timer-=updateTime;
|
||||
var dots = "";
|
||||
for (var i = 0; i < dotCounter; i++)
|
||||
{
|
||||
dots += ".";
|
||||
}
|
||||
text.text = baseText + dots;
|
||||
dotCounter += 1;
|
||||
if (dotCounter > dotCount)
|
||||
{
|
||||
dotCounter = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Hide()
|
||||
{
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Client/Assets/Scripts/UI/WaitStartUI.cs.meta
Normal file
3
Client/Assets/Scripts/UI/WaitStartUI.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8526602f31724cc39ebdf089255189da
|
||||
timeCreated: 1759368694
|
||||
Reference in New Issue
Block a user