diff --git a/Assets/AddressableAssetsData/link.xml b/Assets/AddressableAssetsData/link.xml new file mode 100644 index 00000000..62ce7303 --- /dev/null +++ b/Assets/AddressableAssetsData/link.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Assets/AddressableAssetsData/link.xml.meta b/Assets/AddressableAssetsData/link.xml.meta new file mode 100644 index 00000000..2472afd1 --- /dev/null +++ b/Assets/AddressableAssetsData/link.xml.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 06c4284984209ae4184b0b412cfd93d1 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/so/ally/30201_ayano.asset b/Assets/Resources/so/ally/30201_ayano.asset index 5b8a3837..d339557a 100644 --- a/Assets/Resources/so/ally/30201_ayano.asset +++ b/Assets/Resources/so/ally/30201_ayano.asset @@ -17,6 +17,7 @@ MonoBehaviour: ally_heroID: 30201 isUnlocked: 1 allyType: 0 + allyRolePosition: 4 obsessionTag: "\u9898\u6D77\u6218\u672F" sourceDlcId: ally_heroImage: {fileID: 21300000, guid: dc3bf41a4deb1f9449f007ff7535e138, type: 3} diff --git a/Assets/Resources/so/ally/30202_yuetao.asset b/Assets/Resources/so/ally/30202_yuetao.asset index 754920dd..e834921a 100644 --- a/Assets/Resources/so/ally/30202_yuetao.asset +++ b/Assets/Resources/so/ally/30202_yuetao.asset @@ -17,6 +17,7 @@ MonoBehaviour: ally_heroID: 30202 isUnlocked: 1 allyType: 0 + allyRolePosition: 4 obsessionTag: "\u9038\u4E50\u5171\u8C0B" sourceDlcId: ally_heroImage: {fileID: 21300000, guid: 2658d847700da0541942ef5fdcc378b5, type: 3} diff --git a/Assets/Resources/so/ally/30203_moyuri.asset b/Assets/Resources/so/ally/30203_moyuri.asset index 4dd9743e..b2864bb4 100644 --- a/Assets/Resources/so/ally/30203_moyuri.asset +++ b/Assets/Resources/so/ally/30203_moyuri.asset @@ -17,6 +17,7 @@ MonoBehaviour: ally_heroID: 30203 isUnlocked: 1 allyType: 0 + allyRolePosition: 4 obsessionTag: "\u4F17\u5FD7\u6210\u57CE" sourceDlcId: ally_heroImage: {fileID: 21300000, guid: 440e0141c6eb0144c9e9162f0f278d6b, type: 3} diff --git a/Assets/Resources/so/ally/30204_limiaomiao.asset b/Assets/Resources/so/ally/30204_limiaomiao.asset index 56ce47c3..3fea6a0a 100644 --- a/Assets/Resources/so/ally/30204_limiaomiao.asset +++ b/Assets/Resources/so/ally/30204_limiaomiao.asset @@ -17,6 +17,7 @@ MonoBehaviour: ally_heroID: 30204 isUnlocked: 1 allyType: 0 + allyRolePosition: 4 obsessionTag: "\u8FC7\u6FC0\u884C\u4E3A" sourceDlcId: ally_heroImage: {fileID: 21300000, guid: 7df561841c29f7c4495809fa26c0fd87, type: 3} @@ -250,6 +251,6 @@ MonoBehaviour: skillDescriptionsText: "\u3010\u4F60\u4EEC\u5747\u662F\u201C\u5E2E\u51F6\u201D\u3011\u6D88\u8017\u5168\u90E8\u6CD5\u529B\u503C\u65F6\uFF0C\u81EA\u8EAB\u83B7\u5F97\u201C\u4F24\u5BB3\u6297\u6027\u63D0\u5347\u201D\uFF0C\u63D0\u9AD80.14\uFF0C\u6301\u7EED6\u79D2\uFF1B\u81EA\u8EAB\u83B7\u5F97\u201C\u90FD\u7ED9\u4F60\uFF01\u201D\u3002\n\n\u201C\u4F24\u5BB3\u6297\u6027\u63D0\u5347\u201D\uFF1A\u4F24\u5BB3\u6297\u6027\u63D0\u9AD8\uFF0C\u751F\u6548\u671F\u95F4\u53D7\u5230\u7684\u4F24\u5BB3\u964D\u4F4E\u3002\n\u201C\u90FD\u7ED9\u4F60\uFF01\u201D\uFF1A\u5C06\u81EA\u8EAB\u4E0B\u4E00\u6B21\u53D7\u5230\u7684\u4F24\u5BB3\u6216\u83B7\u5F97\u7684\u589E\u76CA\u8F6C\u79FB\u7ED9\u76F8\u90BB\u5076\u50CF\u3002" thisSkill_levelLimit: 4 isSpecialSkill: 0 - equippedSkillGroupIDs: + equippedSkillGroupIDs: 61e0cc01 equippedEquipment: {fileID: 0} equippedEquipmentId: diff --git a/Assets/Resources/so/ally/30205_winnie.asset b/Assets/Resources/so/ally/30205_winnie.asset index d2a4c1b9..a69b1773 100644 --- a/Assets/Resources/so/ally/30205_winnie.asset +++ b/Assets/Resources/so/ally/30205_winnie.asset @@ -17,6 +17,7 @@ MonoBehaviour: ally_heroID: 30205 isUnlocked: 1 allyType: 0 + allyRolePosition: 4 obsessionTag: "\u9898\u6D77\u6218\u672F" sourceDlcId: ally_heroImage: {fileID: 21300000, guid: 1482ec2642664674f9ec31a7cb9fec90, type: 3} diff --git a/Assets/Resources/so/ally/30206_erendira.asset b/Assets/Resources/so/ally/30206_erendira.asset index 2f6f1cbe..5c14b98c 100644 --- a/Assets/Resources/so/ally/30206_erendira.asset +++ b/Assets/Resources/so/ally/30206_erendira.asset @@ -17,6 +17,7 @@ MonoBehaviour: ally_heroID: 30206 isUnlocked: 1 allyType: 0 + allyRolePosition: 4 obsessionTag: "\u9898\u6D77\u6218\u672F" sourceDlcId: ally_heroImage: {fileID: 21300000, guid: c8f373c5ea610a345a513f33ba768314, type: 3} diff --git a/Assets/Scenes/Songs_Select.unity b/Assets/Scenes/Songs_Select.unity index e959183f..aed19c53 100644 --- a/Assets/Scenes/Songs_Select.unity +++ b/Assets/Scenes/Songs_Select.unity @@ -15187,7 +15187,7 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 1660950642606675524, guid: 2f8645fff0a5d034884405a8e5af53db, type: 3} propertyPath: m_SizeDelta.y - value: 0 + value: 75.49936 objectReference: {fileID: 0} - target: {fileID: 1660950642606675524, guid: 2f8645fff0a5d034884405a8e5af53db, type: 3} propertyPath: m_AnchoredPosition.x @@ -15267,7 +15267,7 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 3823789093604703733, guid: 2f8645fff0a5d034884405a8e5af53db, type: 3} propertyPath: m_PreferredHeight - value: 0 + value: 75.49936 objectReference: {fileID: 0} - target: {fileID: 3851926642032356421, guid: 2f8645fff0a5d034884405a8e5af53db, type: 3} propertyPath: m_AnchorMax.y diff --git a/Assets/Scenes/gamePlay_gamePlay.unity b/Assets/Scenes/gamePlay_gamePlay.unity index 043c7fd2..255bfeb9 100644 --- a/Assets/Scenes/gamePlay_gamePlay.unity +++ b/Assets/Scenes/gamePlay_gamePlay.unity @@ -3167,7 +3167,7 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 2613971938742376913, guid: 83349f645e9e9764ab6c8c66e5b107a3, type: 3} propertyPath: m_AnchoredPosition.y - value: -812.5 + value: -462.5 objectReference: {fileID: 0} - target: {fileID: 2613971938742376913, guid: 83349f645e9e9764ab6c8c66e5b107a3, type: 3} propertyPath: m_LocalEulerAnglesHint.x @@ -11511,7 +11511,7 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 2613971938742376913, guid: 83349f645e9e9764ab6c8c66e5b107a3, type: 3} propertyPath: m_AnchoredPosition.y - value: -447.5 + value: -272.5 objectReference: {fileID: 0} - target: {fileID: 2613971938742376913, guid: 83349f645e9e9764ab6c8c66e5b107a3, type: 3} propertyPath: m_LocalEulerAnglesHint.x @@ -25414,7 +25414,7 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 2613971938742376913, guid: 83349f645e9e9764ab6c8c66e5b107a3, type: 3} propertyPath: m_AnchoredPosition.y - value: -1542.5 + value: -842.5 objectReference: {fileID: 0} - target: {fileID: 2613971938742376913, guid: 83349f645e9e9764ab6c8c66e5b107a3, type: 3} propertyPath: m_LocalEulerAnglesHint.x @@ -33189,7 +33189,7 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} - m_AnchoredPosition: {x: 920, y: 114.999725} + m_AnchoredPosition: {x: 970, y: 160} m_SizeDelta: {x: 100, y: 0} m_Pivot: {x: 0.5, y: 1} --- !u!114 &754636335 @@ -33233,7 +33233,7 @@ MonoBehaviour: m_Top: 0 m_Bottom: 0 m_ChildAlignment: 2 - m_Spacing: 200 + m_Spacing: 25 m_ChildForceExpandWidth: 1 m_ChildForceExpandHeight: 1 m_ChildControlWidth: 0 @@ -38759,6 +38759,8 @@ MonoBehaviour: introMoveDuration: 0.42 introNumberDuration: 0.48 introStepGap: 0.06 + introStaticElementDuration: 0.22 + introBarFillDuration: 0.36 introMvpEnterYOffset: 120 introMvpEnterDuration: 0.42 introMvpEnterEase: 9 @@ -54584,7 +54586,7 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 2613971938742376913, guid: 83349f645e9e9764ab6c8c66e5b107a3, type: 3} propertyPath: m_AnchoredPosition.y - value: -1177.5 + value: -652.5 objectReference: {fileID: 0} - target: {fileID: 2613971938742376913, guid: 83349f645e9e9764ab6c8c66e5b107a3, type: 3} propertyPath: m_LocalEulerAnglesHint.x diff --git a/Assets/artworks/notebook/notebookController.cs b/Assets/artworks/notebook/notebookController.cs index de18398b..6d1d518f 100644 --- a/Assets/artworks/notebook/notebookController.cs +++ b/Assets/artworks/notebook/notebookController.cs @@ -204,6 +204,7 @@ public class notebookController : MonoBehaviour comp.SetFatherImage(so.class_image); if (comp.father_description != null) comp.father_description.text = so.class_description; SetupFatherItem(comp, so, fatherGroup); + UI_OrderedEntryAnimator.PlaySingle(obj, i, 0.18f, 0.012f, -14f, 0.97f, true); if (firstFatherToggle == null) { firstFatherToggle = ResolveFatherToggle(comp); @@ -302,6 +303,7 @@ public class notebookController : MonoBehaviour if (son == null) continue; if (!son.son_isUnlocked) continue; var obj = Instantiate(prefab, parent); + UI_OrderedEntryAnimator.PlaySingle(obj, i, 0.16f, 0.018f, -10f, 0.97f, true); var sonComp = obj.GetComponent(); Toggle sonToggle = null; if (sonComp != null && sonComp.sonToggle != null) sonToggle = sonComp.sonToggle; @@ -396,6 +398,7 @@ public class notebookController : MonoBehaviour } if (passage_title != null) passage_title.text = son.son_title; if (passage_text != null) passage_text.text = son.son_passage; + PlayDetailsRefresh(); } private void InvokeToggleAction(Toggle toggle, System.Action onSelected) @@ -823,4 +826,13 @@ public class notebookController : MonoBehaviour ApplySonDetails(father, son); } + + private void PlayDetailsRefresh() + { + GameObject target = null; + if (detailsImage != null) target = detailsImage.gameObject; + if (target == null && passage_title != null) target = passage_title.gameObject; + if (target == null && passage_text != null) target = passage_text.gameObject; + UI_OrderedEntryAnimator.PlayRefresh(target, 0.16f, -8f, 0.99f, true); + } } diff --git a/Assets/artworks/selectYourSongFirst/heroes_level_image/RatioBar.cs b/Assets/artworks/selectYourSongFirst/heroes_level_image/RatioBar.cs index 3a192ca3..ae913e1d 100644 --- a/Assets/artworks/selectYourSongFirst/heroes_level_image/RatioBar.cs +++ b/Assets/artworks/selectYourSongFirst/heroes_level_image/RatioBar.cs @@ -97,7 +97,7 @@ public class RatioBar : MonoBehaviour { if (heroSO == null) return; - var levelInfo = heroSO.GetEffectiveLevelForCurrentEXP(); + var levelInfo = AllyHeroLevelRuntimeResolver.GetBaseLevelInfo(heroSO); if (levelInfo == null) return; // Documentation text normalized. diff --git a/Assets/artworks/selectYourSongFirst/heroes_level_image/character_detailInformation.cs b/Assets/artworks/selectYourSongFirst/heroes_level_image/character_detailInformation.cs index 1326937d..34c1be1a 100644 --- a/Assets/artworks/selectYourSongFirst/heroes_level_image/character_detailInformation.cs +++ b/Assets/artworks/selectYourSongFirst/heroes_level_image/character_detailInformation.cs @@ -55,7 +55,7 @@ public class character_detailInformation : MonoBehaviour designation_name_combination.text = $"{heroSO.ally_heroDesignation} {heroSO.ally_heroName}"; } - var levelInfo = heroSO.GetEffectiveLevelForCurrentEXP(); + var levelInfo = AllyHeroLevelRuntimeResolver.GetBaseLevelInfo(heroSO); if (levelInfo != null) { int attack = levelInfo.attack; diff --git a/Assets/artworks/selectYourSongFirst/heroes_level_image/levelBar_controller.cs b/Assets/artworks/selectYourSongFirst/heroes_level_image/levelBar_controller.cs index e0f516f7..07236c89 100644 --- a/Assets/artworks/selectYourSongFirst/heroes_level_image/levelBar_controller.cs +++ b/Assets/artworks/selectYourSongFirst/heroes_level_image/levelBar_controller.cs @@ -43,7 +43,7 @@ public class levelBar_controller : MonoBehaviour { if (heroSO == null || heroSO.levelStats == null || heroSO.levelStats.Count == 0) return; - var levelInfo = heroSO.GetEffectiveLevelForCurrentEXP(); + var levelInfo = AllyHeroLevelRuntimeResolver.GetBaseLevelInfo(heroSO); if (levelInfo == null) return; string currentLevel = GetRatingFromSO(heroSO); @@ -71,7 +71,7 @@ public class levelBar_controller : MonoBehaviour } } - int currentEXP = heroSO.ally_currentEXP; + int currentEXP = AllyHeroLevelRuntimeResolver.GetCurrentExp(heroSO); // Documentation text normalized. for (int i = 0; i < 4; i++) @@ -198,15 +198,6 @@ public class levelBar_controller : MonoBehaviour return "C"; } - if (so.ally_heroID <= 0) - { - return so.GetDisplayLevelRatingKey(); - } - - AllyHeroDeployLedger ledger = AllyHeroDeployLedger.EnsureInstance(); - int currentExp = ledger.GetCurrentExp(so.ally_heroID); - int unlockedTier = ledger.GetUnlockedTierIndex(so.ally_heroID); - bool levelLocked = ledger.IsLevelLockEnabled(so.ally_heroID); - return so.GetDisplayLevelRatingKeyFromGrowth(currentExp, unlockedTier, levelLocked); + return AllyHeroLevelRuntimeResolver.GetDisplayRatingKey(so); } } diff --git a/Assets/artworks/selectYourSongFirst/heroes_level_image/loadSkillsSelect.cs b/Assets/artworks/selectYourSongFirst/heroes_level_image/loadSkillsSelect.cs index 1d3e3ed2..3fe0edaa 100644 --- a/Assets/artworks/selectYourSongFirst/heroes_level_image/loadSkillsSelect.cs +++ b/Assets/artworks/selectYourSongFirst/heroes_level_image/loadSkillsSelect.cs @@ -149,10 +149,13 @@ public class loadSkillsSelect : MonoBehaviour : $"Column {columnId}"; Transform skillsContainer = BuildColumnContainer(columnId, columnName); + int cardAnimIndex = 0; foreach (SkillGroup group in columnGroups) { GameObject card = Instantiate(skillCardPrefab, skillsContainer); + UI_OrderedEntryAnimator.PlayFadeOnly(card, cardAnimIndex, 0.16f, 0.012f, true); + cardAnimIndex++; slots_skillSlots slot = card.GetComponent(); if (slot == null) @@ -292,6 +295,7 @@ public class loadSkillsSelect : MonoBehaviour if (columnHeaderPrefab != null) { GameObject header = Instantiate(columnHeaderPrefab, columnContainer.transform); + UI_OrderedEntryAnimator.PlayFadeOnly(header, 0, 0.14f, 0f, true); ApplyColumnHeaderText(header, columnName); } @@ -457,7 +461,7 @@ public class loadSkillsSelect : MonoBehaviour return false; } - int currentLevelId = hero.GetEffectiveLevelForCurrentEXP()?.levelID ?? 0; + int currentLevelId = AllyHeroLevelRuntimeResolver.GetCurrentLevelId(hero); int requiredLevelId = Mathf.Clamp(group.thisSkill_levelLimit, 1, 4); return currentLevelId >= requiredLevelId; } diff --git a/Assets/artworks/selectYourSongFirst/heroes_level_image/loadTeam_select.cs b/Assets/artworks/selectYourSongFirst/heroes_level_image/loadTeam_select.cs index 74e353f6..655e86d5 100644 --- a/Assets/artworks/selectYourSongFirst/heroes_level_image/loadTeam_select.cs +++ b/Assets/artworks/selectYourSongFirst/heroes_level_image/loadTeam_select.cs @@ -124,6 +124,7 @@ public class loadTeam_select : MonoBehaviour if (!so.isUnlocked) continue; var go = Instantiate(roleCardPrefab, contentParent); go.transform.SetParent(contentParent, false); + UI_OrderedEntryAnimator.PlayFadeOnly(go, i, 0.16f, 0.012f, true); var ctrl = go.GetComponent(); if (ctrl == null) { diff --git a/Assets/artworks/selectYourSongFirst/heroes_level_image/load_skill_detail_prefab_inHeroDetailPrefab.cs b/Assets/artworks/selectYourSongFirst/heroes_level_image/load_skill_detail_prefab_inHeroDetailPrefab.cs index f69c45ca..4ebac0be 100644 --- a/Assets/artworks/selectYourSongFirst/heroes_level_image/load_skill_detail_prefab_inHeroDetailPrefab.cs +++ b/Assets/artworks/selectYourSongFirst/heroes_level_image/load_skill_detail_prefab_inHeroDetailPrefab.cs @@ -106,7 +106,7 @@ public class load_skill_detail_prefab_inHeroDetailPrefab : MonoBehaviour } var equippedIds = (found.equippedSkillGroupIDs ?? new int[0]).Where(id => id != 0).ToList(); - var levelInfo = found.GetEffectiveLevelForCurrentEXP(); + var levelInfo = AllyHeroLevelRuntimeResolver.GetBaseLevelInfo(found); int currentMaxSlots = levelInfo?.skill_slot_limited ?? 0; int maxSlotsOverall = 0; @@ -129,6 +129,7 @@ public class load_skill_detail_prefab_inHeroDetailPrefab : MonoBehaviour } var go = Instantiate(skillDetailPrefab, contentParent); + UI_OrderedEntryAnimator.PlayFadeOnly(go, created, 0.16f, 0.012f, true); var detail = go.GetComponent(); if (detail == null) { @@ -157,6 +158,7 @@ public class load_skill_detail_prefab_inHeroDetailPrefab : MonoBehaviour } var emptyGo = Instantiate(skillDetailPrefab, contentParent); + UI_OrderedEntryAnimator.PlayFadeOnly(emptyGo, created, 0.16f, 0.012f, true); var detailEmpty = emptyGo.GetComponent(); if (detailEmpty == null) { diff --git a/Assets/artworks/selectYourSongFirst/heroes_level_image/slots_heroSlots.cs b/Assets/artworks/selectYourSongFirst/heroes_level_image/slots_heroSlots.cs index 0cc60557..8d9cdd43 100644 --- a/Assets/artworks/selectYourSongFirst/heroes_level_image/slots_heroSlots.cs +++ b/Assets/artworks/selectYourSongFirst/heroes_level_image/slots_heroSlots.cs @@ -465,7 +465,7 @@ public class slots_heroSlots : MonoBehaviour, IDropHandler, IBeginDragHandler, I } // Documentation text normalized. - var levelInfo = found.GetEffectiveLevelForCurrentEXP(); + var levelInfo = AllyHeroLevelRuntimeResolver.GetBaseLevelInfo(found); if (levelInfo != null && heroLevelImage != null) { string level = GetRatingFromSO(found); @@ -677,7 +677,7 @@ public class slots_heroSlots : MonoBehaviour, IDropHandler, IBeginDragHandler, I var hero = FindHeroById(id); if (hero != null) { - var levelInfo = hero.GetEffectiveLevelForCurrentEXP(); + var levelInfo = AllyHeroLevelRuntimeResolver.GetBaseLevelInfo(hero); if (levelInfo != null && heroLevelImage != null) { string level = GetRatingFromSO(hero); @@ -731,6 +731,7 @@ public class slots_heroSlots : MonoBehaviour, IDropHandler, IBeginDragHandler, I } // Instantiate skill cards for equipped groups + int skillAnimIndex = 0; foreach (int groupId in hero.equippedSkillGroupIDs) { if (groupId == 0) continue; // Skip empty @@ -739,6 +740,8 @@ public class slots_heroSlots : MonoBehaviour, IDropHandler, IBeginDragHandler, I if (group == null) continue; GameObject skillGo = Instantiate(skillCardPrefab, skillContainer.transform); + UI_OrderedEntryAnimator.PlayFadeOnly(skillGo, skillAnimIndex, 0.14f, 0.01f, true); + skillAnimIndex++; slots_skillSlots skillSlot = skillGo.GetComponent(); if (skillSlot != null) { @@ -874,10 +877,17 @@ public class slots_heroSlots : MonoBehaviour, IDropHandler, IBeginDragHandler, I rt.DOKill(); cg.DOKill(); Vector2 basePos = rt.anchoredPosition; - rt.anchoredPosition = basePos + new Vector2(0f, -changeMoveOffset); + bool canMove = !UI_OrderedEntryAnimator.IsLayoutSensitive(rt); + if (canMove) + { + rt.anchoredPosition = basePos + new Vector2(0f, -changeMoveOffset); + } cg.alpha = 0f; Sequence seq = DOTween.Sequence(); - seq.Join(rt.DOAnchorPos(basePos, changeMoveTime).SetEase(Ease.OutCubic)); + if (canMove) + { + seq.Join(rt.DOAnchorPos(basePos, changeMoveTime).SetEase(Ease.OutCubic)); + } seq.Join(cg.DOFade(1f, changeMoveTime)); seq.Append(cg.DOFade(0f, changeBlinkTime)); seq.Append(cg.DOFade(1f, changeBlinkTime)); diff --git a/Assets/artworks/selectYourSongFirst/heroes_level_image/slots_skillSlots.cs b/Assets/artworks/selectYourSongFirst/heroes_level_image/slots_skillSlots.cs index c8b78932..824c7a2b 100644 --- a/Assets/artworks/selectYourSongFirst/heroes_level_image/slots_skillSlots.cs +++ b/Assets/artworks/selectYourSongFirst/heroes_level_image/slots_skillSlots.cs @@ -155,7 +155,7 @@ public class slots_skillSlots : MonoBehaviour, IPointerClickHandler, IPointerEnt } SkillGroup skillGroup = so.GetSkillGroupByID(skillCard_skillID); - var levelInfo = so.GetEffectiveLevelForCurrentEXP(); + var levelInfo = AllyHeroLevelRuntimeResolver.GetBaseLevelInfo(so); int currentLevel = levelInfo?.levelID ?? 0; int requiredLevel = skillGroup?.thisSkill_levelLimit ?? 1; if (currentLevel < requiredLevel) @@ -191,7 +191,7 @@ public class slots_skillSlots : MonoBehaviour, IPointerClickHandler, IPointerEnt if (!isSelected) { // Documentation text normalized. - var levelInfo = so?.GetEffectiveLevelForCurrentEXP(); + var levelInfo = AllyHeroLevelRuntimeResolver.GetBaseLevelInfo(so); int maxSlots = levelInfo?.skill_slot_limited ?? int.MaxValue; // Documentation text normalized. int currentEquipped = so?.equippedSkillGroupIDs.Where(id => id != 0).Count() ?? 0; @@ -307,7 +307,7 @@ public class slots_skillSlots : MonoBehaviour, IPointerClickHandler, IPointerEnt // Documentation text normalized. string status; - var levelInfo = hero.GetEffectiveLevelForCurrentEXP(); + var levelInfo = AllyHeroLevelRuntimeResolver.GetBaseLevelInfo(hero); int maxSlots = levelInfo?.skill_slot_limited ?? int.MaxValue; int currentEquipped = hero.equippedSkillGroupIDs.Where(id => id != 0).Count(); int requiredLevel = group.thisSkill_levelLimit; diff --git a/Assets/idolsDisplay/UI_Idols.cs b/Assets/idolsDisplay/UI_Idols.cs index 0b68dab5..5fc8fd63 100644 --- a/Assets/idolsDisplay/UI_Idols.cs +++ b/Assets/idolsDisplay/UI_Idols.cs @@ -165,7 +165,13 @@ public class UI_Idols : MonoBehaviour private void HandleQuitClicked() { - gameObject.SetActive(false); + UI_PanelExitUtility.PlayExitThen(gameObject, () => + { + if (gameObject != null) + { + gameObject.SetActive(false); + } + }); } private void BeginStartupSkillValidation() @@ -320,6 +326,7 @@ public class UI_Idols : MonoBehaviour SetObjectState(skillsObj, idolSkillsToggle != null && idolSkillsToggle.isOn); SetObjectState(skinsObj, idolSkinsToggle != null && idolSkinsToggle.isOn); SetObjectState(weaponObj, idolWeaponToggle != null && idolWeaponToggle.isOn); + PlayActiveSectionRefresh(); } private bool AnySectionToggleOn() @@ -421,6 +428,7 @@ public class UI_Idols : MonoBehaviour IdolLevelSnapshot snapshot = BuildLevelSnapshot(hero); GameObject instance = GetOrCreateCard(visibleCardCount); + UI_OrderedEntryAnimator.PlaySingle(instance, visibleCardCount, 0.18f, 0.015f, -18f, 0.965f, true); visibleCardCount++; idolCardPrefab card = instance.GetComponent(); @@ -567,6 +575,7 @@ public class UI_Idols : MonoBehaviour ApplyBehaviourRadar(hero); PopulateSpecialSkills(hero); + UI_OrderedEntryAnimator.PlayRefresh(rightPanel, 0.16f, -8f, 0.99f, true); } private void SetIdolDocumentText(string value) @@ -693,6 +702,7 @@ public class UI_Idols : MonoBehaviour } GameObject instance = GetOrCreateSpecialSkillEntry(shown); + UI_OrderedEntryAnimator.PlaySingle(instance, shown, 0.16f, 0.025f, -10f, 0.97f, true); ssPrefab display = instance.GetComponent(); if (display != null) @@ -839,6 +849,19 @@ public class UI_Idols : MonoBehaviour return entry; } + private void PlayActiveSectionRefresh() + { + GameObject active = null; + if (levelsObj != null && levelsObj.activeSelf) active = levelsObj; + else if (voicesObj != null && voicesObj.activeSelf) active = voicesObj; + else if (detailPassageObj != null && detailPassageObj.activeSelf) active = detailPassageObj; + else if (skillsObj != null && skillsObj.activeSelf) active = skillsObj; + else if (skinsObj != null && skinsObj.activeSelf) active = skinsObj; + else if (weaponObj != null && weaponObj.activeSelf) active = weaponObj; + + UI_OrderedEntryAnimator.PlayRefresh(active, 0.16f, -8f, 0.99f, true); + } + private static void SetText(Text target, string value) { if (target != null) @@ -939,7 +962,7 @@ public class UI_Idols : MonoBehaviour SetText(il.damageResistant, FormatGrowthPercent(baseLevelInfo != null ? baseLevelInfo.damageResistance : levelInfo.damageResistance, levelInfo.damageResistance)); SetText(il.scoreEfficency, FormatGrowthPercent(baseLevelInfo != null ? baseLevelInfo.scoreEfficiency : levelInfo.scoreEfficiency, levelInfo.scoreEfficiency)); int baseSlotAmount = baseLevelInfo != null ? baseLevelInfo.skill_slot_limited : levelInfo.skill_slot_limited; - int effectiveSlotAmount = currentSelectedHero != null ? currentSelectedHero.GetEffectiveSkillSlotLimit() : levelInfo.skill_slot_limited; + int effectiveSlotAmount = currentSelectedHero != null ? AllyHeroLevelRuntimeResolver.GetEffectiveSkillSlotLimit(currentSelectedHero) : levelInfo.skill_slot_limited; SetText(il.slotAmount, FormatGrowthInt(baseSlotAmount, effectiveSlotAmount)); SetText(il.miss_mr, levelInfo.manaGainOnMiss.ToString()); SetText(il.good_mr, levelInfo.manaGainGood.ToString()); @@ -953,39 +976,12 @@ public class UI_Idols : MonoBehaviour private AllyHero_SO.AllyLevelInfo GetEffectiveLevelInfoFromLedger(AllyHero_SO hero) { - AllyHero_SO.AllyLevelInfo baseLevelInfo = GetBaseLevelInfoFromLedger(hero); - return hero != null ? hero.GetEffectiveLevelInfoWithEquipment(baseLevelInfo) : null; + return AllyHeroLevelRuntimeResolver.GetEffectiveLevelInfo(hero); } private AllyHero_SO.AllyLevelInfo GetBaseLevelInfoFromLedger(AllyHero_SO hero) { - if (hero == null || hero.levelStats == null || hero.levelStats.Count == 0) - { - return null; - } - - List levels = new List(); - for (int i = 0; i < hero.levelStats.Count; i++) - { - if (hero.levelStats[i] != null) - { - levels.Add(hero.levelStats[i]); - } - } - - if (levels.Count == 0) - { - return null; - } - - levels.Sort((left, right) => left.requiredEXP.CompareTo(right.requiredEXP)); - int index = ResolveUnlockedLevelIndexFromLedger(hero, levels, AllyHeroDeployLedger.EnsureInstance()); - if (index < 0 || index >= levels.Count) - { - return null; - } - - return levels[index]; + return AllyHeroLevelRuntimeResolver.GetBaseLevelInfo(hero); } private int ResolveUnlockedLevelIndexFromLedger(AllyHero_SO hero, List levels, AllyHeroDeployLedger ledger) diff --git a/Assets/idolsDisplay/idolEquipments.cs b/Assets/idolsDisplay/idolEquipments.cs index b8b94705..39e10e55 100644 --- a/Assets/idolsDisplay/idolEquipments.cs +++ b/Assets/idolsDisplay/idolEquipments.cs @@ -440,6 +440,7 @@ public class idolEquipments : MonoBehaviour { equippedItemInstance = Instantiate(eqpmtItemPrefab, eqpmtToPut); equippedItemInstance.name = string.IsNullOrWhiteSpace(equippedEquipment.GetDisplayTierName()) ? equippedEquipment.name : equippedEquipment.GetDisplayTierName(); + UI_OrderedEntryAnimator.PlayFadeOnly(equippedItemInstance, 0, 0.14f, 0f, true); equipItemPrefab item = equippedItemInstance.GetComponent(); if (item != null) @@ -937,6 +938,7 @@ public class idolEquipments : MonoBehaviour { item.SetActive(true); } + UI_OrderedEntryAnimator.PlaySingle(item, index, 0.16f, 0.012f, -10f, 0.97f, true); } return item; diff --git a/Assets/idolsDisplay/idolSkillsHub.cs b/Assets/idolsDisplay/idolSkillsHub.cs index 171ace0e..f0ffcad4 100644 --- a/Assets/idolsDisplay/idolSkillsHub.cs +++ b/Assets/idolsDisplay/idolSkillsHub.cs @@ -61,7 +61,7 @@ public class idolSkillsHub : MonoBehaviour currentHero.LoadEquippedSkillsFromLocal(); int currentTierNumber = GetCurrentTierNumber(currentHero); - int maxSkillSlots = currentHero.GetEffectiveSkillSlotLimit(); + int maxSkillSlots = AllyHeroLevelRuntimeResolver.GetEffectiveSkillSlotLimit(currentHero); int equippedCount = GetEquippedCount(); int visibleIndex = 0; @@ -172,7 +172,7 @@ public class idolSkillsHub : MonoBehaviour return; } - int maxSkillSlots = currentHero.GetEffectiveSkillSlotLimit(); + int maxSkillSlots = AllyHeroLevelRuntimeResolver.GetEffectiveSkillSlotLimit(currentHero); if (equipped.Count >= maxSkillSlots) { Rebuild(); @@ -273,7 +273,7 @@ public class idolSkillsHub : MonoBehaviour return 1; } - return Mathf.Clamp(hero.ally_growthUnlockedTierIndex + 1, 1, 4); + return AllyHeroLevelRuntimeResolver.GetCurrentTierNumber(hero); } private static string GetTierName(int tierNumber) @@ -322,6 +322,7 @@ public class idolSkillsHub : MonoBehaviour { item.SetActive(true); } + UI_OrderedEntryAnimator.PlaySingle(item, index, 0.16f, 0.018f, -10f, 0.97f, true); } return item; diff --git a/Assets/idolsDisplay/levels/idolUpgrade.cs b/Assets/idolsDisplay/levels/idolUpgrade.cs index 500dcf29..f1c034a0 100644 --- a/Assets/idolsDisplay/levels/idolUpgrade.cs +++ b/Assets/idolsDisplay/levels/idolUpgrade.cs @@ -1285,6 +1285,7 @@ public class idolUpgrade : MonoBehaviour } GameObject instance = Instantiate(materialPrefab, materialContainer); + UI_OrderedEntryAnimator.PlaySingle(instance, materialContainer.childCount - 1, 0.16f, 0.016f, -10f, 0.97f, true); materialPrefab item = instance.GetComponent(); if (item != null) { diff --git a/Assets/itemGet/itemGetPrefab.cs b/Assets/itemGet/itemGetPrefab.cs index cff4655c..e7bf8d9f 100644 --- a/Assets/itemGet/itemGetPrefab.cs +++ b/Assets/itemGet/itemGetPrefab.cs @@ -15,6 +15,7 @@ public class itemGetPrefab : MonoBehaviour public Button close; private readonly List spawnedItems = new List(); + private Coroutine layoutRefreshRoutine; private void Awake() { @@ -52,6 +53,8 @@ public class itemGetPrefab : MonoBehaviour Destroy(displayParent.GetChild(i).gameObject); } } + + RequestLayoutRebuild(); } public get_item_prefab AddItem() @@ -63,11 +66,61 @@ public class itemGetPrefab : MonoBehaviour GameObject instance = Instantiate(itemPrefab, displayParent); spawnedItems.Add(instance); + UI_OrderedEntryAnimator.PlayFadeOnly(instance, spawnedItems.Count - 1, 0.2f, 0.025f, true); + RequestLayoutRebuild(); return instance.GetComponent(); } + private void RequestLayoutRebuild() + { + if (displayParent == null) + { + return; + } + + if (layoutRefreshRoutine != null) + { + StopCoroutine(layoutRefreshRoutine); + layoutRefreshRoutine = null; + } + + if (isActiveAndEnabled) + { + layoutRefreshRoutine = StartCoroutine(RebuildLayoutNextFrame()); + return; + } + + RebuildLayoutNow(); + } + + private System.Collections.IEnumerator RebuildLayoutNextFrame() + { + yield return null; + RebuildLayoutNow(); + layoutRefreshRoutine = null; + } + + private void RebuildLayoutNow() + { + RectTransform rect = displayParent as RectTransform; + if (rect == null) + { + return; + } + + Canvas.ForceUpdateCanvases(); + LayoutRebuilder.ForceRebuildLayoutImmediate(rect); + Canvas.ForceUpdateCanvases(); + } + public void CloseSelf() { - Destroy(gameObject); + UI_PanelExitUtility.PlayExitThen(gameObject, () => + { + if (gameObject != null) + { + Destroy(gameObject); + } + }); } } diff --git a/Assets/mailSystem/mailSlotPrefab.cs b/Assets/mailSystem/mailSlotPrefab.cs index 7f1504bc..ab4b1864 100644 --- a/Assets/mailSystem/mailSlotPrefab.cs +++ b/Assets/mailSystem/mailSlotPrefab.cs @@ -69,6 +69,7 @@ public class mailSlotPrefab : MonoBehaviour } GameObject go = Instantiate(rewardPreviewPrefab, rewardPreviewRoot); + UI_OrderedEntryAnimator.PlayFadeOnly(go, i, 0.14f, 0.01f, true); Image icon = go.GetComponent(); if (icon == null) { diff --git a/Assets/mailSystem/rewardSlotPrefab.cs b/Assets/mailSystem/rewardSlotPrefab.cs index 5588f33f..0f97b18f 100644 --- a/Assets/mailSystem/rewardSlotPrefab.cs +++ b/Assets/mailSystem/rewardSlotPrefab.cs @@ -1,6 +1,7 @@ using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; +using DG.Tweening; public class rewardSlotPrefab : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler { @@ -77,11 +78,40 @@ public class rewardSlotPrefab : MonoBehaviour, IPointerEnterHandler, IPointerExi public void OnPointerEnter(PointerEventData eventData) { - if (detailBtm != null) detailBtm.SetActive(true); + if (detailBtm == null) + { + return; + } + + detailBtm.SetActive(true); + UI_OrderedEntryAnimator.PlayFadeOnly(detailBtm, 0, 0.12f, 0f, true); } public void OnPointerExit(PointerEventData eventData) { - if (detailBtm != null) detailBtm.SetActive(false); + if (detailBtm == null) + { + return; + } + + CanvasGroup group = detailBtm.GetComponent(); + if (group == null) + { + group = detailBtm.AddComponent(); + } + + group.DOKill(); + group.DOFade(0f, 0.1f) + .SetEase(Ease.OutQuad) + .SetUpdate(true) + .SetTarget(detailBtm) + .OnComplete(() => + { + if (detailBtm != null) + { + detailBtm.SetActive(false); + group.alpha = 1f; + } + }); } } diff --git a/Assets/playerBagSystem/UI_userBag.cs b/Assets/playerBagSystem/UI_userBag.cs index 9c6b87aa..20c2a8bc 100644 --- a/Assets/playerBagSystem/UI_userBag.cs +++ b/Assets/playerBagSystem/UI_userBag.cs @@ -32,6 +32,7 @@ public class UI_userBag : MonoBehaviour [Header("button")] public Button closeBagButton; + private bool isClosing; private void Awake() { @@ -43,6 +44,7 @@ public class UI_userBag : MonoBehaviour private void OnEnable() { + isClosing = false; InitializeToggleGroup(); BindToggles(); BindCloseButton(); @@ -189,14 +191,21 @@ public class UI_userBag : MonoBehaviour private void HandleCloseBagClicked() { - uBag bagRoot = GetComponentInParent(); - if (bagRoot != null) + if (isClosing) { - Destroy(bagRoot.gameObject); return; } - Destroy(gameObject); + isClosing = true; + uBag bagRoot = GetComponentInParent(); + GameObject target = bagRoot != null ? bagRoot.gameObject : gameObject; + UI_PanelExitUtility.PlayExitThen(target, () => + { + if (target != null) + { + Destroy(target); + } + }); } private void ApplyPanelState(GameObject activeObject) @@ -221,7 +230,12 @@ public class UI_userBag : MonoBehaviour return; } + bool wasActive = target.activeInHierarchy; target.SetActive(active); + if (active && !wasActive) + { + UI_OrderedEntryAnimator.PlayRefresh(target, 0.14f, -6f, 0.99f, true); + } } private void SetToggleInteractable(Toggle toggle, bool interactable) diff --git a/Assets/playerBagSystem/uBag.cs b/Assets/playerBagSystem/uBag.cs index d80855b1..26dd9254 100644 --- a/Assets/playerBagSystem/uBag.cs +++ b/Assets/playerBagSystem/uBag.cs @@ -534,6 +534,7 @@ public class uBag : MonoBehaviour } PositionIntroduction(source, spawnedIntroduction); + UI_OrderedEntryAnimator.PlayFadeOnly(spawnedIntroduction, 0, 0.16f, 0f, true); } public void HidePreviewFor(uBagItemPrefab source) @@ -862,6 +863,7 @@ public class uBag : MonoBehaviour GameObject instance = Instantiate(itemPrefab, itemParent); instance.name = $"uBagItem_{entry.stableId}"; spawnedItems.Add(instance); + UI_OrderedEntryAnimator.PlaySingle(instance, spawnedItems.Count - 1, 0.18f, 0.01f, -16f, 0.965f, true); uBagItemPrefab prefabView = instance.GetComponent(); if (prefabView != null) @@ -973,6 +975,8 @@ public class uBag : MonoBehaviour { itemDescription.text = entry.description ?? string.Empty; } + + PlayRightPanelRefresh(); } private void ClearRightPanel() @@ -1024,6 +1028,17 @@ public class uBag : MonoBehaviour { itemDescription.text = string.Empty; } + + PlayRightPanelRefresh(); + } + + private void PlayRightPanelRefresh() + { + GameObject target = null; + if (btmImg != null) target = btmImg.gameObject; + if (target == null && itemDprofile != null) target = itemDprofile.gameObject; + if (target == null && itemName != null) target = itemName.gameObject; + UI_OrderedEntryAnimator.PlayRefresh(target, 0.14f, -6f, 0.99f, true); } private static int CompareEntries(BagEntry left, BagEntry right) diff --git a/Assets/playerDisplay/UI_Player.cs b/Assets/playerDisplay/UI_Player.cs index b98af423..74d390d9 100644 --- a/Assets/playerDisplay/UI_Player.cs +++ b/Assets/playerDisplay/UI_Player.cs @@ -123,7 +123,13 @@ public class UI_Player : MonoBehaviour private void ClosePanel() { - gameObject.SetActive(false); + UI_PanelExitUtility.PlayExitThen(gameObject, () => + { + if (gameObject != null) + { + gameObject.SetActive(false); + } + }); } private void RestartForceRefreshUiRoutine() @@ -505,6 +511,7 @@ public class UI_Player : MonoBehaviour GameObject entryObject = Instantiate(pInfoPrefab, pInfoParent); spawnedInfoEntries.Add(entryObject); + UI_OrderedEntryAnimator.PlaySingle(entryObject, spawnedInfoEntries.Count - 1, 0.17f, 0.014f, -12f, 0.97f, true); pInfoPrefab entry = entryObject.GetComponent(); if (entry == null) diff --git a/Assets/playerInfoDisplay/uRecentGameHistory.cs b/Assets/playerInfoDisplay/uRecentGameHistory.cs index de424bbb..5730b783 100644 --- a/Assets/playerInfoDisplay/uRecentGameHistory.cs +++ b/Assets/playerInfoDisplay/uRecentGameHistory.cs @@ -77,6 +77,7 @@ public class uRecentGameHistory : MonoBehaviour GameObject instance = Instantiate(gameHistoryPrefab, gameHistoryParent); instance.transform.localScale *= prefabScaleRatio; previewEntries.Add(instance); + UI_OrderedEntryAnimator.PlaySingle(instance, i, 0.18f, 0.015f, -14f, 0.97f, true); ghPrefab controller = instance.GetComponent(); if (controller == null) { @@ -92,6 +93,7 @@ public class uRecentGameHistory : MonoBehaviour if (more_gameHistory != null) { more_gameHistory.SetActive(true); + UI_OrderedEntryAnimator.PlayRefresh(more_gameHistory, 0.18f, -10f, 0.985f, true); } if (dGameHistoryParent == null || gameHistoryPrefab == null) @@ -118,6 +120,7 @@ public class uRecentGameHistory : MonoBehaviour GameObject instance = Instantiate(gameHistoryPrefab, dGameHistoryParent); detailEntries.Add(instance); + UI_OrderedEntryAnimator.PlaySingle(instance, i, 0.16f, 0.012f, -12f, 0.97f, true); ghPrefab controller = instance.GetComponent(); if (controller == null) @@ -131,11 +134,20 @@ public class uRecentGameHistory : MonoBehaviour private void CloseDetailedHistory() { - ClearEntries(detailEntries, dGameHistoryParent); if (more_gameHistory != null) { - more_gameHistory.SetActive(false); + UI_PanelExitUtility.PlayExitThen(more_gameHistory, () => + { + ClearEntries(detailEntries, dGameHistoryParent); + if (more_gameHistory != null) + { + more_gameHistory.SetActive(false); + } + }); + return; } + + ClearEntries(detailEntries, dGameHistoryParent); } private SongData FindSongById(int songId) diff --git a/Assets/scripts/Audio/BgmPlaybackManager.cs b/Assets/scripts/Audio/BgmPlaybackManager.cs index 95c6c776..7d336a64 100644 --- a/Assets/scripts/Audio/BgmPlaybackManager.cs +++ b/Assets/scripts/Audio/BgmPlaybackManager.cs @@ -192,7 +192,10 @@ public class BgmPlaybackManager : MonoBehaviour } if (audioSource.clip != null && !audioSource.isPlaying) + { audioSource.Play(); + StopLegacyMusicManagerSources(); + } } private IEnumerator LoadClipRoutine() @@ -248,7 +251,10 @@ public class BgmPlaybackManager : MonoBehaviour } if (audioSource.clip != null && !audioSource.isPlaying) + { audioSource.Play(); + StopLegacyMusicManagerSources(); + } if (loadClipRoutine != null) { @@ -342,6 +348,45 @@ public class BgmPlaybackManager : MonoBehaviour audioSource.loop = loop; audioSource.time = 0f; audioSource.Play(); + StopLegacyMusicManagerSources(); + } + + public void PlayExternalClip(AudioClip externalClip, bool restart) + { + if (externalClip == null) + { + return; + } + + if (!ShouldPlayInScene(SceneManager.GetActiveScene().name)) + { + StopLobbyAudioAndParticles(); + return; + } + + if (audioSource == null) + { + audioSource = gameObject.AddComponent(); + } + + ApplyOutputMixerGroup(); + + bool clipChanged = audioSource.clip != externalClip; + clip = externalClip; + audioSource.clip = externalClip; + audioSource.loop = loop; + + if (restart || clipChanged) + { + audioSource.time = 0f; + } + + if (!audioSource.isPlaying || restart || clipChanged) + { + audioSource.Play(); + } + + StopLegacyMusicManagerSources(); } public void Next() @@ -400,6 +445,24 @@ public class BgmPlaybackManager : MonoBehaviour } } + private void StopLegacyMusicManagerSources() + { + var managers = FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None); + for (int i = 0; i < managers.Length; i++) + { + Music_Mgr manager = managers[i]; + if (manager == null || manager.AudioSource == null || manager.AudioSource == audioSource) + { + continue; + } + + if (manager.AudioSource.isPlaying) + { + manager.AudioSource.Stop(); + } + } + } + public float CurrentTime => audioSource != null ? audioSource.time : 0f; public float TotalTime => (audioSource != null && audioSource.clip != null) ? audioSource.clip.length : 0f; public bool IsReady => audioSource != null && audioSource.clip != null; diff --git a/Assets/scripts/InGameAchievements/InGamePerformanceManager.cs b/Assets/scripts/InGameAchievements/InGamePerformanceManager.cs index 10ec17a7..2d4a4997 100644 --- a/Assets/scripts/InGameAchievements/InGamePerformanceManager.cs +++ b/Assets/scripts/InGameAchievements/InGamePerformanceManager.cs @@ -205,8 +205,9 @@ public class InGamePerformanceManager : MonoBehaviour .OrderByDescending(info => (int)info.level.rarity) .ToList(); - foreach (var info in sortedAchievements) + for (int i = 0; i < sortedAchievements.Count; i++) { + var info = sortedAchievements[i]; var cat = info.sourceSO != null ? info.sourceSO.category : AchievementCategory.Combo; GameObject targetParent = place_to_putdown; @@ -219,6 +220,7 @@ public class InGamePerformanceManager : MonoBehaviour GameObject prefabToSpawn = (info.sourceSO != null && info.sourceSO.customPrefab != null) ? info.sourceSO.customPrefab : archievePrefab; GameObject go = Instantiate(prefabToSpawn, targetParent.transform); + UI_OrderedEntryAnimator.PlayFadeOnly(go, i, 0.16f, 0.012f, true); var script = go.GetComponent(); if (script != null) diff --git a/Assets/scripts/Main_main/pressStart.cs b/Assets/scripts/Main_main/pressStart.cs index dbcc451f..e2ec4069 100644 --- a/Assets/scripts/Main_main/pressStart.cs +++ b/Assets/scripts/Main_main/pressStart.cs @@ -57,6 +57,7 @@ public class pressStart : MonoBehaviour // polling private Coroutine pollCoroutine; private float pollInterval = 3f; + private UI_PanelPopupTween helpPopupTween; // Start is called before the first frame update void Start() @@ -90,6 +91,11 @@ public class pressStart : MonoBehaviour } if (helpContentObject != null) { + helpPopupTween = helpContentObject.GetComponent(); + if (helpPopupTween == null) + { + helpPopupTween = helpContentObject.AddComponent(); + } helpContentObject.SetActive(false); } @@ -198,7 +204,22 @@ public class pressStart : MonoBehaviour if (helpContentObject != null) { bool isActive = helpContentObject.activeSelf; - helpContentObject.SetActive(!isActive); + if (isActive) + { + HideHelpContentWithExitAnim(); + } + else + { + if (helpPopupTween == null) + { + helpPopupTween = helpContentObject.GetComponent(); + if (helpPopupTween == null) + { + helpPopupTween = helpContentObject.AddComponent(); + } + } + helpContentObject.SetActive(true); + } Debug.Log("[pressStart] Help button clicked. Help content active: " + !isActive); } } @@ -207,11 +228,27 @@ public class pressStart : MonoBehaviour { if (helpContentObject != null) { - helpContentObject.SetActive(false); + HideHelpContentWithExitAnim(); Debug.Log("[pressStart] Close button clicked. Help content hidden."); } } + private void HideHelpContentWithExitAnim() + { + if (helpContentObject == null || !helpContentObject.activeInHierarchy) + { + return; + } + + UI_PanelExitUtility.PlayExitThen(helpContentObject, () => + { + if (helpContentObject != null) + { + helpContentObject.SetActive(false); + } + }); + } + private void OnExitButtonClick() { Debug.Log("[pressStart] Exit button clicked. Application quitting."); diff --git a/Assets/scripts/SongsSelect/UI_SongsSelect_EnterAnim.cs b/Assets/scripts/SongsSelect/UI_SongsSelect_EnterAnim.cs index d7249908..0ee17456 100644 --- a/Assets/scripts/SongsSelect/UI_SongsSelect_EnterAnim.cs +++ b/Assets/scripts/SongsSelect/UI_SongsSelect_EnterAnim.cs @@ -37,6 +37,7 @@ public class UI_SongsSelect_EnterAnim : MonoBehaviour public CanvasGroup canvasGroup; public float baseAlpha; public bool createdCanvasGroup; + public bool restoreTransform; } private class SelectableState @@ -114,6 +115,7 @@ public class UI_SongsSelect_EnterAnim : MonoBehaviour Vector2 basePos = rt.anchoredPosition; float baseAlpha = group.alpha <= 0f ? 1f : group.alpha; + bool layoutSensitive = UI_OrderedEntryAnimator.IsLayoutSensitive(rt); nodeStates.Add(new NodeState { @@ -121,20 +123,27 @@ public class UI_SongsSelect_EnterAnim : MonoBehaviour basePos = basePos, canvasGroup = group, baseAlpha = baseAlpha, - createdCanvasGroup = created + createdCanvasGroup = created, + restoreTransform = !layoutSensitive }); rt.DOKill(); group.DOKill(); - rt.anchoredPosition = basePos - new Vector2(0f, Mathf.Abs(fromOffsetY)); + if (!layoutSensitive) + { + rt.anchoredPosition = basePos - new Vector2(0f, Mathf.Abs(fromOffsetY)); + } group.alpha = 0f; float start = i * Mathf.Max(0f, itemStagger); - enterSequence.Insert(start, - rt.DOAnchorPos(basePos, Mathf.Max(0.01f, itemDuration)) - .SetEase(moveEase) - .SetUpdate(useUnscaledTime)); + if (!layoutSensitive) + { + enterSequence.Insert(start, + rt.DOAnchorPos(basePos, Mathf.Max(0.01f, itemDuration)) + .SetEase(moveEase) + .SetUpdate(useUnscaledTime)); + } enterSequence.Insert(start, group.DOFade(baseAlpha, Mathf.Max(0.01f, itemDuration)) .SetEase(fadeEase) @@ -292,7 +301,10 @@ public class UI_SongsSelect_EnterAnim : MonoBehaviour if (st.canvasGroup != null) st.canvasGroup.DOKill(); - st.rect.anchoredPosition = st.basePos; + if (st.restoreTransform) + { + st.rect.anchoredPosition = st.basePos; + } if (st.canvasGroup != null) st.canvasGroup.alpha = st.baseAlpha; } diff --git a/Assets/scripts/Team/TeamSelectorAnimController.cs b/Assets/scripts/Team/TeamSelectorAnimController.cs index 6a49666d..d1514a55 100644 --- a/Assets/scripts/Team/TeamSelectorAnimController.cs +++ b/Assets/scripts/Team/TeamSelectorAnimController.cs @@ -183,31 +183,46 @@ public class TeamSelectorAnimController : MonoBehaviour } if (slotRects == null || slotRects.Count == 0) yield break; - LayoutGroup layout = leftSlotsContainer != null ? leftSlotsContainer.GetComponent() : null; - bool layoutEnabled = layout != null && layout.enabled; if (leftSlotsContainer != null) LayoutRebuilder.ForceRebuildLayoutImmediate(leftSlotsContainer); slotRects.Sort((a, b) => a.GetSiblingIndex().CompareTo(b.GetSiblingIndex())); - if (layoutEnabled) layout.enabled = false; - var basePosBySlot = new Dictionary(slotRects.Count); + var canMoveBySlot = new Dictionary(slotRects.Count); for (int i = 0; i < slotRects.Count; i++) { RectTransform rt = slotRects[i]; if (rt == null) continue; Vector2 basePos = rt.anchoredPosition; basePosBySlot[rt] = basePos; + bool canMove = !UI_OrderedEntryAnimator.IsLayoutSensitive(rt); + canMoveBySlot[rt] = canMove; rt.DOKill(); - rt.anchoredPosition = basePos + new Vector2(0f, -slotEnterOffset); - rt.DOAnchorPos(basePos, slotEnterTime) - .SetEase(Ease.OutCubic) - .SetDelay(i * slotStagger) - .SetUpdate(useUnscaled) - // If a slot gets disabled/enabled during layout/UI updates, don't kill the tween - // (killing it can leave the slot stuck at the start offset). - .SetLink(rt.gameObject, LinkBehaviour.PauseOnDisablePlayOnEnable); + + CanvasGroup cg = EnsureCanvasGroup(rt); + if (cg != null) + { + cg.DOKill(); + cg.alpha = 0f; + cg.DOFade(1f, slotEnterTime) + .SetEase(Ease.OutCubic) + .SetDelay(i * slotStagger) + .SetUpdate(useUnscaled) + .SetLink(rt.gameObject, LinkBehaviour.PauseOnDisablePlayOnEnable); + } + + if (canMove) + { + rt.anchoredPosition = basePos + new Vector2(0f, -slotEnterOffset); + rt.DOAnchorPos(basePos, slotEnterTime) + .SetEase(Ease.OutCubic) + .SetDelay(i * slotStagger) + .SetUpdate(useUnscaled) + // If a slot gets disabled/enabled during layout/UI updates, don't kill the tween + // (killing it can leave the slot stuck at the start offset). + .SetLink(rt.gameObject, LinkBehaviour.PauseOnDisablePlayOnEnable); + } } float total = slotEnterTime + slotStagger * Mathf.Max(0, slotRects.Count - 1); @@ -223,6 +238,7 @@ public class TeamSelectorAnimController : MonoBehaviour { RectTransform rt = kvp.Key; if (rt == null) continue; + if (!canMoveBySlot.TryGetValue(rt, out bool canMove) || !canMove) continue; Vector2 basePos = kvp.Value; if (Vector2.Distance(rt.anchoredPosition, basePos) > 0.5f) { @@ -234,7 +250,6 @@ public class TeamSelectorAnimController : MonoBehaviour } } - if (layoutEnabled) layout.enabled = true; if (leftSlotsContainer != null) LayoutRebuilder.ForceRebuildLayoutImmediate(leftSlotsContainer); } @@ -281,6 +296,20 @@ public class TeamSelectorAnimController : MonoBehaviour void AnimatePanel(RectTransform panel, float offsetX, float delay) { if (panel == null) return; + bool canMove = !UI_OrderedEntryAnimator.IsLayoutSensitive(panel); + CanvasGroup cg = EnsureCanvasGroup(panel); + if (cg != null) + { + cg.DOKill(); + cg.alpha = 0f; + cg.DOFade(1f, panelEnterTime) + .SetEase(Ease.OutCubic) + .SetDelay(delay) + .SetUpdate(useUnscaled) + .SetLink(cg.gameObject, LinkBehaviour.KillOnDisable); + } + if (!canMove) return; + Vector2 basePos = panel.anchoredPosition; panel.DOKill(); panel.anchoredPosition = basePos + new Vector2(offsetX, 0f); @@ -294,6 +323,19 @@ public class TeamSelectorAnimController : MonoBehaviour void AnimateConfirm(RectTransform button) { if (button == null) return; + bool canMove = !UI_OrderedEntryAnimator.IsLayoutSensitive(button); + CanvasGroup cg = EnsureCanvasGroup(button); + if (cg != null) + { + cg.DOKill(); + cg.alpha = 0f; + cg.DOFade(1f, confirmEnterTime) + .SetEase(Ease.OutCubic) + .SetUpdate(useUnscaled) + .SetLink(cg.gameObject, LinkBehaviour.KillOnDisable); + } + if (!canMove) return; + Vector2 basePos = button.anchoredPosition; button.DOKill(); button.anchoredPosition = basePos + new Vector2(0f, -confirmEnterOffset); diff --git a/Assets/scripts/Team/newTeamSelector.cs b/Assets/scripts/Team/newTeamSelector.cs index 80969020..9b854de3 100644 --- a/Assets/scripts/Team/newTeamSelector.cs +++ b/Assets/scripts/Team/newTeamSelector.cs @@ -115,6 +115,7 @@ public class newTeamSelector : MonoBehaviour var go = Instantiate(slotPrefab, container); go.transform.SetParent(container, false); go.name = $"heroSlot_{i}"; + UI_OrderedEntryAnimator.PlayFadeOnly(go, i, 0.16f, 0.012f, true); var slotComp = go.GetComponent(); if (slotComp == null) diff --git a/Assets/scripts/Team/settileTeam/loadSettlementTeamPrefab.cs b/Assets/scripts/Team/settileTeam/loadSettlementTeamPrefab.cs index 9c668a2e..376c2194 100644 --- a/Assets/scripts/Team/settileTeam/loadSettlementTeamPrefab.cs +++ b/Assets/scripts/Team/settileTeam/loadSettlementTeamPrefab.cs @@ -103,8 +103,11 @@ public class loadSettlementTeamPrefab : MonoBehaviour var rectTransform = go.GetComponent(); if (rectTransform != null) { - rectTransform.anchoredPosition = Vector2.zero; - rectTransform.sizeDelta = Vector2.zero; + if (!UI_OrderedEntryAnimator.IsLayoutSensitive(rectTransform)) + { + rectTransform.anchoredPosition = Vector2.zero; + rectTransform.sizeDelta = Vector2.zero; + } spawnedCardRoots.Add(rectTransform); } @@ -296,10 +299,15 @@ public class loadSettlementTeamPrefab : MonoBehaviour CanvasGroup group = GetOrAddCanvasGroup(rt.transform); if (group != null) group.alpha = 0f; - rt.anchoredPosition = new Vector2(basePos.x + offsetX, basePos.y); + bool canMove = !UI_OrderedEntryAnimator.IsLayoutSensitive(rt); + if (canMove) + { + rt.anchoredPosition = new Vector2(basePos.x + offsetX, basePos.y); + } float startAt = i * stagger; // top -> bottom (sibling order) - allySlotEntrySequence.Insert(startAt, rt.DOAnchorPos(basePos, duration).SetEase(allySlotEntryEase).SetUpdate(allySlotEntryUseUnscaledTime)); + if (canMove) + allySlotEntrySequence.Insert(startAt, rt.DOAnchorPos(basePos, duration).SetEase(allySlotEntryEase).SetUpdate(allySlotEntryUseUnscaledTime)); if (group != null) allySlotEntrySequence.Insert(startAt, group.DOFade(1f, duration).SetEase(allySlotEntryEase).SetUpdate(allySlotEntryUseUnscaledTime)); } @@ -336,7 +344,10 @@ public class loadSettlementTeamPrefab : MonoBehaviour if (rt == null) continue; if (i < spawnedCardBasePositions.Count) - rt.anchoredPosition = spawnedCardBasePositions[i]; + { + if (!UI_OrderedEntryAnimator.IsLayoutSensitive(rt)) + rt.anchoredPosition = spawnedCardBasePositions[i]; + } SetCanvasAlpha(rt.transform, 1f); } } diff --git a/Assets/scripts/Team/teamSettingPanel.cs b/Assets/scripts/Team/teamSettingPanel.cs index 199f24a1..304ac7ea 100644 --- a/Assets/scripts/Team/teamSettingPanel.cs +++ b/Assets/scripts/Team/teamSettingPanel.cs @@ -196,7 +196,9 @@ public class teamSettingPanel : MonoBehaviour if (tcdi != null) { if (t.charcterImg != null) { t.charcterImg.sprite = tcdi.CharacterTeamSprite; t.charcterImg.color=new Color(t.charcterImg.color.r,t.charcterImg.color.g,t.charcterImg.color.b,1f); } - if (t.levelIcon != null) { t.levelIcon.sprite = getLevelSprite(currentTeam[i].currentBoundaryLevel); t.levelIcon.color=new Color(t.levelIcon.color.r,t.levelIcon.color.g,t.levelIcon.color.b,1f); } + string boundaryLevel = ResolveBoundaryLevel(t.characterID, currentTeam[i].currentBoundaryLevel); + currentTeam[i].currentBoundaryLevel = boundaryLevel; + if (t.levelIcon != null) { t.levelIcon.sprite = getLevelSprite(boundaryLevel); t.levelIcon.color=new Color(t.levelIcon.color.r,t.levelIcon.color.g,t.levelIcon.color.b,1f); } if (t.skillName != null) t.skillName.text = tcdi.CharacterSkillName ?? string.Empty; } else @@ -230,6 +232,7 @@ public class teamSettingPanel : MonoBehaviour teamManager.currentSelectedCharacterCard = null; List currentTeam = teamManager.getCurrentSelectedTeam().teamIdList; List selectAbleCharacters = teamManager.SelectableCharacterList; + int visibleIndex = 0; foreach (CharacterView c in selectAbleCharacters) //id and level { if (!IsCharacterUnlocked(c != null ? c.characterId : 0)) @@ -238,14 +241,16 @@ public class teamSettingPanel : MonoBehaviour } GameObject characterObj = Instantiate(teamCharacterPrefab, teamCharacterViewContent.transform); + UI_OrderedEntryAnimator.PlayFadeOnly(characterObj, visibleIndex, 0.16f, 0.012f, true); + visibleIndex++; CharacterCardView ccv = characterObj.GetComponent(); TeamCharacterDataInfo tcdi = getCharacterViewInfo(c.characterId); if (ccv != null&& tcdi!=null) { ccv.characterID = tcdi.CharacterID; - ccv.currentBoundaryLevel= c.currentBoundaryLevel; + ccv.currentBoundaryLevel= ResolveBoundaryLevel(c.characterId, c.currentBoundaryLevel); ccv.characterImage.sprite =tcdi.CharacterCardSprite; - ccv.levelIcon.sprite = getLevelSprite(c.currentBoundaryLevel); + ccv.levelIcon.sprite = getLevelSprite(ccv.currentBoundaryLevel); ccv.occupationIcon.sprite = tcdi.CharacterRoleSprite; } @@ -277,6 +282,26 @@ public class teamSettingPanel : MonoBehaviour return false; } + private string ResolveBoundaryLevel(int characterID, string fallbackLevel) + { + if (characterID <= 0) + { + return fallbackLevel; + } + + AllyHero_SO[] heroes = RuntimeResourcesCache.LoadAllAllyHeroes(); + for (int i = 0; i < heroes.Length; i++) + { + AllyHero_SO hero = heroes[i]; + if (hero != null && hero.ally_heroID == characterID) + { + return AllyHeroLevelRuntimeResolver.GetDisplayRatingKey(hero); + } + } + + return fallbackLevel; + } + private bool checkExistenceStatus(List currentTeam,int characterID) { foreach (CharacterView c in currentTeam) diff --git a/Assets/scripts/UI/Panel/UI_Panel_Character.cs b/Assets/scripts/UI/Panel/UI_Panel_Character.cs index 4919b33b..c5e3366f 100644 --- a/Assets/scripts/UI/Panel/UI_Panel_Character.cs +++ b/Assets/scripts/UI/Panel/UI_Panel_Character.cs @@ -59,7 +59,7 @@ class UI_Panel_Character : MonoBehaviour { if (Input.GetKeyDown(KeyCode.Escape)) { - gameObject.SetActive(false); + ClosePanel(); } } @@ -77,7 +77,7 @@ class UI_Panel_Character : MonoBehaviour confirm_thisHero.onClick.AddListener(OnConfirmHeroClicked); if (quitButton != null) - quitButton.onClick.AddListener(() => gameObject.SetActive(false)); + quitButton.onClick.AddListener(ClosePanel); if (Image_Character_Illustration != null) { @@ -126,6 +126,7 @@ class UI_Panel_Character : MonoBehaviour for (int i = 0; i < allyHeroList.Count; i++) { var slotObject = Instantiate(button_Character_Slot_Prefab, content_Character_Slot); + UI_OrderedEntryAnimator.PlayFadeOnly(slotObject, i, 0.16f, 0.012f, true); var displayPrefab = slotObject.GetComponent(); var slotButton = displayPrefab != null ? displayPrefab.characterProfileButton : slotObject.GetComponent