app.hypergames.hypersdk 1.4.19 → 1.4.21

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 CHANGED
@@ -1,3 +1,17 @@
1
+ ## [1.4.21](https://github.com/mvmhyper/hyper-sdk/compare/v1.4.20...v1.4.21) (2026-01-12)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * Update restart flow to handle scene unloading and add custom restart option ([7f0d79a](https://github.com/mvmhyper/hyper-sdk/commit/7f0d79a5873d33a4a6d2ffb099b205861224d882))
7
+
8
+ ## [1.4.20](https://github.com/mvmhyper/hyper-sdk/compare/v1.4.19...v1.4.20) (2026-01-12)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * Add custom restart flow and improve default restart for async scenes ([72c6d78](https://github.com/mvmhyper/hyper-sdk/commit/72c6d781b485503b98acc028294015db3cf93474))
14
+
1
15
  ## [1.4.19](https://github.com/mvmhyper/hyper-sdk/compare/v1.4.18...v1.4.19) (2026-01-06)
2
16
 
3
17
 
@@ -110,6 +110,31 @@ namespace Hyper.Editor
110
110
  EditorGUILayout.Space(-1f);
111
111
  DrawPreviewImage();
112
112
 
113
+ // Draw Restart Flow Settings
114
+ EditorGUILayout.Space(12);
115
+ EditorGUILayout.LabelField("Restart Flow Settings", EditorStyles.boldLabel);
116
+
117
+ EditorGUILayout.BeginVertical(EditorStyles.helpBox);
118
+ {
119
+ EditorGUILayout.LabelField(
120
+ "Enable custom restart flow if your game has its own restart logic. " +
121
+ "When enabled, SDK will fire OnCustomRestart event instead of using default restart.",
122
+ EditorStyles.wordWrappedMiniLabel);
123
+
124
+ // if (settings.useCustomRestartFlow)
125
+ // {
126
+ // EditorGUILayout.Space(4);
127
+ // EditorGUILayout.HelpBox(
128
+ // "Custom restart enabled. Subscribe to HyperSDK.Event.OnCustomRestart in your game manager:\n" +
129
+ // "HyperSDK.Event.OnCustomRestart += YourRestartMethod;",
130
+ // MessageType.Info);
131
+ // }
132
+ }
133
+ EditorGUILayout.EndVertical();
134
+ settings.useCustomRestartFlow = EditorGUILayout.Toggle(
135
+ new GUIContent("Use Custom Restart Flow"),
136
+ settings.useCustomRestartFlow);
137
+
113
138
  EditorGUILayout.Space(12);
114
139
  // Draw Editor Testing
115
140
  SerializedProperty settingsProp = serializedObject.FindProperty("_settings");
package/HyperLoader.unity CHANGED
@@ -304,7 +304,7 @@ RectTransform:
304
304
  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
305
305
  m_AnchorMin: {x: 0, y: 1}
306
306
  m_AnchorMax: {x: 0, y: 1}
307
- m_AnchoredPosition: {x: 489.205, y: -280.1698}
307
+ m_AnchoredPosition: {x: 489.20746, y: -280.1698}
308
308
  m_SizeDelta: {x: 1044.9, y: 239.347}
309
309
  m_Pivot: {x: 0.5, y: 0.5}
310
310
  --- !u!114 &751153944
@@ -426,7 +426,7 @@ Canvas:
426
426
  m_OverridePixelPerfect: 0
427
427
  m_SortingBucketNormalizedSize: 0
428
428
  m_VertexColorAlwaysGammaSpace: 0
429
- m_AdditionalShaderChannelsFlag: 7
429
+ m_AdditionalShaderChannelsFlag: 31
430
430
  m_UpdateRectTransformForStandalone: 0
431
431
  m_SortingLayerID: 0
432
432
  m_SortingOrder: 0
@@ -1092,7 +1092,7 @@ RectTransform:
1092
1092
  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
