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