app.hypergames.hypersdk 1.5.2 → 1.5.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 +16 -0
- package/Editor/Scripts/Inspectors/HyperSDKSettingsEditor.cs +2 -1
- package/Editor/Scripts/Windows/HyperSettingsWindow.cs +85 -0
- package/HyperLoader.unity +3 -3
- package/Runtime/Internal/Managers/GameManager.cs +34 -8
- package/Runtime/Internal/UI/Components/SafeArea.cs +17 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
## [1.5.4](https://github.com/mvmhyper/hyper-sdk/compare/v1.5.3...v1.5.4) (2026-02-24)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* correct landscape safe area handling and control bar alignment in SDK UI ([83c4c1e](https://github.com/mvmhyper/hyper-sdk/commit/83c4c1e82fc14d296d5eb6cd916beafe8726bea3))
|
|
7
|
+
* Ensure Settings window and asset file stay in sync ([a9c7a43](https://github.com/mvmhyper/hyper-sdk/commit/a9c7a43927404573148467702791a9c3eb38dae0))
|
|
8
|
+
|
|
9
|
+
## [1.5.3](https://github.com/mvmhyper/hyper-sdk/compare/v1.5.2...v1.5.3) (2026-02-10)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
* bump SDK version and update release branch to sdk/releaseTests ([dc1d32b](https://github.com/mvmhyper/hyper-sdk/commit/dc1d32bb067b0623b47a60eeb59fe8fca5828bea))
|
|
15
|
+
* ensure parent canvas takes precedence over nested canvases in SafeArea ([0d5931a](https://github.com/mvmhyper/hyper-sdk/commit/0d5931aa9bb21ecb6e1154339fe44e5af225145d))
|
|
16
|
+
|
|
1
17
|
## [1.5.2](https://github.com/mvmhyper/hyper-sdk/compare/v1.5.1...v1.5.2) (2026-02-09)
|
|
2
18
|
|
|
3
19
|
|
|
@@ -183,10 +183,11 @@ namespace Hyper.Editor
|
|
|
183
183
|
|
|
184
184
|
serializedObject.ApplyModifiedProperties();
|
|
185
185
|
|
|
186
|
-
// Mark object as dirty if any changes were made
|
|
186
|
+
// Mark object as dirty and save immediately if any changes were made
|
|
187
187
|
if (GUI.changed)
|
|
188
188
|
{
|
|
189
189
|
EditorUtility.SetDirty(settings);
|
|
190
|
+
AssetDatabase.SaveAssets();
|
|
190
191
|
}
|
|
191
192
|
}
|
|
192
193
|
|
|
@@ -25,10 +25,12 @@ namespace Hyper.Editor
|
|
|
25
25
|
// Core Settings
|
|
26
26
|
private HyperSDKSettings _settings;
|
|
27
27
|
private UnityEditor.Editor _settingsEditor;
|
|
28
|
+
private double _lastSettingsModificationTime;
|
|
28
29
|
|
|
29
30
|
// Game Content
|
|
30
31
|
private HyperGameContentConfig _contentConfig;
|
|
31
32
|
private UnityEditor.Editor _contentEditor;
|
|
33
|
+
private double _lastContentModificationTime;
|
|
32
34
|
|
|
33
35
|
#endregion
|
|
34
36
|
|
|
@@ -68,10 +70,17 @@ namespace Hyper.Editor
|
|
|
68
70
|
private void OnEnable()
|
|
69
71
|
{
|
|
70
72
|
LoadAllSettings();
|
|
73
|
+
UpdateModificationTimes();
|
|
74
|
+
|
|
75
|
+
// Subscribe to asset modification events
|
|
76
|
+
EditorApplication.projectChanged += OnProjectChanged;
|
|
71
77
|
}
|
|
72
78
|
|
|
73
79
|
private void OnDisable()
|
|
74
80
|
{
|
|
81
|
+
// Unsubscribe from events
|
|
82
|
+
EditorApplication.projectChanged -= OnProjectChanged;
|
|
83
|
+
|
|
75
84
|
// Clean up editors
|
|
76
85
|
if (_settingsEditor != null)
|
|
77
86
|
{
|
|
@@ -96,6 +105,11 @@ namespace Hyper.Editor
|
|
|
96
105
|
_settings = Resources.Load<HyperSDKSettings>(HyperConstants.SETTINGS_RESOURCE_PATH);
|
|
97
106
|
if (_settings != null)
|
|
98
107
|
{
|
|
108
|
+
// Destroy old editor if it exists
|
|
109
|
+
if (_settingsEditor != null)
|
|
110
|
+
{
|
|
111
|
+
DestroyImmediate(_settingsEditor);
|
|
112
|
+
}
|
|
99
113
|
_settingsEditor = UnityEditor.Editor.CreateEditor(_settings);
|
|
100
114
|
}
|
|
101
115
|
|
|
@@ -103,10 +117,63 @@ namespace Hyper.Editor
|
|
|
103
117
|
_contentConfig = Resources.Load<HyperGameContentConfig>(HyperConstants.GAME_CONTENT_RESOURCE_PATH);
|
|
104
118
|
if (_contentConfig != null)
|
|
105
119
|
{
|
|
120
|
+
// Destroy old editor if it exists
|
|
121
|
+
if (_contentEditor != null)
|
|
122
|
+
{
|
|
123
|
+
DestroyImmediate(_contentEditor);
|
|
124
|
+
}
|
|
106
125
|
_contentEditor = UnityEditor.Editor.CreateEditor(_contentConfig);
|
|
107
126
|
}
|
|
108
127
|
}
|
|
109
128
|
|
|
129
|
+
private void UpdateModificationTimes()
|
|
130
|
+
{
|
|
131
|
+
// Update modification times for both assets
|
|
132
|
+
if (System.IO.File.Exists(HyperConstants.SETTINGS_ASSET_PATH))
|
|
133
|
+
{
|
|
134
|
+
_lastSettingsModificationTime = System.IO.File.GetLastWriteTime(HyperConstants.SETTINGS_ASSET_PATH).ToFileTime();
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (System.IO.File.Exists(HyperConstants.GAME_CONTENT_ASSET_PATH))
|
|
138
|
+
{
|
|
139
|
+
_lastContentModificationTime = System.IO.File.GetLastWriteTime(HyperConstants.GAME_CONTENT_ASSET_PATH).ToFileTime();
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
private void OnProjectChanged()
|
|
144
|
+
{
|
|
145
|
+
// Check if our assets were modified externally
|
|
146
|
+
bool settingsChanged = false;
|
|
147
|
+
bool contentChanged = false;
|
|
148
|
+
|
|
149
|
+
if (System.IO.File.Exists(HyperConstants.SETTINGS_ASSET_PATH))
|
|
150
|
+
{
|
|
151
|
+
var currentTime = System.IO.File.GetLastWriteTime(HyperConstants.SETTINGS_ASSET_PATH).ToFileTime();
|
|
152
|
+
if (currentTime != _lastSettingsModificationTime)
|
|
153
|
+
{
|
|
154
|
+
settingsChanged = true;
|
|
155
|
+
_lastSettingsModificationTime = currentTime;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (System.IO.File.Exists(HyperConstants.GAME_CONTENT_ASSET_PATH))
|
|
160
|
+
{
|
|
161
|
+
var currentTime = System.IO.File.GetLastWriteTime(HyperConstants.GAME_CONTENT_ASSET_PATH).ToFileTime();
|
|
162
|
+
if (currentTime != _lastContentModificationTime)
|
|
163
|
+
{
|
|
164
|
+
contentChanged = true;
|
|
165
|
+
_lastContentModificationTime = currentTime;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Reload if changes detected
|
|
170
|
+
if (settingsChanged || contentChanged)
|
|
171
|
+
{
|
|
172
|
+
LoadAllSettings();
|
|
173
|
+
UpdateModificationTimes();
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
110
177
|
private void CreateSettingsAsset()
|
|
111
178
|
{
|
|
112
179
|
EnsureResourcesFolderExists();
|
|
@@ -214,7 +281,16 @@ namespace Hyper.Editor
|
|
|
214
281
|
|
|
215
282
|
if (_settingsEditor != null)
|
|
216
283
|
{
|
|
284
|
+
EditorGUI.BeginChangeCheck();
|
|
217
285
|
_settingsEditor.OnInspectorGUI();
|
|
286
|
+
|
|
287
|
+
// Save immediately if changes were made
|
|
288
|
+
if (EditorGUI.EndChangeCheck())
|
|
289
|
+
{
|
|
290
|
+
EditorUtility.SetDirty(_settings);
|
|
291
|
+
AssetDatabase.SaveAssets();
|
|
292
|
+
UpdateModificationTimes();
|
|
293
|
+
}
|
|
218
294
|
}
|
|
219
295
|
|
|
220
296
|
EditorGUILayout.EndScrollView();
|
|
@@ -242,7 +318,16 @@ namespace Hyper.Editor
|
|
|
242
318
|
|
|
243
319
|
if (_contentEditor != null)
|
|
244
320
|
{
|
|
321
|
+
EditorGUI.BeginChangeCheck();
|
|
245
322
|
_contentEditor.OnInspectorGUI();
|
|
323
|
+
|
|
324
|
+
// Save immediately if changes were made
|
|
325
|
+
if (EditorGUI.EndChangeCheck())
|
|
326
|
+
{
|
|
327
|
+
EditorUtility.SetDirty(_contentConfig);
|
|
328
|
+
AssetDatabase.SaveAssets();
|
|
329
|
+
UpdateModificationTimes();
|
|
330
|
+
}
|
|
246
331
|
}
|
|
247
332
|
|
|
248
333
|
EditorGUILayout.EndScrollView();
|
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:
|
|
307
|
+
m_AnchoredPosition: {x: 1059.0492, 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
|
|
@@ -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_639075716235347695
|
|
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:
|
|
1095
|
+
m_AnchoredPosition: {x: 1059.0492, 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
|
|
@@ -721,12 +721,12 @@ namespace Hyper.Internal.Managers
|
|
|
721
721
|
|
|
722
722
|
private void OnEnable()
|
|
723
723
|
{
|
|
724
|
-
SceneManager.
|
|
724
|
+
SceneManager.sceneLoaded += OnSceneLoaded;
|
|
725
725
|
}
|
|
726
726
|
|
|
727
727
|
private void OnDisable()
|
|
728
728
|
{
|
|
729
|
-
SceneManager.
|
|
729
|
+
SceneManager.sceneLoaded -= OnSceneLoaded;
|
|
730
730
|
|
|
731
731
|
if (HyperRuntime.EventManager != null)
|
|
732
732
|
{
|
|
@@ -734,7 +734,7 @@ namespace Hyper.Internal.Managers
|
|
|
734
734
|
}
|
|
735
735
|
}
|
|
736
736
|
|
|
737
|
-
private void
|
|
737
|
+
private void OnSceneLoaded(Scene newScene, LoadSceneMode loadSceneMode)
|
|
738
738
|
{
|
|
739
739
|
Time.timeScale = 1;
|
|
740
740
|
_previousTimeScale = 1f; // Sync tracking on scene load
|
|
@@ -829,13 +829,13 @@ namespace Hyper.Internal.Managers
|
|
|
829
829
|
{
|
|
830
830
|
HideGameOverModal();
|
|
831
831
|
HidePauseModals();
|
|
832
|
-
|
|
832
|
+
|
|
833
833
|
// Reset game state flags
|
|
834
834
|
_hasGameStarted = false;
|
|
835
835
|
_hasGameEnded = false;
|
|
836
836
|
_isPaused = false;
|
|
837
837
|
_isFrozenBeforePause = false;
|
|
838
|
-
|
|
838
|
+
|
|
839
839
|
HyperRuntime.Timer.Reset();
|
|
840
840
|
HyperRuntime.DataManager.UpdateScore(0);
|
|
841
841
|
|
|
@@ -891,13 +891,32 @@ namespace Hyper.Internal.Managers
|
|
|
891
891
|
private void ApplySafeArea()
|
|
892
892
|
{
|
|
893
893
|
var canvases = FindObjectsByType<Canvas>(FindObjectsSortMode.None);
|
|
894
|
+
var canvasSet = new HashSet<Canvas>(canvases);
|
|
894
895
|
|
|
895
896
|
foreach (var canvas in canvases)
|
|
896
897
|
{
|
|
897
898
|
if (canvas.name == "HyperCanvas") continue;
|
|
898
|
-
if (canvas.GetComponentInChildren<SafeArea>(true) != null) continue;
|
|
899
899
|
|
|
900
|
-
|
|
900
|
+
//? Skip if this canvas is a child/descendant of another canvas in the list
|
|
901
|
+
//? Only the parent canvas should take precedence
|
|
902
|
+
bool isNestedCanvas = false;
|
|
903
|
+
Transform parent = canvas.transform.parent;
|
|
904
|
+
while (parent != null)
|
|
905
|
+
{
|
|
906
|
+
var parentCanvas = parent.GetComponent<Canvas>();
|
|
907
|
+
if (parentCanvas != null && canvasSet.Contains(parentCanvas))
|
|
908
|
+
{
|
|
909
|
+
isNestedCanvas = true;
|
|
910
|
+
break;
|
|
911
|
+
}
|
|
912
|
+
parent = parent.parent;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
if (isNestedCanvas) continue;
|
|
916
|
+
|
|
917
|
+
if (canvas.transform.childCount == 0) continue;
|
|
918
|
+
|
|
919
|
+
var safeAreaGO = new GameObject("SafeArea", typeof(RectTransform));
|
|
901
920
|
var safeAreaRect = (RectTransform)safeAreaGO.transform;
|
|
902
921
|
safeAreaRect.SetParent(canvas.transform, false);
|
|
903
922
|
|
|
@@ -906,6 +925,8 @@ namespace Hyper.Internal.Managers
|
|
|
906
925
|
safeAreaRect.offsetMin = Vector2.zero;
|
|
907
926
|
safeAreaRect.offsetMax = Vector2.zero;
|
|
908
927
|
|
|
928
|
+
safeAreaGO.AddComponent<SafeArea>();
|
|
929
|
+
|
|
909
930
|
var toMove = new List<Transform>();
|
|
910
931
|
foreach (Transform child in canvas.transform)
|
|
911
932
|
{
|
|
@@ -1091,7 +1112,12 @@ namespace Hyper.Internal.Managers
|
|
|
1091
1112
|
|
|
1092
1113
|
GameObject prefab = Resources.Load<GameObject>("UIPrefabs/ControlBar");
|
|
1093
1114
|
GameObject instance = Instantiate(prefab);
|
|
1094
|
-
|
|
1115
|
+
|
|
1116
|
+
Transform controlBarParent = _isPortrait ? _safeArea.transform : _canvas.transform;
|
|
1117
|
+
|
|
1118
|
+
instance.transform.SetParent(controlBarParent, false);
|
|
1119
|
+
|
|
1120
|
+
if (!_isPortrait) instance.transform.SetAsFirstSibling();
|
|
1095
1121
|
|
|
1096
1122
|
RectTransform rectTransform = instance.GetComponent<RectTransform>();
|
|
1097
1123
|
if (rectTransform != null)
|
|
@@ -55,7 +55,7 @@ namespace Hyper.Internal
|
|
|
55
55
|
|
|
56
56
|
Rect MapSafeAreaToRect(SafeAreaInsets safeAreaInsets)
|
|
57
57
|
{
|
|
58
|
-
|
|
58
|
+
|
|
59
59
|
|
|
60
60
|
if (_gameManager.ControlBarLayout == ControlBarLayout.Default)
|
|
61
61
|
{
|
|
@@ -70,6 +70,22 @@ namespace Hyper.Internal
|
|
|
70
70
|
safeAreaInsets.top += topPadding;
|
|
71
71
|
safeAreaInsets.bottom = 0f;
|
|
72
72
|
|
|
73
|
+
if (_gameManager != null && !_gameManager.IsPortrait())
|
|
74
|
+
{
|
|
75
|
+
//? Hyper Mobile currently supports a forced left-landscape mode.
|
|
76
|
+
//? This is to avoid the notch/cutout in the landscape mode.
|
|
77
|
+
bool shouldMapTopToLeft =
|
|
78
|
+
safeAreaInsets.top > 0f &&
|
|
79
|
+
safeAreaInsets.left <= 0f &&
|
|
80
|
+
safeAreaInsets.right <= 0f;
|
|
81
|
+
|
|
82
|
+
if (shouldMapTopToLeft)
|
|
83
|
+
{
|
|
84
|
+
safeAreaInsets.left = safeAreaInsets.top;
|
|
85
|
+
safeAreaInsets.top = 0f;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
73
89
|
float screenWidth = Screen.width;
|
|
74
90
|
float screenHeight = Screen.height;
|
|
75
91
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "app.hypergames.hypersdk",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.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",
|