1093
1093
  m_AnchorMin: {x: 0, y: 1}
1094
1094
  m_AnchorMax: {x: 0, y: 1}
1095
- m_AnchoredPosition: {x: 489.205, y: -133.2274}
1095
+ m_AnchoredPosition: {x: 489.20746, y: -133.2274}
1096
1096
  m_SizeDelta: {x: 875, y: 54.5378}
1097
1097
  m_Pivot: {x: 0.5, y: 0.5}
1098
1098
  --- !u!1 &2874543288936963705
@@ -1,4 +1,6 @@
1
1
  using System;
2
+ using System.Collections;
3
+ using System.Collections.Generic;
2
4
  using UnityEngine;
3
5
  using UnityEngine.SceneManagement;
4
6
  using Hyper.Internal.Managers;
@@ -44,15 +46,97 @@ namespace Hyper.Internal
44
46
  ///
45
47
  /// This is the internal implementation used by both the public
46
48
  /// HyperSDK facade and internal UI flows (pause/game over modals).
49
+ ///
50
+ /// If useCustomRestartFlow is enabled in settings, fires OnCustomRestart event
51
+ /// instead of performing default restart. Otherwise, performs improved default
52
+ /// restart that properly unloads all scenes (including additive) before reloading.
47
53
  /// </summary>
48
54
  internal static void RestartSession()
49
55
  {
50
56
  _isSoftRestarting = true;
51
57
 
58
+ if (_settings != null && _settings.useCustomRestartFlow)
59
+ {
60
+ // Fire custom restart event - developers handle restart themselves
61
+ _eventManager?.InvokeCustomRestartEvent();
62
+
63
+ // Reset SDK UI state for custom restart
64
+ // This prepares the SDK UI (hides game over, shows start modal, resets timer, etc.)
65
+ // so the game appears fresh when the developer's restart logic runs
66
+ _gameManager?.ResetUIStateForCustomRestart();
67
+
68
+ return;
69
+ }
70
+
71
+ // Use improved default restart flow
72
+ if (_host != null)
73
+ {
74
+ _host.StartCoroutine(RestartSessionCoroutine());
75
+ }
76
+ else
77
+ {
78
+ // Fallback to immediate restart if host doesn't exist
79
+ ClearAllDontDestroyOnLoadObjects();
80
+ SceneManager.LoadScene("HyperLoader");
81
+ }
82
+ }
83
+
84
+ /// <summary>
85
+ /// Coroutine-based restart that properly unloads all scenes before reloading.
86
+ /// Handles async scene operations and ensures clean state before restart.
87
+ /// </summary>
88
+ private static IEnumerator RestartSessionCoroutine()
89
+ {
90
+ yield return UnloadAllScenesCoroutine();
91
+
52
92
  ClearAllDontDestroyOnLoadObjects();
53
93
  SceneManager.LoadScene("HyperLoader");
54
94
  }
55
95
 
96
+ /// <summary>
97
+ /// Unloads all additive scenes. The active (single) scene will be replaced when HyperLoader loads.
98
+ /// Waits for all async unload operations to complete before proceeding.
99
+ /// </summary>
100
+ private static IEnumerator UnloadAllScenesCoroutine()
101
+ {
102
+ List<AsyncOperation> unloadOps = new List<AsyncOperation>();
103
+ Scene activeScene = SceneManager.GetActiveScene();
104
+
105
+ // Only unload additive scenes (not the active single scene)
106
+ for (int i = SceneManager.sceneCount - 1; i >= 0; i--)
107
+ {
108
+ Scene scene = SceneManager.GetSceneAt(i);
109
+
110
+ if (scene.name == "HyperLoader")
111
+ continue;
112
+
113
+ if (scene == activeScene)
114
+ continue;
115
+
116
+ // Only unload additive scenes that are loaded
117
+ if (scene.isLoaded)
118
+ {
119
+ AsyncOperation unloadOp = SceneManager.UnloadSceneAsync(scene);
120
+ if (unloadOp != null)
121
+ {
122
+ unloadOps.Add(unloadOp);
123
+ }
124
+ }
125
+ }
126
+
127
+ // Wait for all unload operations to complete
128
+ foreach (AsyncOperation op in unloadOps)
129
+ {
130
+ while (op != null && !op.isDone)
131
+ {
132
+ yield return null;
133
+ }
134
+ }
135
+
136
+ Resources.UnloadUnusedAssets();
137
+ yield return null;
138
+ }
139
+
56
140
  internal static void Initialize(Action callback)
