app.hypergames.hypersdk 1.4.22 → 1.5.0
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 +7 -0
- package/Editor/Scripts/Inspectors/HyperSDKSettingsEditor.cs +48 -12
- package/Editor/Scripts/Tools/HyperBuildAssistant.cs +33 -9
- package/HyperLoader.unity +4 -4
- package/Runtime/Internal/Bootstrap/HyperLoader.cs +29 -24
- package/Runtime/Internal/Managers/BackendManager.cs +207 -40
- package/Runtime/Internal/Managers/DataManager.cs +128 -35
- package/Runtime/Internal/ScriptableObjects/HyperSDKSettings.cs +3 -0
- package/Runtime/Internal/UI/Components/ControlBar.cs +9 -1
- package/Runtime/Internal/UI/Components/LivesDisplay.cs +6 -7
- package/Runtime/Internal/UI/Components/TimerText.cs +1 -1
- package/Runtime/Internal/UI/Modals/GameOverModal.cs +6 -1
- package/Runtime/Internal/UI/Modals/StartingInstructionModal.cs +50 -20
- package/Runtime/Resources/HyperSDKSettings.asset +1 -0
- package/Runtime/Resources/UIPrefabs/StartingInstructionModal.prefab +4 -4
- package/Runtime/Shared/DTOs/Enums.cs +26 -0
- package/Runtime/Shared/Hyper.Shared.asmdef +3 -1
- package/Runtime/Shared/Utils/HyperDebug.cs +17 -7
- package/Runtime/Shared/Utils/HyperNumberFormatter.cs +67 -0
- package/Runtime/Shared/Utils/HyperNumberFormatter.cs.meta +2 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
# [1.5.0](https://github.com/mvmhyper/hyper-sdk/compare/v1.4.22...v1.5.0) (2026-02-04)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* refine swipe Start CTA to support explicit directions ([4edf02e](https://github.com/mvmhyper/hyper-sdk/commit/4edf02e5202d8fcebc9ded9046ffd46b25c76faa))
|
|
7
|
+
|
|
1
8
|
## [1.4.22](https://github.com/mvmhyper/hyper-sdk/compare/v1.4.21...v1.4.22) (2026-01-26)
|
|
2
9
|
|
|
3
10
|
|
|
@@ -55,9 +55,52 @@ namespace Hyper.Editor
|
|
|
55
55
|
EditorGUILayout.Space(12);
|
|
56
56
|
EditorGUILayout.LabelField("Start CTA Overlay", EditorStyles.boldLabel);
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
settings.startCTA
|
|
58
|
+
bool isSwipe =
|
|
59
|
+
settings.startCTA == StartCTA.SwipeToPlayVertical ||
|
|
60
|
+
settings.startCTA == StartCTA.SwipeToPlayHorizontal;
|
|
61
|
+
|
|
62
|
+
string[] ctaOptions = { "Tap To Play", "Swipe To Play" };
|
|
63
|
+
int currentCtaIndex = isSwipe ? 1 : 0;
|
|
64
|
+
|
|
65
|
+
int newCtaIndex = EditorGUILayout.Popup(
|
|
66
|
+
new GUIContent("Start CTA Type", "Choose how players start the game. Hyper requires one of these types - do not add your own start buttons."),
|
|
67
|
+
currentCtaIndex,
|
|
68
|
+
ctaOptions);
|
|
69
|
+
|
|
70
|
+
if (newCtaIndex == 0)
|
|
71
|
+
{
|
|
72
|
+
settings.startCTA = StartCTA.TapToPlay;
|
|
73
|
+
}
|
|
74
|
+
else
|
|
75
|
+
{
|
|
76
|
+
// Ensure StartCTA axis matches the selected swipe direction
|
|
77
|
+
bool isHorizontalDirection =
|
|
78
|
+
settings.swipeDirection == SwipeDirection.Left ||
|
|
79
|
+
settings.swipeDirection == SwipeDirection.Right;
|
|
80
|
+
|
|
81
|
+
settings.startCTA = isHorizontalDirection
|
|
82
|
+
? StartCTA.SwipeToPlayHorizontal
|
|
83
|
+
: StartCTA.SwipeToPlayVertical;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// When Swipe To Play is selected, show swipe direction field
|
|
87
|
+
if (newCtaIndex == 1)
|
|
88
|
+
{
|
|
89
|
+
EditorGUI.indentLevel++;
|
|
90
|
+
settings.swipeDirection = (SwipeDirection)EditorGUILayout.EnumPopup(
|
|
91
|
+
new GUIContent("Swipe Direction", "Choose the direction of the swipe used for the Start CTA visual."),
|
|
92
|
+
settings.swipeDirection);
|
|
93
|
+
|
|
94
|
+
// Keep StartCTA axis in sync in case direction changed
|
|
95
|
+
bool isHorizontalDirection =
|
|
96
|
+
settings.swipeDirection == SwipeDirection.Left ||
|
|
97
|
+
settings.swipeDirection == SwipeDirection.Right;
|
|
98
|
+
|
|
99
|
+
settings.startCTA = isHorizontalDirection
|
|
100
|
+
? StartCTA.SwipeToPlayHorizontal
|
|
101
|
+
: StartCTA.SwipeToPlayVertical;
|
|
102
|
+
EditorGUI.indentLevel--;
|
|
103
|
+
}
|
|
61
104
|
|
|
62
105
|
// Draw Control Bar Settings
|
|
63
106
|
EditorGUILayout.Space(12);
|
|
@@ -108,7 +151,9 @@ namespace Hyper.Editor
|
|
|
108
151
|
|
|
109
152
|
// Draw preview image right after Control Bar Settings
|
|
110
153
|
EditorGUILayout.Space(-1f);
|
|
154
|
+
EditorGUI.indentLevel++;
|
|
111
155
|
DrawPreviewImage();
|
|
156
|
+
EditorGUI.indentLevel--;
|
|
112
157
|
|
|
113
158
|
// Draw Restart Flow Settings
|
|
114
159
|
EditorGUILayout.Space(12);
|
|
@@ -120,15 +165,6 @@ namespace Hyper.Editor
|
|
|
120
165
|
"Enable custom restart flow if your game has its own restart logic. " +
|
|
121
166
|
"When enabled, SDK will fire OnCustomRestart event instead of using default restart.",
|
|
122
167
|
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
168
|
}
|
|
133
169
|
EditorGUILayout.EndVertical();
|
|
134
170
|
settings.useCustomRestartFlow = EditorGUILayout.Toggle(
|
|
@@ -2205,21 +2205,45 @@ namespace Hyper.Editor
|
|
|
2205
2205
|
{
|
|
2206
2206
|
string defines = PlayerSettings.GetScriptingDefineSymbols(NamedBuildTarget.WebGL);
|
|
2207
2207
|
const string RELEASE_DEFINE = "HYPER_RELEASE_BUILD";
|
|
2208
|
+
const string DEVELOPMENT_DEFINE = "HYPER_DEVELOPMENT_BUILD";
|
|
2208
2209
|
|
|
2209
|
-
bool
|
|
2210
|
+
bool hasReleaseDefine = defines.Contains(RELEASE_DEFINE);
|
|
2211
|
+
bool hasDevelopmentDefine = defines.Contains(DEVELOPMENT_DEFINE);
|
|
2210
2212
|
|
|
2211
|
-
if (isRelease
|
|
2213
|
+
if (isRelease)
|
|
2212
2214
|
{
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2215
|
+
// Add HYPER_RELEASE_BUILD if not present
|
|
2216
|
+
if (!hasReleaseDefine)
|
|
2217
|
+
{
|
|
2218
|
+
defines = string.IsNullOrEmpty(defines) ? RELEASE_DEFINE : $"{defines};{RELEASE_DEFINE}";
|
|
2219
|
+
if (IsSDKDeveloper()) HyperDebug.LogSuccess("Set HYPER_RELEASE_BUILD define symbol for production API URL");
|
|
2220
|
+
}
|
|
2221
|
+
|
|
2222
|
+
// Remove HYPER_DEVELOPMENT_BUILD if present
|
|
2223
|
+
if (hasDevelopmentDefine)
|
|
2224
|
+
{
|
|
2225
|
+
defines = defines.Replace(DEVELOPMENT_DEFINE, "").Replace(";;", ";").Trim(';');
|
|
2226
|
+
if (IsSDKDeveloper()) HyperDebug.LogSuccess("Removed HYPER_DEVELOPMENT_BUILD define symbol for release build");
|
|
2227
|
+
}
|
|
2216
2228
|
}
|
|
2217
|
-
else
|
|
2229
|
+
else
|
|
2218
2230
|
{
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2231
|
+
// Remove HYPER_RELEASE_BUILD if present
|
|
2232
|
+
if (hasReleaseDefine)
|
|
2233
|
+
{
|
|
2234
|
+
defines = defines.Replace(RELEASE_DEFINE, "").Replace(";;", ";").Trim(';');
|
|
2235
|
+
if (IsSDKDeveloper()) HyperDebug.LogSuccess("Removed HYPER_RELEASE_BUILD define symbol for dev API URL");
|
|
2236
|
+
}
|
|
2237
|
+
|
|
2238
|
+
// Add HYPER_DEVELOPMENT_BUILD if not present (since we're not using BuildOptions.Development to keep Brotli compression)
|
|
2239
|
+
if (!hasDevelopmentDefine && IsSDKDeveloper()) // This is a developer only feature
|
|
2240
|
+
{
|
|
2241
|
+
defines = string.IsNullOrEmpty(defines) ? DEVELOPMENT_DEFINE : $"{defines};{DEVELOPMENT_DEFINE}";
|
|
2242
|
+
if (IsSDKDeveloper()) HyperDebug.LogSuccess("Set HYPER_DEVELOPMENT_BUILD define symbol for development build");
|
|
2243
|
+
}
|
|
2222
2244
|
}
|
|
2245
|
+
|
|
2246
|
+
PlayerSettings.SetScriptingDefineSymbols(NamedBuildTarget.WebGL, defines);
|
|
2223
2247
|
}
|
|
2224
2248
|
catch (System.Exception ex)
|
|
2225
2249
|
{
|
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.
|
|
307
|
+
m_AnchoredPosition: {x: 489.27765, y: -280.1698}
|
|
308
308
|
m_SizeDelta: {x: 0, y: 239.347}
|
|
309
309
|
m_Pivot: {x: 0.5, y: 0.5}
|
|
310
310
|
--- !u!114 &751153944
|
|
@@ -661,7 +661,7 @@ RectTransform:
|
|
|
661
661
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
|
662
662
|
m_AnchorMin: {x: 0, y: 0}
|
|
663
663
|
m_AnchorMax: {x: 1, y: 0}
|
|
664
|
-
m_AnchoredPosition: {x: 0, y: 186.
|
|
664
|
+
m_AnchoredPosition: {x: 0, y: 186.1919}
|
|
665
665
|
m_SizeDelta: {x: 0, y: 372.3734}
|
|
666
666
|
m_Pivot: {x: 0.5, y: 0.5}
|
|
667
667
|
--- !u!114 &948186156
|
|
@@ -840,7 +840,7 @@ GameObject:
|
|
|
840
840
|
m_Component:
|
|
841
841
|
- component: {fileID: 1064166296}
|
|
842
842
|
m_Layer: 0
|
|
843
|
-
m_Name:
|
|
843
|
+
m_Name: __HyperSDK_BuildMarker_639052456961623634
|
|
844
844
|
m_TagString: Untagged
|
|
845
845
|
m_Icon: {fileID: 0}
|
|
846
846
|
m_NavMeshLayer: 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.
|
|
1095
|
+
m_AnchoredPosition: {x: 489.27765, 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
|
|
@@ -35,11 +35,14 @@ namespace Hyper.Internal
|
|
|
35
35
|
private AspectRatioFitter _aspectRatioFitter;
|
|
36
36
|
private string _targetSceneName;
|
|
37
37
|
private bool _wasConnectionLost;
|
|
38
|
+
private float _bootstrapProgress = 0f;
|
|
38
39
|
private string[] _hintsArray;
|
|
40
|
+
private WaitForSecondsRealtime _hintWaitInstruction;
|
|
39
41
|
private EventManager _eventManager;
|
|
40
42
|
private GameManager _gameManager;
|
|
41
43
|
private BackendManager _backendManager;
|
|
42
44
|
|
|
45
|
+
|
|
43
46
|
#endregion
|
|
44
47
|
|
|
45
48
|
#region Unity Lifecycle
|
|
@@ -47,7 +50,7 @@ namespace Hyper.Internal
|
|
|
47
50
|
private void Awake()
|
|
48
51
|
{
|
|
49
52
|
HyperRuntime.IsSoftRestarting = false;
|
|
50
|
-
|
|
53
|
+
|
|
51
54
|
HyperRuntime.Clear();
|
|
52
55
|
|
|
53
56
|
InitializeComponents();
|
|
@@ -97,6 +100,7 @@ namespace Hyper.Internal
|
|
|
97
100
|
}
|
|
98
101
|
|
|
99
102
|
_hintsArray = _gameContentConfig.hints ?? new string[0];
|
|
103
|
+
_hintWaitInstruction = new WaitForSecondsRealtime(_gameContentConfig.HintSwitchTimeInSeconds);
|
|
100
104
|
}
|
|
101
105
|
|
|
102
106
|
#endregion
|
|
@@ -158,7 +162,8 @@ namespace Hyper.Internal
|
|
|
158
162
|
{
|
|
159
163
|
string randomHint = _hintsArray[UnityEngine.Random.Range(0, _hintsArray.Length)];
|
|
160
164
|
hintText.text = randomHint;
|
|
161
|
-
|
|
165
|
+
// Use cached wait instruction to avoid per-loop allocations
|
|
166
|
+
yield return _hintWaitInstruction;
|
|
162
167
|
}
|
|
163
168
|
}
|
|
164
169
|
|
|
@@ -174,8 +179,8 @@ namespace Hyper.Internal
|
|
|
174
179
|
|
|
175
180
|
private IEnumerator BootstrapAndLoadGame()
|
|
176
181
|
{
|
|
177
|
-
|
|
178
|
-
_loadingBarSlider.value =
|
|
182
|
+
_bootstrapProgress = 0f;
|
|
183
|
+
_loadingBarSlider.value = _bootstrapProgress;
|
|
179
184
|
|
|
180
185
|
// Step 1: Initialize HyperSDK
|
|
181
186
|
bool sdkInitialized = false;
|
|
@@ -191,18 +196,18 @@ namespace Hyper.Internal
|
|
|
191
196
|
|
|
192
197
|
while (!sdkInitialized)
|
|
193
198
|
{
|
|
194
|
-
|
|
195
|
-
_loadingBarSlider.value =
|
|
199
|
+
_bootstrapProgress = Mathf.MoveTowards(_bootstrapProgress, 0.20f, Time.deltaTime * 2f);
|
|
200
|
+
_loadingBarSlider.value = _bootstrapProgress;
|
|
196
201
|
yield return null;
|
|
197
202
|
}
|
|
198
203
|
|
|
199
|
-
|
|
200
|
-
_loadingBarSlider.value =
|
|
204
|
+
_bootstrapProgress = 0.20f;
|
|
205
|
+
_loadingBarSlider.value = _bootstrapProgress;
|
|
201
206
|
|
|
202
207
|
// Step 2: Handle Backend/PVP or Practice mode initialization
|
|
203
208
|
if (_gameManager.Config.IsBackendGame && _gameManager.Config.isPVP)
|
|
204
209
|
{
|
|
205
|
-
yield return InitializeBackendGame(
|
|
210
|
+
yield return InitializeBackendGame();
|
|
206
211
|
}
|
|
207
212
|
else if (_gameManager.Config.GameMode == GameMode.Battle)
|
|
208
213
|
{
|
|
@@ -214,10 +219,10 @@ namespace Hyper.Internal
|
|
|
214
219
|
}
|
|
215
220
|
|
|
216
221
|
// Step 3: Load target scene asynchronously
|
|
217
|
-
yield return LoadTargetScene(
|
|
222
|
+
yield return LoadTargetScene();
|
|
218
223
|
}
|
|
219
224
|
|
|
220
|
-
private IEnumerator InitializeBackendGame(
|
|
225
|
+
private IEnumerator InitializeBackendGame()
|
|
221
226
|
{
|
|
222
227
|
_targetSceneName = _gameContentConfig.GameScene?.SceneName;
|
|
223
228
|
|
|
@@ -226,13 +231,13 @@ namespace Hyper.Internal
|
|
|
226
231
|
|
|
227
232
|
while (!HyperRuntime.BackendManager.isSocketConnected)
|
|
228
233
|
{
|
|
229
|
-
|
|
230
|
-
_loadingBarSlider.value =
|
|
234
|
+
_bootstrapProgress = Mathf.MoveTowards(_bootstrapProgress, 0.35f, Time.deltaTime * 0.5f);
|
|
235
|
+
_loadingBarSlider.value = _bootstrapProgress;
|
|
231
236
|
yield return null;
|
|
232
237
|
}
|
|
233
238
|
|
|
234
|
-
|
|
235
|
-
_loadingBarSlider.value =
|
|
239
|
+
_bootstrapProgress = 0.35f;
|
|
240
|
+
_loadingBarSlider.value = _bootstrapProgress;
|
|
236
241
|
|
|
237
242
|
// Create session
|
|
238
243
|
bool sessionCreated = false;
|
|
@@ -243,13 +248,13 @@ namespace Hyper.Internal
|
|
|
243
248
|
|
|
244
249
|
while (!sessionCreated)
|
|
245
250
|
{
|
|
246
|
-
|
|
247
|
-
_loadingBarSlider.value =
|
|
251
|
+
_bootstrapProgress = Mathf.MoveTowards(_bootstrapProgress, 0.50f, Time.deltaTime * 0.5f);
|
|
252
|
+
_loadingBarSlider.value = _bootstrapProgress;
|
|
248
253
|
yield return null;
|
|
249
254
|
}
|
|
250
255
|
|
|
251
|
-
|
|
252
|
-
_loadingBarSlider.value =
|
|
256
|
+
_bootstrapProgress = 0.50f;
|
|
257
|
+
_loadingBarSlider.value = _bootstrapProgress;
|
|
253
258
|
}
|
|
254
259
|
|
|
255
260
|
private void InitializeNonBackendBattle()
|
|
@@ -281,7 +286,7 @@ namespace Hyper.Internal
|
|
|
281
286
|
return DateTime.Now.Millisecond;
|
|
282
287
|
}
|
|
283
288
|
|
|
284
|
-
private IEnumerator LoadTargetScene(
|
|
289
|
+
private IEnumerator LoadTargetScene()
|
|
285
290
|
{
|
|
286
291
|
var asyncLoad = SceneManager.LoadSceneAsync(_targetSceneName);
|
|
287
292
|
asyncLoad.allowSceneActivation = false;
|
|
@@ -289,12 +294,12 @@ namespace Hyper.Internal
|
|
|
289
294
|
while (!asyncLoad.isDone)
|
|
290
295
|
{
|
|
291
296
|
float sceneProgress = Mathf.Clamp01(asyncLoad.progress / 0.9f);
|
|
292
|
-
float targetProgress = Mathf.Lerp(
|
|
293
|
-
|
|
297
|
+
float targetProgress = Mathf.Lerp(_bootstrapProgress, 1f, sceneProgress);
|
|
298
|
+
_bootstrapProgress = Mathf.MoveTowards(_bootstrapProgress, targetProgress, Time.unscaledDeltaTime * 2f);
|
|
294
299
|
|
|
295
|
-
_loadingBarSlider.value =
|
|
300
|
+
_loadingBarSlider.value = _bootstrapProgress;
|
|
296
301
|
|
|
297
|
-
if (asyncLoad.progress >= 0.9f &&
|
|
302
|
+
if (asyncLoad.progress >= 0.9f && _bootstrapProgress >= 0.95f)
|
|
298
303
|
{
|
|
299
304
|
_loadingBarSlider.value = 1f;
|
|
300
305
|
asyncLoad.allowSceneActivation = true;
|