app.hypergames.hypersdk 1.11.3-beta.1 → 1.11.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -1
- package/Runtime/Internal/Core/HyperRuntime.cs +5 -0
- package/Runtime/Internal/Managers/GameManager.cs +16 -0
- package/Runtime/Internal/UI/Modals/GameOverModal.cs +45 -5
- package/Runtime/Internal/UI/Modals/TutorialLoaderModal.cs +0 -2
- package/Runtime/Internal/UI/Modals/TutorialModal.cs +8 -0
- package/Runtime/Resources/UIPrefabs/GameOverModal_Battle.prefab +1 -1
- package/Runtime/Resources/UIPrefabs/GameOverModal_Practice.prefab +117 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
## [1.11.
|
|
1
|
+
## [1.11.4](https://github.com/mvmhyper/hyper-sdk/compare/v1.11.3...v1.11.4) (2026-10-16)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **sdk:** keep Play Again overlay until scene handoff ([baf5397](https://github.com/mvmhyper/hyper-sdk/commit/baf5397fa8f397cc06223f6943abf9baae114035))
|
|
7
|
+
* **sdk:** remove tutorial modal when no tutorial exists ([e6c4f6a](https://github.com/mvmhyper/hyper-sdk/commit/e6c4f6a08e914c2e4b7cdd1488c71b8f2ff05a5c))
|
|
8
|
+
|
|
9
|
+
## [1.11.3](https://github.com/mvmhyper/hyper-sdk/compare/v1.11.2...v1.11.3) (2026-10-15)
|
|
2
10
|
|
|
3
11
|
|
|
4
12
|
### Bug Fixes
|
|
@@ -120,6 +120,7 @@ namespace Hyper.Internal
|
|
|
120
120
|
}
|
|
121
121
|
else
|
|
122
122
|
{
|
|
123
|
+
_gameManager?.PreserveUIForSceneRestart();
|
|
123
124
|
ClearAllDontDestroyOnLoadObjects();
|
|
124
125
|
SceneManager.LoadScene("HyperLoader");
|
|
125
126
|
}
|
|
@@ -215,6 +216,7 @@ namespace Hyper.Internal
|
|
|
215
216
|
}
|
|
216
217
|
else
|
|
217
218
|
{
|
|
219
|
+
_gameManager?.PreserveUIForSceneRestart();
|
|
218
220
|
ClearAllDontDestroyOnLoadObjects();
|
|
219
221
|
SceneManager.LoadScene("HyperLoader");
|
|
220
222
|
}
|
|
@@ -267,6 +269,9 @@ namespace Hyper.Internal
|
|
|
267
269
|
/// </summary>
|
|
268
270
|
private static IEnumerator RestartSessionCoroutine()
|
|
269
271
|
{
|
|
272
|
+
_gameManager?.PreserveUIForSceneRestart();
|
|
273
|
+
// Render the disabled buttons and spinner before scene cleanup starts.
|
|
274
|
+
yield return null;
|
|
270
275
|
yield return UnloadAllScenesCoroutine();
|
|
271
276
|
|
|
272
277
|
Clear();
|
|
@@ -74,6 +74,20 @@ namespace Hyper.Internal.Managers
|
|
|
74
74
|
EndGame();
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
+
internal void PreserveUIForSceneRestart()
|
|
78
|
+
{
|
|
79
|
+
if (_hyperCanvasObject == null) return;
|
|
80
|
+
|
|
81
|
+
// Keep the modal and shade until the game scene unloads, then let the
|
|
82
|
+
// scene destroy them before HyperLoader presents its own loading UI.
|
|
83
|
+
Scene activeScene = SceneManager.GetActiveScene();
|
|
84
|
+
if (_hyperCanvasObject.scene != activeScene)
|
|
85
|
+
{
|
|
86
|
+
SceneManager.MoveGameObjectToScene(_hyperCanvasObject, activeScene);
|
|
87
|
+
}
|
|
88
|
+
_hyperCanvasObject = null;
|
|
89
|
+
}
|
|
90
|
+
|
|
77
91
|
internal void Cleanup()
|
|
78
92
|
{
|
|
79
93
|
StopAllCoroutines();
|
|
@@ -637,6 +651,8 @@ namespace Hyper.Internal.Managers
|
|
|
637
651
|
|
|
638
652
|
internal void AddTutorialModal(bool showModal = false)
|
|
639
653
|
{
|
|
654
|
+
if (_backendManager.tutorialDoesNotExist) return;
|
|
655
|
+
|
|
640
656
|
bool isPortrait = ResolvePortraitFlag();
|
|
641
657
|
var activeModal = EnsureTutorialModal(isPortrait);
|
|
642
658
|
_tutorialModalComponent = activeModal.GetComponent<TutorialModal>();
|
|
@@ -23,11 +23,15 @@ namespace Hyper.Internal
|
|
|
23
23
|
[SerializeField]
|
|
24
24
|
private GameObject loadingBar;
|
|
25
25
|
[SerializeField]
|
|
26
|
-
|
|
26
|
+
[UnityEngine.Serialization.FormerlySerializedAs("loadingCircle")]
|
|
27
|
+
private GameObject exitLoadingCircle;
|
|
28
|
+
[SerializeField]
|
|
29
|
+
private GameObject playAgainLoadingCircle;
|
|
27
30
|
private Slider loadingBarSlider;
|
|
28
31
|
Coroutine sliderCoroutine;
|
|
29
32
|
|
|
30
33
|
private GameManager _gameManager;
|
|
34
|
+
private bool _restartRequested;
|
|
31
35
|
|
|
32
36
|
private void Awake()
|
|
33
37
|
{
|
|
@@ -37,8 +41,10 @@ namespace Hyper.Internal
|
|
|
37
41
|
if (loadingBarSlider != null)
|
|
38
42
|
loadingBarSlider.value = 0.075f;
|
|
39
43
|
|
|
40
|
-
if (
|
|
41
|
-
|
|
44
|
+
if (exitLoadingCircle != null)
|
|
45
|
+
exitLoadingCircle.SetActive(false);
|
|
46
|
+
|
|
47
|
+
SetPlayAgainLoading(false);
|
|
42
48
|
|
|
43
49
|
_gameManager = HyperRuntime.GameManager;
|
|
44
50
|
|
|
@@ -103,6 +109,15 @@ namespace Hyper.Internal
|
|
|
103
109
|
|
|
104
110
|
private void OnEnable()
|
|
105
111
|
{
|
|
112
|
+
_restartRequested = false;
|
|
113
|
+
if (buttonHolder != null)
|
|
114
|
+
{
|
|
115
|
+
buttonHolder.interactable = true;
|
|
116
|
+
buttonHolder.alpha = 1f;
|
|
117
|
+
}
|
|
118
|
+
if (exitLoadingCircle != null) exitLoadingCircle.SetActive(false);
|
|
119
|
+
SetPlayAgainLoading(false);
|
|
120
|
+
|
|
106
121
|
currentScore.text = HyperRuntime.DataManager.CurrentScore.ToString("N0");
|
|
107
122
|
bestScore.text = HyperRuntime.DataManager.GetBestScore().ToString("N0");
|
|
108
123
|
}
|
|
@@ -171,15 +186,40 @@ namespace Hyper.Internal
|
|
|
171
186
|
buttonHolder.interactable = false;
|
|
172
187
|
buttonHolder.alpha = 0.6f;
|
|
173
188
|
|
|
174
|
-
// Enable
|
|
175
|
-
|
|
189
|
+
// Enable only the exit button's loading circle.
|
|
190
|
+
SetPlayAgainLoading(false);
|
|
191
|
+
exitLoadingCircle.SetActive(true);
|
|
176
192
|
|
|
177
193
|
HyperRuntime.DataManager.MuteAudioForGameSessionEnd();
|
|
178
194
|
HyperRuntime.BackendManager.LogEvent(ConsoleEventType.PracticeGameEnd);
|
|
179
195
|
}
|
|
180
196
|
|
|
197
|
+
private void SetPlayAgainLoading(bool isLoading)
|
|
198
|
+
{
|
|
199
|
+
if (playAgainLoadingCircle == null) return;
|
|
200
|
+
|
|
201
|
+
playAgainLoadingCircle.SetActive(isLoading);
|
|
202
|
+
Transform button = playAgainLoadingCircle.transform.parent;
|
|
203
|
+
if (button != null)
|
|
204
|
+
{
|
|
205
|
+
TMP_Text label = button.GetComponentInChildren<TMP_Text>(true);
|
|
206
|
+
if (label != null) label.gameObject.SetActive(!isLoading);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
181
210
|
public void PlayAgain()
|
|
182
211
|
{
|
|
212
|
+
if (_restartRequested) return;
|
|
213
|
+
_restartRequested = true;
|
|
214
|
+
|
|
215
|
+
if (buttonHolder != null)
|
|
216
|
+
{
|
|
217
|
+
buttonHolder.interactable = false;
|
|
218
|
+
buttonHolder.alpha = 0.6f;
|
|
219
|
+
}
|
|
220
|
+
if (exitLoadingCircle != null) exitLoadingCircle.SetActive(false);
|
|
221
|
+
SetPlayAgainLoading(true);
|
|
222
|
+
|
|
183
223
|
HyperRuntime.RestartSession();
|
|
184
224
|
}
|
|
185
225
|
|
|
@@ -26,7 +26,6 @@ namespace Hyper.Internal
|
|
|
26
26
|
rectTransform = GetComponent<RectTransform>();
|
|
27
27
|
|
|
28
28
|
_eventManager.OnTutorialLoadingComplete += HandleTutorialLoadingComplete;
|
|
29
|
-
_eventManager.OnTutorialDoesNotExist += HandleTutorialFailed;
|
|
30
29
|
_eventManager.OnTutorialFetchFailed += HandleTutorialFailed;
|
|
31
30
|
}
|
|
32
31
|
|
|
@@ -48,7 +47,6 @@ namespace Hyper.Internal
|
|
|
48
47
|
{
|
|
49
48
|
_eventManager.OnTutorialLoadingComplete -= HandleTutorialLoadingComplete;
|
|
50
49
|
_eventManager.OnTutorialFetchFailed -= HandleTutorialFailed;
|
|
51
|
-
_eventManager.OnTutorialDoesNotExist -= HandleTutorialFailed;
|
|
52
50
|
}
|
|
53
51
|
}
|
|
54
52
|
|
|
@@ -108,6 +108,7 @@ namespace Hyper.Internal
|
|
|
108
108
|
|
|
109
109
|
_eventManager.OnTutorialResourcesReferenced += ShowTutorialBasedOnType;
|
|
110
110
|
_eventManager.OnTutorialLoadingComplete += HandleTutorialLoadingComplete;
|
|
111
|
+
_eventManager.OnTutorialDoesNotExist += HandleTutorialDoesNotExist;
|
|
111
112
|
}
|
|
112
113
|
|
|
113
114
|
void OnEnable()
|
|
@@ -1133,12 +1134,19 @@ namespace Hyper.Internal
|
|
|
1133
1134
|
}
|
|
1134
1135
|
}
|
|
1135
1136
|
|
|
1137
|
+
private void HandleTutorialDoesNotExist()
|
|
1138
|
+
{
|
|
1139
|
+
gameObject.SetActive(false);
|
|
1140
|
+
Destroy(gameObject);
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1136
1143
|
private void OnDestroy()
|
|
1137
1144
|
{
|
|
1138
1145
|
if (_eventManager == null) return;
|
|
1139
1146
|
|
|
1140
1147
|
_eventManager.OnTutorialResourcesReferenced -= ShowTutorialBasedOnType;
|
|
1141
1148
|
_eventManager.OnTutorialLoadingComplete -= HandleTutorialLoadingComplete;
|
|
1149
|
+
_eventManager.OnTutorialDoesNotExist -= HandleTutorialDoesNotExist;
|
|
1142
1150
|
}
|
|
1143
1151
|
|
|
1144
1152
|
private void DisplayImage(int index)
|
|
@@ -254,7 +254,7 @@ MonoBehaviour:
|
|
|
254
254
|
scoreSubmissionText: {fileID: 4314462782470164325}
|
|
255
255
|
buttonHolder: {fileID: 0}
|
|
256
256
|
loadingBar: {fileID: 7071240272076755227}
|
|
257
|
-
|
|
257
|
+
exitLoadingCircle: {fileID: 0}
|
|
258
258
|
--- !u!114 &7863664679590643807
|
|
259
259
|
MonoBehaviour:
|
|
260
260
|
m_ObjectHideFlags: 0
|
|
@@ -193,7 +193,8 @@ MonoBehaviour:
|
|
|
193
193
|
scoreSubmissionText: {fileID: 0}
|
|
194
194
|
buttonHolder: {fileID: 1454075834828744570}
|
|
195
195
|
loadingBar: {fileID: 0}
|
|
196
|
-
|
|
196
|
+
exitLoadingCircle: {fileID: 4090140612718772822}
|
|
197
|
+
playAgainLoadingCircle: {fileID: 700000000000000001}
|
|
197
198
|
--- !u!114 &2358495542796786633
|
|
198
199
|
MonoBehaviour:
|
|
199
200
|
m_ObjectHideFlags: 0
|
|
@@ -1261,7 +1262,10 @@ PrefabInstance:
|
|
|
1261
1262
|
objectReference: {fileID: 0}
|
|
1262
1263
|
m_RemovedComponents: []
|
|
1263
1264
|
m_RemovedGameObjects: []
|
|
1264
|
-
m_AddedGameObjects:
|
|
1265
|
+
m_AddedGameObjects:
|
|
1266
|
+
- targetCorrespondingSourceObject: {fileID: 446956918503945639, guid: 7196382af023e984dbe20e6bcdc9933c, type: 3}
|
|
1267
|
+
insertIndex: -1
|
|
1268
|
+
addedObject: {fileID: 700000000000000002}
|
|
1265
1269
|
m_AddedComponents: []
|
|
1266
1270
|
m_SourcePrefab: {fileID: 100100000, guid: 7196382af023e984dbe20e6bcdc9933c, type: 3}
|
|
1267
1271
|
--- !u!224 &4567816188166193046 stripped
|
|
@@ -1455,3 +1459,114 @@ RectTransform:
|
|
|
1455
1459
|
m_CorrespondingSourceObject: {fileID: 446956918503945639, guid: 51f1fa5ca88e94a4f8c654ed76e16c02, type: 3}
|
|
1456
1460
|
m_PrefabInstance: {fileID: 6772588356203191674}
|
|
1457
1461
|
m_PrefabAsset: {fileID: 0}
|
|
1462
|
+
--- !u!1 &700000000000000001
|
|
1463
|
+
GameObject:
|
|
1464
|
+
m_ObjectHideFlags: 0
|
|
1465
|
+
m_CorrespondingSourceObject: {fileID: 0}
|
|
1466
|
+
m_PrefabInstance: {fileID: 0}
|
|
1467
|
+
m_PrefabAsset: {fileID: 0}
|
|
1468
|
+
serializedVersion: 6
|
|
1469
|
+
m_Component:
|
|
1470
|
+
- component: {fileID: 700000000000000002}
|
|
1471
|
+
- component: {fileID: 700000000000000003}
|
|
1472
|
+
- component: {fileID: 700000000000000004}
|
|
1473
|
+
- component: {fileID: 700000000000000005}
|
|
1474
|
+
- component: {fileID: 700000000000000006}
|
|
1475
|
+
m_Layer: 5
|
|
1476
|
+
m_Name: Play Again Loader
|
|
1477
|
+
m_TagString: Untagged
|
|
1478
|
+
m_Icon: {fileID: 0}
|
|
1479
|
+
m_NavMeshLayer: 0
|
|
1480
|
+
m_StaticEditorFlags: 0
|
|
1481
|
+
m_IsActive: 0
|
|
1482
|
+
--- !u!224 &700000000000000002
|
|
1483
|
+
RectTransform:
|
|
1484
|
+
m_ObjectHideFlags: 0
|
|
1485
|
+
m_CorrespondingSourceObject: {fileID: 0}
|
|
1486
|
+
m_PrefabInstance: {fileID: 0}
|
|
1487
|
+
m_PrefabAsset: {fileID: 0}
|
|
1488
|
+
m_GameObject: {fileID: 700000000000000001}
|
|
1489
|
+
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
|
1490
|
+
m_LocalPosition: {x: 0, y: 0, z: 0}
|
|
1491
|
+
m_LocalScale: {x: 0.75, y: 0.75, z: 0.75}
|
|
1492
|
+
m_ConstrainProportionsScale: 1
|
|
1493
|
+
m_Children: []
|
|
1494
|
+
m_Father: {fileID: 4567816188166193046}
|
|
1495
|
+
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
|
1496
|
+
m_AnchorMin: {x: 0.5, y: 0.5}
|
|
1497
|
+
m_AnchorMax: {x: 0.5, y: 0.5}
|
|
1498
|
+
m_AnchoredPosition: {x: 0, y: 14}
|
|
1499
|
+
m_SizeDelta: {x: 100, y: 100}
|
|
1500
|
+
m_Pivot: {x: 0.5, y: 0.5}
|
|
1501
|
+
--- !u!222 &700000000000000003
|
|
1502
|
+
CanvasRenderer:
|
|
1503
|
+
m_ObjectHideFlags: 0
|
|
1504
|
+
m_CorrespondingSourceObject: {fileID: 0}
|
|
1505
|
+
m_PrefabInstance: {fileID: 0}
|
|
1506
|
+
m_PrefabAsset: {fileID: 0}
|
|
1507
|
+
m_GameObject: {fileID: 700000000000000001}
|
|
1508
|
+
m_CullTransparentMesh: 1
|
|
1509
|
+
--- !u!114 &700000000000000004
|
|
1510
|
+
MonoBehaviour:
|
|
1511
|
+
m_ObjectHideFlags: 0
|
|
1512
|
+
m_CorrespondingSourceObject: {fileID: 0}
|
|
1513
|
+
m_PrefabInstance: {fileID: 0}
|
|
1514
|
+
m_PrefabAsset: {fileID: 0}
|
|
1515
|
+
m_GameObject: {fileID: 700000000000000001}
|
|
1516
|
+
m_Enabled: 1
|
|
1517
|
+
m_EditorHideFlags: 0
|
|
1518
|
+
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
|
1519
|
+
m_Name:
|
|
1520
|
+
m_EditorClassIdentifier:
|
|
1521
|
+
m_Material: {fileID: 0}
|
|
1522
|
+
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
|
1523
|
+
m_RaycastTarget: 1
|
|
1524
|
+
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
|
1525
|
+
m_Maskable: 1
|
|
1526
|
+
m_OnCullStateChanged:
|
|
1527
|
+
m_PersistentCalls:
|
|
1528
|
+
m_Calls: []
|
|
1529
|
+
m_Sprite: {fileID: 21300000, guid: 5c57961c662dfdd46a321974424c3f15, type: 3}
|
|
1530
|
+
m_Type: 0
|
|
1531
|
+
m_PreserveAspect: 1
|
|
1532
|
+
m_FillCenter: 1
|
|
1533
|
+
m_FillMethod: 4
|
|
1534
|
+
m_FillAmount: 1
|
|
1535
|
+
m_FillClockwise: 1
|
|
1536
|
+
m_FillOrigin: 0
|
|
1537
|
+
m_UseSpriteMesh: 0
|
|
1538
|
+
m_PixelsPerUnitMultiplier: 1
|
|
1539
|
+
--- !u!95 &700000000000000005
|
|
1540
|
+
Animator:
|
|
1541
|
+
serializedVersion: 7
|
|
1542
|
+
m_ObjectHideFlags: 0
|
|
1543
|
+
m_CorrespondingSourceObject: {fileID: 0}
|
|
1544
|
+
m_PrefabInstance: {fileID: 0}
|
|
1545
|
+
m_PrefabAsset: {fileID: 0}
|
|
1546
|
+
m_GameObject: {fileID: 700000000000000001}
|
|
1547
|
+
m_Enabled: 1
|
|
1548
|
+
m_Avatar: {fileID: 0}
|
|
1549
|
+
m_Controller: {fileID: 9100000, guid: 3b038a3cf997e10408e5ae13866f375e, type: 2}
|
|
1550
|
+
m_CullingMode: 0
|
|
1551
|
+
m_UpdateMode: 0
|
|
1552
|
+
m_ApplyRootMotion: 0
|
|
1553
|
+
m_LinearVelocityBlending: 0
|
|
1554
|
+
m_StabilizeFeet: 0
|
|
1555
|
+
m_AnimatePhysics: 0
|
|
1556
|
+
m_WarningMessage:
|
|
1557
|
+
m_HasTransformHierarchy: 1
|
|
1558
|
+
m_AllowConstantClipSamplingOptimization: 1
|
|
1559
|
+
m_KeepAnimatorStateOnDisable: 0
|
|
1560
|
+
m_WriteDefaultValuesOnDisable: 0
|
|
1561
|
+
--- !u!225 &700000000000000006
|
|
1562
|
+
CanvasGroup:
|
|
1563
|
+
m_ObjectHideFlags: 0
|
|
1564
|
+
m_CorrespondingSourceObject: {fileID: 0}
|
|
1565
|
+
m_PrefabInstance: {fileID: 0}
|
|
1566
|
+
m_PrefabAsset: {fileID: 0}
|
|
1567
|
+
m_GameObject: {fileID: 700000000000000001}
|
|
1568
|
+
m_Enabled: 1
|
|
1569
|
+
m_Alpha: 1
|
|
1570
|
+
m_Interactable: 1
|
|
1571
|
+
m_BlocksRaycasts: 1
|
|
1572
|
+
m_IgnoreParentGroups: 1
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "app.hypergames.hypersdk",
|
|
3
|
-
"version": "1.11.
|
|
3
|
+
"version": "1.11.4",
|
|
4
4
|
"displayName": "HyperSDK",
|
|
5
5
|
"description": "Official Unity SDK for Hyper: multiplayer battles, leaderboards, deterministic RNG, session management, tutorials, and WebGL optimizations for production-ready games.",
|
|
6
6
|
"unity": "6000.0",
|