57
141
  {
58
142
  ValidatePlatform();
@@ -29,6 +29,7 @@ namespace Hyper.Internal.Managers
29
29
  public event Action OnGameEnded;
30
30
  public event Action OnLivesExhausted;
31
31
  public event Action OnHealthExhausted;
32
+ public event Action OnCustomRestart;
32
33
 
33
34
  #endregion
34
35
 
@@ -62,6 +63,7 @@ namespace Hyper.Internal.Managers
62
63
  internal void InvokeGameEndedEvent() => OnGameEnded?.Invoke();
63
64
  internal void InvokeLivesExhaustedEvent() => OnLivesExhausted?.Invoke();
64
65
  internal void InvokeHealthExhaustedEvent() => OnHealthExhausted?.Invoke();
66
+ internal void InvokeCustomRestartEvent() => OnCustomRestart?.Invoke();
65
67
  internal void InvokeConnectionLostEvent() => OnInternetConnectionLost?.Invoke();
66
68
  internal void InvokeConnectionFoundEvent() => OnInternetConnectionFound?.Invoke();
67
69
  internal void InvokeTutorialLoadingCompleteEvent() => OnTutorialLoadingComplete?.Invoke();
@@ -1,4 +1,4 @@
1
- using System;
1
+ using System;
2
2
  using System.Collections;
3
3
  using System.Collections.Generic;
4
4
  using System.Runtime.InteropServices;
@@ -871,6 +871,34 @@ namespace Hyper.Internal.Managers
871
871
 
872
872
  #endregion
873
873
 
874
+ #region Custom Restart Cleanup
875
+
876
+ /// <summary>
877
+ /// Resets SDK UI state for custom restart flow.
878
+ /// Called after OnCustomRestart event is fired to prepare the SDK for the developer's restart logic.
879
+ /// </summary>
880
+ internal void ResetUIStateForCustomRestart()
881
+ {
882
+ HideGameOverModal();
883
+ HidePauseModals();
884
+
885
+ // Reset game state flags
886
+ _hasGameStarted = false;
887
+ _hasGameEnded = false;
888
+ _isPaused = false;
889
+ _isFrozenBeforePause = false;
890
+
891
+ HyperRuntime.Timer.Reset();
892
+ HyperRuntime.DataManager.UpdateScore(0);
893
+
894
+ ShowControlBarElements();
895
+ ShowStartingInstructionModal();
896
+
897
+ Time.timeScale = 1;
898
+ }
899
+
900
+ #endregion
901
+
874
902
  #region Game End Logic
875
903
 
876
904
  private void EndGameInternal()
@@ -54,6 +54,16 @@ namespace Hyper.Internal
54
54
 
55
55
  #endregion
56
56
 
57
+ #region Restart Flow Settings
58
+
59
+ [Space(20)]
60
+ [Header("Restart Flow Settings")]
61
+ [Tooltip("Enable custom restart flow. If enabled, SDK will fire OnCustomRestart event " +
62
+ "instead of using default restart. Listen to HyperSDK.Event.OnCustomRestart in your game manager.")]
63
+ public bool useCustomRestartFlow = false;
64
+
65
+ #endregion
66
+
57
67
  #region Editor Testing
58
68
  [Header("Editor Simulation")]
59
69
  [Tooltip("Configuration settings for testing within the Unity Editor.")]
@@ -178,6 +178,7 @@ namespace Hyper
178
178
  event Action<bool> OnSoundChanged;
179
179
  event Action OnLivesExhausted;
180
180
  event Action OnHealthExhausted;
181
+ event Action OnCustomRestart;
181
182
  }
