app.hypergames.hypersdk 1.10.0 → 1.11.0-beta.10
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 +97 -0
- package/Editor/Scripts/Setup/HyperSDKInstaller.cs +42 -0
- package/Editor/Scripts/Tools/HyperGameModeMenu.cs +27 -7
- package/Runtime/Internal/AssemblyInfo.cs +1 -0
- package/Runtime/Internal/Bootstrap/HyperLoader.cs +186 -8
- package/Runtime/Internal/Core/HyperRuntime.cs +115 -0
- package/Runtime/Internal/Core/HyperRuntimeHost.cs +6 -0
- package/Runtime/Internal/Data/URLData.cs +18 -1
- package/Runtime/Internal/Managers/BackendManager.cs +281 -24
- package/Runtime/Internal/Managers/DataManager.cs +208 -21
- package/Runtime/Internal/Managers/GameManager.cs +404 -19
- package/Runtime/Internal/Managers/ReplayManager.cs +118 -0
- package/Runtime/Internal/Managers/ReplayManager.cs.meta +11 -0
- package/Runtime/Internal/Managers/TimeManager.cs +78 -19
- package/Runtime/Internal/Replay/ReplayActivityRecorder.cs +182 -0
- package/Runtime/Internal/Replay/ReplayActivityRecorder.cs.meta +2 -0
- package/Runtime/Internal/Replay/ReplaySessionState.cs +238 -0
- package/Runtime/Internal/Replay/ReplaySessionState.cs.meta +2 -0
- package/Runtime/Internal/Replay.meta +8 -0
- package/Runtime/Internal/ScriptableObjects/HyperSDKSettings.cs +5 -0
- package/Runtime/Internal/UI/Animation/LoadingTextAnimation.cs +15 -1
- package/Runtime/Internal/UI/Components/ControlBar.cs +25 -2
- package/Runtime/Internal/UI/Components/PauseButton.cs +4 -1
- package/Runtime/Internal/UI/Components/ReplayController.cs +531 -0
- package/Runtime/Internal/UI/Components/ReplayController.cs.meta +2 -0
- package/Runtime/Internal/UI/Components/ReplayMarkerPulse.cs +89 -0
- package/Runtime/Internal/UI/Components/ReplayMarkerPulse.cs.meta +2 -0
- package/Runtime/Internal/UI/Components/ReplayPresentationCanvas.cs +183 -0
- package/Runtime/Internal/UI/Components/ReplayPresentationCanvas.cs.meta +2 -0
- package/Runtime/Internal/UI/Modals/LoadingFailedModal.cs +12 -0
- package/Runtime/Internal/UI/Modals/ReplayOverModal.cs +61 -0
- package/Runtime/Internal/UI/Modals/ReplayOverModal.cs.meta +2 -0
- package/Runtime/Internal/UI/Modals/ReplayPausedModal.cs +145 -0
- package/Runtime/Internal/UI/Modals/ReplayPausedModal.cs.meta +2 -0
- package/Runtime/Internal/UI/Modals/StartingInstructionModal.cs +39 -29
- package/Runtime/Public/AssemblyInfo.cs +3 -0
- package/Runtime/Public/AssemblyInfo.cs.meta +2 -0
- package/Runtime/Public/Core/HyperSDK.cs +321 -109
- package/Runtime/Public/Hyper.asmdef +2 -1
- package/Runtime/Public/Replay/ReplayPlaybackEngine.cs +610 -0
- package/Runtime/Public/Replay/ReplayPlaybackEngine.cs.meta +2 -0
- package/Runtime/Public/Replay.meta +8 -0
- package/Runtime/Resources/Fonts/Nunito/Nunito-Bold SDF.asset +500 -457
- package/Runtime/Resources/Fonts/Nunito/Nunito-Light SDF.asset +528 -521
- package/Runtime/Resources/Materials/HyperReplayScanlines.preset +340 -0
- package/Runtime/Resources/Materials/HyperReplayScanlines.preset.meta +8 -0
- package/Runtime/Resources/Materials/ReplayScanlineOverlay.mat +55 -0
- package/Runtime/Resources/Materials/ReplayScanlineOverlay.mat.meta +8 -0
- package/Runtime/Resources/Shaders/ReplayScanlineOverlay.shader +150 -0
- package/Runtime/Resources/Shaders/ReplayScanlineOverlay.shader.meta +10 -0
- package/Runtime/Resources/Sprites/Buttons/Hyper Long White Button_Normal.png +0 -0
- package/Runtime/Resources/Sprites/Buttons/Hyper Long White Button_Normal.png.meta +156 -0
- package/Runtime/Resources/Sprites/Buttons/Hyper Long White Button_Pressed.png +0 -0
- package/Runtime/Resources/Sprites/Buttons/Hyper Long White Button_Pressed.png.meta +156 -0
- package/Runtime/Resources/Sprites/Replays/Fallback avatar.png +0 -0
- package/Runtime/Resources/Sprites/Replays/Fallback avatar.png.meta +156 -0
- package/Runtime/Resources/Sprites/Replays/Replay frame.png +0 -0
- package/Runtime/Resources/Sprites/Replays/Replay frame.png.meta +156 -0
- package/Runtime/Resources/Sprites/Replays/Replay modal icon.png +0 -0
- package/Runtime/Resources/Sprites/Replays/Replay modal icon.png.meta +156 -0
- package/Runtime/Resources/Sprites/Replays/Replay.png +0 -0
- package/Runtime/Resources/Sprites/Replays/Replay.png.meta +156 -0
- package/Runtime/Resources/Sprites/Replays.meta +8 -0
- package/Runtime/Resources/UIPrefabs/ControlBar.prefab +169 -2
- package/Runtime/Resources/UIPrefabs/GamePausedModal_Battle.prefab +1 -1
- package/Runtime/Resources/UIPrefabs/ReplayController.prefab +1388 -0
- package/Runtime/Resources/UIPrefabs/ReplayController.prefab.meta +7 -0
- package/Runtime/Resources/UIPrefabs/ReplayInputBlocker.prefab +90 -0
- package/Runtime/Resources/UIPrefabs/ReplayInputBlocker.prefab.meta +7 -0
- package/Runtime/Resources/UIPrefabs/ReplayOverModal.prefab +958 -0
- package/Runtime/Resources/UIPrefabs/ReplayOverModal.prefab.meta +7 -0
- package/Runtime/Resources/UIPrefabs/ReplayPausedModal.prefab +2194 -0
- package/Runtime/Resources/UIPrefabs/ReplayPausedModal.prefab.meta +7 -0
- package/Runtime/Resources/UIPrefabs/ReplaySeekOverlay.prefab +189 -0
- package/Runtime/Resources/UIPrefabs/ReplaySeekOverlay.prefab.meta +7 -0
- package/Runtime/Resources/UIPrefabs/SnackBar.prefab +2 -2
- package/Runtime/Shared/AssemblyInfo.cs +5 -0
- package/Runtime/Shared/AssemblyInfo.cs.meta +11 -0
- package/Runtime/Shared/DTOs/Enums.cs +8 -3
- package/Runtime/Shared/DTOs/Score/ScoreSnapshot.cs +13 -1
- package/Runtime/Shared/Replay/IReplayPlaybackEngine.cs +40 -0
- package/Runtime/Shared/Replay/IReplayPlaybackEngine.cs.meta +11 -0
- package/Runtime/Shared/Replay.meta +8 -0
- package/Samples~/LaneRunner/LaneRunnerSample.unity +1604 -0
- package/Samples~/LaneRunner/LaneRunnerSample.unity.meta +7 -0
- package/Samples~/LaneRunner/Materials/DoubleScore.mat +86 -0
- package/Samples~/LaneRunner/Materials/DoubleScore.mat.meta +8 -0
- package/Samples~/LaneRunner/Materials/Ground.mat +84 -0
- package/Samples~/LaneRunner/Materials/Ground.mat.meta +8 -0
- package/Samples~/LaneRunner/Materials/Lane.mat +84 -0
- package/Samples~/LaneRunner/Materials/Lane.mat.meta +8 -0
- package/Samples~/LaneRunner/Materials/LaneMarker.mat +84 -0
- package/Samples~/LaneRunner/Materials/LaneMarker.mat.meta +8 -0
- package/Samples~/LaneRunner/Materials/Obstacle.mat +84 -0
- package/Samples~/LaneRunner/Materials/Obstacle.mat.meta +8 -0
- package/Samples~/LaneRunner/Materials/Player.mat +84 -0
- package/Samples~/LaneRunner/Materials/Player.mat.meta +8 -0
- package/Samples~/LaneRunner/Materials.meta +8 -0
- package/Samples~/LaneRunner/Prefabs/DoubleScorePickup.prefab +152 -0
- package/Samples~/LaneRunner/Prefabs/DoubleScorePickup.prefab.meta +7 -0
- package/Samples~/LaneRunner/Prefabs/Obstacle.prefab +152 -0
- package/Samples~/LaneRunner/Prefabs/Obstacle.prefab.meta +7 -0
- package/Samples~/LaneRunner/Prefabs.meta +8 -0
- package/Samples~/LaneRunner/README.md +42 -0
- package/Samples~/LaneRunner/README.md.meta +7 -0
- package/Samples~/LaneRunner/Scripts/Gameplay/LaneRunnerCommand.cs +9 -0
- package/Samples~/LaneRunner/Scripts/Gameplay/LaneRunnerCommand.cs.meta +2 -0
- package/Samples~/LaneRunner/Scripts/Gameplay/LaneRunnerGame.cs +93 -0
- package/Samples~/LaneRunner/Scripts/Gameplay/LaneRunnerGame.cs.meta +2 -0
- package/Samples~/LaneRunner/Scripts/Gameplay/LaneRunnerPlayer.cs +169 -0
- package/Samples~/LaneRunner/Scripts/Gameplay/LaneRunnerPlayer.cs.meta +2 -0
- package/Samples~/LaneRunner/Scripts/Gameplay/LaneRunnerSpawner.cs +112 -0
- package/Samples~/LaneRunner/Scripts/Gameplay/LaneRunnerSpawner.cs.meta +2 -0
- package/Samples~/LaneRunner/Scripts/Gameplay/LaneRunnerTrackItem.cs +41 -0
- package/Samples~/LaneRunner/Scripts/Gameplay/LaneRunnerTrackItem.cs.meta +2 -0
- package/Samples~/LaneRunner/Scripts/Gameplay.meta +8 -0
- package/Samples~/LaneRunner/Scripts/Hyper/LaneRunnerReplayAdapter.cs +62 -0
- package/Samples~/LaneRunner/Scripts/Hyper/LaneRunnerReplayAdapter.cs.meta +2 -0
- package/Samples~/LaneRunner/Scripts/Hyper/LaneRunnerTournamentAdapter.cs +72 -0
- package/Samples~/LaneRunner/Scripts/Hyper/LaneRunnerTournamentAdapter.cs.meta +2 -0
- package/Samples~/LaneRunner/Scripts/Hyper.meta +8 -0
- package/Samples~/LaneRunner/Scripts.meta +8 -0
- package/Tests.meta +8 -0
- package/package.json +8 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,100 @@
|
|
|
1
|
+
# [1.11.0-beta.10](https://github.com/mvmhyper/hyper-sdk/compare/v1.11.0-beta.9...v1.11.0-beta.10) (2026-08-30)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **replay:** reduce default seek speed ([f70551a](https://github.com/mvmhyper/hyper-sdk/commit/f70551aea942274ace1cb952ddae4e9edb0c1c12))
|
|
7
|
+
|
|
8
|
+
# [1.11.0-beta.9](https://github.com/mvmhyper/hyper-sdk/compare/v1.11.0-beta.8...v1.11.0-beta.9) (2026-08-30)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **replay:** show loader while exiting paused replay ([4a2e7a6](https://github.com/mvmhyper/hyper-sdk/commit/4a2e7a6045017ea8ed3ae3525271440dbf013e6c))
|
|
14
|
+
|
|
15
|
+
# [1.11.0-beta.8](https://github.com/mvmhyper/hyper-sdk/compare/v1.11.0-beta.7...v1.11.0-beta.8) (2026-08-30)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* **replay:** mute audio while seeking ([5ab8cd1](https://github.com/mvmhyper/hyper-sdk/commit/5ab8cd1411493cb5add07b51dc190c85251f99d2))
|
|
21
|
+
|
|
22
|
+
# [1.11.0-beta.7](https://github.com/mvmhyper/hyper-sdk/compare/v1.11.0-beta.6...v1.11.0-beta.7) (2026-08-30)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Bug Fixes
|
|
26
|
+
|
|
27
|
+
* **replay:** stabilize scene reload seeking ([dd9ac63](https://github.com/mvmhyper/hyper-sdk/commit/dd9ac632d08349d9578f64ae0b2dc2ab905a26af))
|
|
28
|
+
|
|
29
|
+
# [1.11.0-beta.6](https://github.com/mvmhyper/hyper-sdk/compare/v1.11.0-beta.5...v1.11.0-beta.6) (2026-08-29)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
### Bug Fixes
|
|
33
|
+
|
|
34
|
+
* **timer:** restore gameplay timers after pause ([ca82d57](https://github.com/mvmhyper/hyper-sdk/commit/ca82d57df87618807cbae611c0a9d6acc14f8470))
|
|
35
|
+
|
|
36
|
+
# [1.11.0-beta.5](https://github.com/mvmhyper/hyper-sdk/compare/v1.11.0-beta.4...v1.11.0-beta.5) (2026-08-28)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
### Bug Fixes
|
|
40
|
+
|
|
41
|
+
* **replay:** wait for custom restart readiness ([43f1aeb](https://github.com/mvmhyper/hyper-sdk/commit/43f1aeb6a127c8c12dbb8379e7230d64ef5e0763))
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
### Features
|
|
45
|
+
|
|
46
|
+
* **replay:** add replay pause controls ([b9fb470](https://github.com/mvmhyper/hyper-sdk/commit/b9fb470e65c69e66a8a9611b0caa7e5417b1e4bf))
|
|
47
|
+
* **replay:** update replay control bar assets ([79ce8c0](https://github.com/mvmhyper/hyper-sdk/commit/79ce8c0f1b68129ae5b8bcf18a302117cf11c885))
|
|
48
|
+
|
|
49
|
+
# [1.11.0-beta.4](https://github.com/mvmhyper/hyper-sdk/compare/v1.11.0-beta.3...v1.11.0-beta.4) (2026-08-28)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
### Bug Fixes
|
|
53
|
+
|
|
54
|
+
* **replay:** align recording with fixed simulation ([ae2b322](https://github.com/mvmhyper/hyper-sdk/commit/ae2b32216a0a9ea125572d788eee3bfd846414b0))
|
|
55
|
+
|
|
56
|
+
# [1.11.0-beta.3](https://github.com/mvmhyper/hyper-sdk/compare/v1.11.0-beta.2...v1.11.0-beta.3) (2026-08-28)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
### Bug Fixes
|
|
60
|
+
|
|
61
|
+
* **replay:** reset random state before playback restart ([526a4d9](https://github.com/mvmhyper/hyper-sdk/commit/526a4d98c9b22241e3c52bb6837145bad999fb2b))
|
|
62
|
+
* **sample:** support lane runner custom restart ([49da385](https://github.com/mvmhyper/hyper-sdk/commit/49da385aaa917de438672a8630d4fe7927741b2a))
|
|
63
|
+
|
|
64
|
+
# [1.11.0-beta.2](https://github.com/mvmhyper/hyper-sdk/compare/v1.11.0-beta.1...v1.11.0-beta.2) (2026-08-27)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
### Bug Fixes
|
|
68
|
+
|
|
69
|
+
* **replay:** respect custom restart flows ([7470a17](https://github.com/mvmhyper/hyper-sdk/commit/7470a17c60534465500a202c24b0e360f61850fc))
|
|
70
|
+
* **replay:** shorten automatic replay start ([d05dc92](https://github.com/mvmhyper/hyper-sdk/commit/d05dc9267fbf05d392135eac3bb7c4f69b786eff))
|
|
71
|
+
* **timer:** align game time with fixed simulation ([b690d86](https://github.com/mvmhyper/hyper-sdk/commit/b690d861e178f05b21f1a7fbd87e255d97008a8b))
|
|
72
|
+
|
|
73
|
+
# [1.11.0-beta.1](https://github.com/mvmhyper/hyper-sdk/compare/v1.10.0...v1.11.0-beta.1) (2026-08-26)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
### Bug Fixes
|
|
77
|
+
|
|
78
|
+
* **replay:** add player handle font glyph ([5ba9f0d](https://github.com/mvmhyper/hyper-sdk/commit/5ba9f0d0c3e207b4ff0a4b4f16ffe53bd215ea14))
|
|
79
|
+
* **replay:** handle backend loading failures ([1d299cf](https://github.com/mvmhyper/hyper-sdk/commit/1d299cf7d1002d5632cd0b1da2c928405b50e56a))
|
|
80
|
+
* **replay:** harden web replay playback ([96f0521](https://github.com/mvmhyper/hyper-sdk/commit/96f05215f6a483306622b632366de20b58ede6e9))
|
|
81
|
+
* **replay:** preserve recorded action timing ([48ff268](https://github.com/mvmhyper/hyper-sdk/commit/48ff268c16b0ddd5fd4e81e0903d4b54b05d4a1c))
|
|
82
|
+
* **replay:** refine replay ui behavior ([8a9364f](https://github.com/mvmhyper/hyper-sdk/commit/8a9364fb19f6ccd6df31a396bf7fef30c5f66040))
|
|
83
|
+
* **score:** preserve latest final snapshot time ([b9242cd](https://github.com/mvmhyper/hyper-sdk/commit/b9242cd5478702621fbc30a1bd21a972bbf9fb4c))
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
### Features
|
|
87
|
+
|
|
88
|
+
* **replay:** add math rush replay integration ([394e8b0](https://github.com/mvmhyper/hyper-sdk/commit/394e8b0591c99899b5f2433bbadf159aa4631d47))
|
|
89
|
+
* **replay:** add replay activity recording ([8b87b42](https://github.com/mvmhyper/hyper-sdk/commit/8b87b425440ebfa4d08fcc9d62586afde58fda33))
|
|
90
|
+
* **replay:** add replay playback scheduling ([40c9c83](https://github.com/mvmhyper/hyper-sdk/commit/40c9c83a886b06434ee886fa85f490ca74710ac6))
|
|
91
|
+
* **replay:** add replay ui flows ([e287986](https://github.com/mvmhyper/hyper-sdk/commit/e287986222763c814a299cfcb81d1cd14bcf49e9))
|
|
92
|
+
* **replay:** add replay visual assets ([4c61645](https://github.com/mvmhyper/hyper-sdk/commit/4c616458155e04444feac9fb187b63f646035f7a))
|
|
93
|
+
* **replay:** add stable replay launch mode ([fbfd8fc](https://github.com/mvmhyper/hyper-sdk/commit/fbfd8fcdc5a7119f7c3655f1a033705ccd47608f))
|
|
94
|
+
* **replay:** align playback with fixed simulation ([8e4051d](https://github.com/mvmhyper/hyper-sdk/commit/8e4051d5d41fe3dbc4d050ee4f961ae6d690d1bd))
|
|
95
|
+
* **replay:** finalize playback simulation and seeking ([de3b6e7](https://github.com/mvmhyper/hyper-sdk/commit/de3b6e79be4ecde5abc4bb20190e80f12fbe3598))
|
|
96
|
+
* **replay:** load replay data from backend ([f89c067](https://github.com/mvmhyper/hyper-sdk/commit/f89c067b6e55074c08f75e34c0d378af969b60c5))
|
|
97
|
+
|
|
1
98
|
# [1.10.0](https://github.com/mvmhyper/hyper-sdk/compare/v1.9.1...v1.10.0) (2026-08-10)
|
|
2
99
|
|
|
3
100
|
|
|
@@ -20,9 +20,51 @@ namespace Hyper.Editor
|
|
|
20
20
|
private const string HyperSDKSettingsRelativePath = "Runtime/Resources/HyperSDKSettings.asset";
|
|
21
21
|
private const string HyperGameContentConfigDestination = "Assets/HyperSDK/Runtime/Resources/HyperGameContentConfig.asset";
|
|
22
22
|
private const string HyperSDKSettingsDestination = "Assets/HyperSDK/Runtime/Resources/HyperSDKSettings.asset";
|
|
23
|
+
private const string LaneRunnerSampleRelativePath = "Samples~/LaneRunner";
|
|
24
|
+
private const string LaneRunnerSampleDestination = "Assets/Samples/HyperSDK/Lane Runner";
|
|
23
25
|
|
|
24
26
|
private static bool _hasChecked = false;
|
|
25
27
|
|
|
28
|
+
[MenuItem("Hyper/Samples/Import Lane Runner", priority = 100)]
|
|
29
|
+
private static void ImportLaneRunnerSample()
|
|
30
|
+
{
|
|
31
|
+
var packageInfo = UnityEditor.PackageManager.PackageInfo.FindForAssembly(typeof(HyperSDKInstaller).Assembly);
|
|
32
|
+
if (packageInfo == null || string.IsNullOrEmpty(packageInfo.resolvedPath) ||
|
|
33
|
+
packageInfo.resolvedPath.Replace('\\', '/').Contains("/Assets/"))
|
|
34
|
+
{
|
|
35
|
+
var developmentSample = AssetDatabase.LoadAssetAtPath<SceneAsset>(
|
|
36
|
+
"Assets/SampleGame (Lane Runner)/LaneRunnerSample.unity");
|
|
37
|
+
Selection.activeObject = developmentSample;
|
|
38
|
+
EditorGUIUtility.PingObject(developmentSample);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
string sourcePath = Path.Combine(packageInfo.resolvedPath, LaneRunnerSampleRelativePath);
|
|
43
|
+
|
|
44
|
+
if (!Directory.Exists(sourcePath))
|
|
45
|
+
{
|
|
46
|
+
EditorUtility.DisplayDialog("Lane Runner Sample",
|
|
47
|
+
"The Lane Runner sample was not found in this HyperSDK installation.", "OK");
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (Directory.Exists(LaneRunnerSampleDestination))
|
|
52
|
+
{
|
|
53
|
+
EditorUtility.DisplayDialog("Lane Runner Sample",
|
|
54
|
+
"Lane Runner is already imported at Assets/Samples/HyperSDK/Lane Runner.", "OK");
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
Directory.CreateDirectory(Path.GetDirectoryName(LaneRunnerSampleDestination));
|
|
59
|
+
FileUtil.CopyFileOrDirectory(sourcePath, LaneRunnerSampleDestination);
|
|
60
|
+
AssetDatabase.Refresh();
|
|
61
|
+
|
|
62
|
+
var scene = AssetDatabase.LoadAssetAtPath<SceneAsset>(
|
|
63
|
+
LaneRunnerSampleDestination + "/LaneRunnerSample.unity");
|
|
64
|
+
Selection.activeObject = scene;
|
|
65
|
+
EditorGUIUtility.PingObject(scene);
|
|
66
|
+
}
|
|
67
|
+
|
|
26
68
|
static HyperSDKInstaller()
|
|
27
69
|
{
|
|
28
70
|
// Only register delayCall once per domain reload
|
|
@@ -8,11 +8,12 @@ namespace Hyper.Editor
|
|
|
8
8
|
{
|
|
9
9
|
static class HyperGameModeMenu
|
|
10
10
|
{
|
|
11
|
-
private enum DevMode { Practice = 0, Battle = 1 }
|
|
11
|
+
private enum DevMode { Practice = 0, Battle = 1, Replay = 2 }
|
|
12
12
|
private const string PrefKey = "Hyper.DevMode";
|
|
13
13
|
|
|
14
14
|
private const string BattlePath = "Hyper/Battle Game Mode";
|
|
15
15
|
private const string PracticePath = "Hyper/Practice Game Mode";
|
|
16
|
+
private const string ReplayPath = "Hyper/Replay Game Mode";
|
|
16
17
|
|
|
17
18
|
private static HyperSDKSettings _settings;
|
|
18
19
|
|
|
@@ -26,10 +27,14 @@ namespace Hyper.Editor
|
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
private static DevMode FromSettings(GameMode gm)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
{
|
|
31
|
+
switch (gm)
|
|
32
|
+
{
|
|
33
|
+
case GameMode.Battle: return DevMode.Battle;
|
|
34
|
+
case GameMode.Replay: return DevMode.Replay;
|
|
35
|
+
default: return DevMode.Practice;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
33
38
|
|
|
34
39
|
private static DevMode Current
|
|
35
40
|
{
|
|
@@ -44,8 +49,12 @@ namespace Hyper.Editor
|
|
|
44
49
|
{
|
|
45
50
|
if (TryLoadSettings(out var s))
|
|
46
51
|
{
|
|
47
|
-
|
|
48
|
-
|
|
52
|
+
switch (value)
|
|
53
|
+
{
|
|
54
|
+
case DevMode.Battle: s.SetModeAsBattle(); break;
|
|
55
|
+
case DevMode.Replay: s.SetModeAsReplay(); break;
|
|
56
|
+
default: s.SetModeAsPractice(); break;
|
|
57
|
+
}
|
|
49
58
|
|
|
50
59
|
EditorUtility.SetDirty(s);
|
|
51
60
|
AssetDatabase.SaveAssets();
|
|
@@ -84,6 +93,16 @@ namespace Hyper.Editor
|
|
|
84
93
|
return !EditorApplication.isPlaying;
|
|
85
94
|
}
|
|
86
95
|
|
|
96
|
+
[MenuItem(ReplayPath, priority = 300)]
|
|
97
|
+
private static void SetReplay() => SetMode(DevMode.Replay);
|
|
98
|
+
|
|
99
|
+
[MenuItem(ReplayPath, validate = true)]
|
|
100
|
+
private static bool ValidateReplay()
|
|
101
|
+
{
|
|
102
|
+
Menu.SetChecked(ReplayPath, Current == DevMode.Replay);
|
|
103
|
+
return !EditorApplication.isPlaying;
|
|
104
|
+
}
|
|
105
|
+
|
|
87
106
|
#endregion
|
|
88
107
|
|
|
89
108
|
private static void SetMode(DevMode mode)
|
|
@@ -94,6 +113,7 @@ namespace Hyper.Editor
|
|
|
94
113
|
|
|
95
114
|
Menu.SetChecked(BattlePath, mode == DevMode.Battle);
|
|
96
115
|
Menu.SetChecked(PracticePath, mode == DevMode.Practice);
|
|
116
|
+
Menu.SetChecked(ReplayPath, mode == DevMode.Replay);
|
|
97
117
|
|
|
98
118
|
HyperDebug.LogSuccess($"Game Mode set to: {mode}");
|
|
99
119
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
using Hyper.Internal.Managers;
|
|
2
2
|
using System;
|
|
3
3
|
using System.Collections;
|
|
4
|
+
#if UNITY_EDITOR
|
|
5
|
+
using System.IO;
|
|
6
|
+
#endif
|
|
4
7
|
using TMPro;
|
|
5
8
|
using UnityEngine;
|
|
6
9
|
using UnityEngine.SceneManagement;
|
|
@@ -60,6 +63,11 @@ namespace Hyper.Internal
|
|
|
60
63
|
InitializeComponents();
|
|
61
64
|
LoadConfiguration();
|
|
62
65
|
SetupSplashScreen();
|
|
66
|
+
|
|
67
|
+
if (ReplaySessionState.IsSeeking)
|
|
68
|
+
{
|
|
69
|
+
SetLoaderCanvasVisible(false);
|
|
70
|
+
}
|
|
63
71
|
}
|
|
64
72
|
|
|
65
73
|
private void Start()
|
|
@@ -74,6 +82,15 @@ namespace Hyper.Internal
|
|
|
74
82
|
|
|
75
83
|
#endregion
|
|
76
84
|
|
|
85
|
+
private void SetLoaderCanvasVisible(bool isVisible)
|
|
86
|
+
{
|
|
87
|
+
Canvas[] canvases = GetComponentsInChildren<Canvas>(true);
|
|
88
|
+
for (int i = 0; i < canvases.Length; i++)
|
|
89
|
+
{
|
|
90
|
+
canvases[i].enabled = isVisible;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
77
94
|
#region Initialization
|
|
78
95
|
|
|
79
96
|
private void InitializeComponents()
|
|
@@ -115,7 +132,7 @@ namespace Hyper.Internal
|
|
|
115
132
|
private static T LoadResourceFromAssets<T>(string resourceName) where T : UnityEngine.Object
|
|
116
133
|
{
|
|
117
134
|
T[] allResources = Resources.LoadAll<T>(string.Empty);
|
|
118
|
-
|
|
135
|
+
|
|
119
136
|
if (allResources == null || allResources.Length == 0)
|
|
120
137
|
{
|
|
121
138
|
return Resources.Load<T>(resourceName);
|
|
@@ -247,9 +264,13 @@ namespace Hyper.Internal
|
|
|
247
264
|
{
|
|
248
265
|
sdkInitialized = true;
|
|
249
266
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
267
|
+
// Bootstrap retries recreate the runtime managers. Always bind the
|
|
268
|
+
// current instances rather than retaining objects queued for destruction.
|
|
269
|
+
_eventManager = HyperRuntime.EventManager;
|
|
270
|
+
_gameManager = HyperRuntime.GameManager;
|
|
271
|
+
_backendManager = HyperRuntime.BackendManager;
|
|
272
|
+
UpdateLoadingTextForMode();
|
|
273
|
+
UpdateHintVisibilityForMode();
|
|
253
274
|
SubscribeToEvents();
|
|
254
275
|
});
|
|
255
276
|
|
|
@@ -264,14 +285,23 @@ namespace Hyper.Internal
|
|
|
264
285
|
_loadingBarSlider.value = _bootstrapProgress;
|
|
265
286
|
|
|
266
287
|
// Start tutorial discovery early, but never wait for it before loading gameplay.
|
|
267
|
-
|
|
288
|
+
if (!_gameManager.IsReplayMode)
|
|
289
|
+
{
|
|
290
|
+
HyperRuntime.BackendManager.GetTutorial(null);
|
|
291
|
+
}
|
|
268
292
|
|
|
269
293
|
// Step 2: Handle Backend/PVP or Practice mode initialization
|
|
270
|
-
if (_gameManager.
|
|
294
|
+
if (_gameManager.IsReplayMode)
|
|
295
|
+
{
|
|
296
|
+
bool replayInitialized = false;
|
|
297
|
+
yield return InitializeReplay(success => replayInitialized = success);
|
|
298
|
+
if (!replayInitialized) yield break;
|
|
299
|
+
}
|
|
300
|
+
else if (_gameManager.Config.IsBackendGame && _gameManager.Config.isPVP)
|
|
271
301
|
{
|
|
272
302
|
yield return InitializeBackendGame();
|
|
273
303
|
}
|
|
274
|
-
else if (_gameManager.
|
|
304
|
+
else if (_gameManager.IsBattleMode)
|
|
275
305
|
{
|
|
276
306
|
InitializeNonBackendBattle();
|
|
277
307
|
}
|
|
@@ -328,6 +358,117 @@ namespace Hyper.Internal
|
|
|
328
358
|
_loadingBarSlider.value = _bootstrapProgress;
|
|
329
359
|
}
|
|
330
360
|
|
|
361
|
+
private IEnumerator InitializeReplay(Action<bool> onComplete)
|
|
362
|
+
{
|
|
363
|
+
_targetSceneName = _gameContentConfig.GameScene?.SceneName;
|
|
364
|
+
|
|
365
|
+
if (!ReplaySessionState.HasReplayData)
|
|
366
|
+
{
|
|
367
|
+
#if UNITY_EDITOR
|
|
368
|
+
if (string.IsNullOrWhiteSpace(_gameManager.Config.EntryId))
|
|
369
|
+
{
|
|
370
|
+
if (TryLoadEditorReplay(out string editorReplayError))
|
|
371
|
+
{
|
|
372
|
+
_backendManager.RegisterSeed(GetRandomSeed());
|
|
373
|
+
onComplete?.Invoke(true);
|
|
374
|
+
yield break;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
HandleReplayLoadingFailure(editorReplayError, onComplete);
|
|
378
|
+
yield break;
|
|
379
|
+
}
|
|
380
|
+
#endif
|
|
381
|
+
bool replayDownloaded = false;
|
|
382
|
+
string replayError = null;
|
|
383
|
+
yield return _backendManager.FetchReplay(
|
|
384
|
+
_gameManager.Config.EntryId,
|
|
385
|
+
() => replayDownloaded = true,
|
|
386
|
+
error => replayError = error);
|
|
387
|
+
|
|
388
|
+
if (!replayDownloaded || !ReplaySessionState.HasReplayData)
|
|
389
|
+
{
|
|
390
|
+
HandleReplayLoadingFailure($"Unable to load replay: {replayError}", onComplete);
|
|
391
|
+
yield break;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
if (ReplaySessionState.AvatarTexture == null &&
|
|
397
|
+
!string.IsNullOrWhiteSpace(ReplaySessionState.AvatarUrl))
|
|
398
|
+
{
|
|
399
|
+
Texture2D downloadedAvatar = null;
|
|
400
|
+
string avatarError = null;
|
|
401
|
+
|
|
402
|
+
yield return _backendManager.FetchReplayAvatar(
|
|
403
|
+
ReplaySessionState.AvatarUrl,
|
|
404
|
+
texture => downloadedAvatar = texture,
|
|
405
|
+
error => avatarError = error);
|
|
406
|
+
|
|
407
|
+
if (downloadedAvatar != null)
|
|
408
|
+
{
|
|
409
|
+
Texture2D circularAvatar = ReplayController.CreateCircularAvatar(
|
|
410
|
+
downloadedAvatar,
|
|
411
|
+
ReplayController.AvatarTextureSize);
|
|
412
|
+
|
|
413
|
+
Destroy(downloadedAvatar);
|
|
414
|
+
ReplaySessionState.SetAvatarTexture(circularAvatar);
|
|
415
|
+
}
|
|
416
|
+
else
|
|
417
|
+
{
|
|
418
|
+
HyperDebug.LogWarning(
|
|
419
|
+
$"Unable to load replay avatar. Using fallback avatar. Error: {avatarError}");
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
_backendManager.RegisterSeed(GetRandomSeed());
|
|
424
|
+
_bootstrapProgress = _progressAfterBackend;
|
|
425
|
+
_loadingBarSlider.value = _bootstrapProgress;
|
|
426
|
+
onComplete?.Invoke(true);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
#if UNITY_EDITOR
|
|
430
|
+
private bool TryLoadEditorReplay(out string error)
|
|
431
|
+
{
|
|
432
|
+
error = null;
|
|
433
|
+
string path = ReplaySessionState.EditorReplayFilePath;
|
|
434
|
+
if (!File.Exists(path))
|
|
435
|
+
{
|
|
436
|
+
error = $"No Editor replay has been recorded at {path}.";
|
|
437
|
+
return false;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
try
|
|
441
|
+
{
|
|
442
|
+
string ndjson = File.ReadAllText(path);
|
|
443
|
+
if (!BackendManager.TryParseReplayResponse(
|
|
444
|
+
ndjson,
|
|
445
|
+
out BackendManager.ReplayResponse replay,
|
|
446
|
+
out error))
|
|
447
|
+
{
|
|
448
|
+
return false;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
ReplaySessionState.SetMetadata(replay.PlayerName, replay.AvatarUrl, replay.Seed);
|
|
452
|
+
ReplaySessionState.SetReplayData(replay.ActivityNdjson);
|
|
453
|
+
HyperDebug.Log($"Replay loaded from {path}");
|
|
454
|
+
return true;
|
|
455
|
+
}
|
|
456
|
+
catch (Exception exception)
|
|
457
|
+
{
|
|
458
|
+
error = $"Unable to load Editor replay: {exception.Message}";
|
|
459
|
+
return false;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
#endif
|
|
463
|
+
|
|
464
|
+
private void HandleReplayLoadingFailure(string error, Action<bool> onComplete)
|
|
465
|
+
{
|
|
466
|
+
HyperDebug.LogError(error);
|
|
467
|
+
onComplete?.Invoke(false);
|
|
468
|
+
_gameManager.ShowLoadingFailedModal(true);
|
|
469
|
+
_gameManager.LoadingFailedModalComponent?.AllAttemptsHaveFailed();
|
|
470
|
+
}
|
|
471
|
+
|
|
331
472
|
private void InitializeNonBackendBattle()
|
|
332
473
|
{
|
|
333
474
|
_targetSceneName = _gameContentConfig.GameScene?.SceneName;
|
|
@@ -377,8 +518,21 @@ namespace Hyper.Internal
|
|
|
377
518
|
|
|
378
519
|
private long GetRandomSeed()
|
|
379
520
|
{
|
|
521
|
+
if (_gameManager.IsReplayMode)
|
|
522
|
+
{
|
|
523
|
+
if (ReplaySessionState.OriginalRandomSeed != 0)
|
|
524
|
+
{
|
|
525
|
+
return ReplaySessionState.OriginalRandomSeed;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
if (HyperRuntime.Settings != null && HyperRuntime.Settings._settings != null)
|
|
529
|
+
{
|
|
530
|
+
return HyperRuntime.Settings._settings.RandomSeed;
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
|
|
380
534
|
#if UNITY_EDITOR
|
|
381
|
-
// In editor, use the seed from editor simulation settings if available
|
|
535
|
+
// In editor, use the seed from editor simulation settings if available.
|
|
382
536
|
if (HyperRuntime.Settings != null && HyperRuntime.Settings._settings != null)
|
|
383
537
|
{
|
|
384
538
|
return HyperRuntime.Settings._settings.RandomSeed;
|
|
@@ -464,6 +618,30 @@ namespace Hyper.Internal
|
|
|
464
618
|
|
|
465
619
|
#region UI Control
|
|
466
620
|
|
|
621
|
+
private void UpdateLoadingTextForMode()
|
|
622
|
+
{
|
|
623
|
+
if (_gameManager == null) return;
|
|
624
|
+
|
|
625
|
+
SetLoadingText(_gameManager.IsReplayMode ? "LOADING REPLAY" : "LAUNCHING GAME");
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
private void SetLoadingText(string text)
|
|
629
|
+
{
|
|
630
|
+
if (launchingGameAnimation == null) return;
|
|
631
|
+
|
|
632
|
+
LoadingTextAnimation animation =
|
|
633
|
+
launchingGameAnimation.GetComponentInChildren<LoadingTextAnimation>(true);
|
|
634
|
+
animation?.SetBaseText(text);
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
private void UpdateHintVisibilityForMode()
|
|
638
|
+
{
|
|
639
|
+
if (hintContainer != null && _gameManager != null && _gameManager.IsReplayMode)
|
|
640
|
+
{
|
|
641
|
+
hintContainer.SetActive(false);
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
|
|
467
645
|
private void ShowLoadingScreenElements(bool show)
|
|
468
646
|
{
|
|
469
647
|
if (launchingGameAnimation != null)
|