182
183
 
183
184
  #region Adapter Implementations
@@ -248,6 +249,7 @@ namespace Hyper
248
249
  private Action<bool> _onSoundChanged;
249
250
  private Action _onLivesExhausted;
250
251
  private Action _onHealthExhausted;
252
+ private Action _onCustomRestart;
251
253
 
252
254
  private Action _gameStartBridge;
253
255
  private Action _timeUpBridge;
@@ -257,6 +259,7 @@ namespace Hyper
257
259
  private Action<bool> _soundChangedBridge;
258
260
  private Action _livesExhaustedBridge;
259
261
  private Action _healthExhaustedBridge;
262
+ private Action _customRestartBridge;
260
263
 
261
264
  public event Action OnGameStart
262
265
  {
@@ -338,6 +341,16 @@ namespace Hyper
338
341
  remove => _onHealthExhausted -= value;
339
342
  }
340
343
 
344
+ public event Action OnCustomRestart
345
+ {
346
+ add
347
+ {
348
+ _onCustomRestart += value;
349
+ RefreshBindings();
350
+ }
351
+ remove => _onCustomRestart -= value;
352
+ }
353
+
341
354
  internal void RefreshBindings()
342
355
  {
343
356
  var manager = HyperRuntime.EventManager;
@@ -366,6 +379,7 @@ namespace Hyper
366
379
  _soundChangedBridge = enabled => _onSoundChanged?.Invoke(enabled);
367
380
  _livesExhaustedBridge = () => _onLivesExhausted?.Invoke();
368
381
  _healthExhaustedBridge = () => _onHealthExhausted?.Invoke();
382
+ _customRestartBridge = () => _onCustomRestart?.Invoke();
369
383
 
370
384
  manager.OnGameStart += _gameStartBridge;
371
385
  manager.OnTimeUp += _timeUpBridge;
@@ -375,6 +389,7 @@ namespace Hyper
375
389
  manager.OnSoundChanged += _soundChangedBridge;
376
390
  manager.OnLivesExhausted += _livesExhaustedBridge;
377
391
  manager.OnHealthExhausted += _healthExhaustedBridge;
392
+ manager.OnCustomRestart += _customRestartBridge;
378
393
 
379
394
  _attachedManager = manager;
380
395
  }
@@ -394,6 +409,7 @@ namespace Hyper
394
409
  if (_soundChangedBridge != null) _attachedManager.OnSoundChanged -= _soundChangedBridge;
395
410
  if (_livesExhaustedBridge != null) _attachedManager.OnLivesExhausted -= _livesExhaustedBridge;
396
411
  if (_healthExhaustedBridge != null) _attachedManager.OnHealthExhausted -= _healthExhaustedBridge;
412
+ if (_customRestartBridge != null) _attachedManager.OnCustomRestart -= _customRestartBridge;
397
413
 
398
414
  _gameStartBridge = null;
399
415
  _timeUpBridge = null;
@@ -403,6 +419,7 @@ namespace Hyper
403
419
  _soundChangedBridge = null;
404
420
  _livesExhaustedBridge = null;
405
421
  _healthExhaustedBridge = null;
422
+ _customRestartBridge = null;
406
423
  _attachedManager = null;
407
424
  }
408
425
  }
@@ -19,6 +19,7 @@ MonoBehaviour:
19
19
  startCTA: 0
20
20
  controlBarLayout: 0
21
21
  controlBarTheme: 1
22
+ useCustomRestartFlow: 0
22
23
  _settings:
23
24
  GameMode: 0
24
25
  ShowInstructions: 0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "app.hypergames.hypersdk",
3
- "version": "1.4.19",
3
+ "version": "1.4.21",
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",