gg.easy.airship 0.1.2193 → 0.1.2194
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/Editor/Accessories/Clothing/PlatformGearBundleManifestEditor.cs +7 -1
- package/Editor/CreateAssetBundles.cs +5 -11
- package/Editor/Publish/Callback/IBuildAirshipGameBundle.cs +49 -0
- package/Editor/Publish/Callback/IBuildAirshipGameBundle.cs.meta +3 -0
- package/Editor/Publish/Callback.meta +3 -0
- package/Editor/Publish/Deploy.cs +28 -21
- package/Editor/Quality/QualityConfig.cs +39 -12
- package/Editor/Settings/AirshipSettingsProvider.cs +17 -0
- package/Runtime/Code/AirshipConst.cs +2 -2
- package/Runtime/Code/CoreUI/Components/AirshipVersionOverlay.cs +21 -0
- package/Runtime/Code/CoreUI/Components/AirshipVersionOverlay.cs.meta +3 -0
- package/Runtime/Code/Luau/LuauAssembly/BinaryBlob.cs +2 -1
- package/Runtime/Code/Luau/LuauCoreCallbacks.cs +5 -0
- package/Runtime/Code/LuauAPI/GameObjectAPI.cs +15 -4
- package/Runtime/Code/LuauAPI/TransformAPI.cs +14 -2
- package/Runtime/Code/LuauHelper/LuauHelper.cs +9 -1
- package/Runtime/Code/Network/Simulation/AirshipNetworkedObject.cs +1 -3
- package/Runtime/Code/Network/Simulation/AirshipSimulationManager.cs +11 -10
- package/Runtime/Code/Network/Simulation/History.cs +3 -3
- package/Runtime/Code/Network/StateSystem/AirshipNetworkedStateManager.cs +21 -15
- package/Runtime/Code/Network/StateSystem/Implementations/TestMovementSystem/TestMovementInputDiff.cs +7 -0
- package/Runtime/Code/Network/StateSystem/Implementations/TestMovementSystem/TestMovementInputDiff.cs.meta +3 -0
- package/Runtime/Code/Network/StateSystem/Implementations/TestMovementSystem/TestMovementInputGroup.cs +16 -0
- package/Runtime/Code/Network/StateSystem/Implementations/TestMovementSystem/TestMovementInputGroup.cs.meta +3 -0
- package/Runtime/Code/Network/StateSystem/Implementations/TestMovementSystem/TestNetworkedStateManager.cs +7 -5
- package/Runtime/Code/Network/StateSystem/Structures/InputCommand.cs +9 -0
- package/Runtime/Code/Network/StateSystem/Structures/InputCommandDiff.cs +13 -0
- package/Runtime/Code/Network/StateSystem/Structures/InputCommandDiff.cs.meta +3 -0
- package/Runtime/Code/Network/StateSystem/Structures/InputCommandGroup.cs +43 -0
- package/Runtime/Code/Network/StateSystem/Structures/InputCommandGroup.cs.meta +3 -0
- package/Runtime/Code/Player/Character/MovementSystems/Character/CharacterMovement.cs +68 -167
- package/Runtime/Code/Player/Character/MovementSystems/Character/CharacterNetworkedStateManager.cs +5 -6
- package/Runtime/Code/Player/Character/MovementSystems/Character/CharacterPhysics.cs +2 -2
- package/Runtime/Code/Player/Character/MovementSystems/Character/Structures/CharacterInputData.cs +113 -2
- package/Runtime/Code/Player/Character/MovementSystems/Character/Structures/CharacterInputDiff.cs +56 -0
- package/Runtime/Code/Player/Character/MovementSystems/Character/Structures/CharacterInputDiff.cs.meta +3 -0
- package/Runtime/Code/Player/Character/MovementSystems/Character/Structures/CharacterInputGroup.cs +27 -0
- package/Runtime/Code/Player/Character/MovementSystems/Character/Structures/CharacterInputGroup.cs.meta +3 -0
- package/Runtime/Code/Player/Character/MovementSystems/Character/Structures/CharacterSnapshotData.cs +30 -41
- package/Runtime/Code/VoxelWorld/Resources/VoxelWorldMatURP.mat +3 -3
- package/Runtime/Code/VoxelWorld/VoxelWorld.cs +41 -24
- package/Runtime/Code/VoxelWorld/VoxelWorldChunk.cs +4 -1
- package/Runtime/Code/VoxelWorld/VoxelWorldEditorConfig.cs +13 -0
- package/Runtime/Code/VoxelWorld/VoxelWorldEditorConfig.cs.meta +3 -0
- package/Runtime/Code/VoxelWorld/VoxelWorldNetworker.cs +2 -0
- package/Runtime/Scenes/CoreScene.unity +261 -648
- package/ThirdParty/UiRoundedCorners/ImageWithIndependentRoundedCorners.cs +1 -0
- package/ThirdParty/UiRoundedCorners/ImageWithRoundedCorners.cs +1 -0
- package/URP/AirshipLowestURPAsset_Renderer.asset +1 -1
- package/URP/AirshipMobileURPAsset.asset +2 -0
- package/URP/AirshipMobileURPAsset_Renderer.asset +3 -3
- package/URP/AirshipURPAsset.asset +3 -1
- package/URP/AirshipURPAsset_Renderer.asset +3 -3
- package/package.json +1 -1
|
@@ -23,7 +23,13 @@ namespace Editor.Accessories.Clothing {
|
|
|
23
23
|
[CustomEditor(typeof(PlatformGearBundleManifest))]
|
|
24
24
|
[CanEditMultipleObjects]
|
|
25
25
|
public class PlatformGearBundleManifestEditor : UnityEditor.Editor {
|
|
26
|
+
#if AIRSHIP_STAGING
|
|
27
|
+
private static string easyOrgId = "6536df9f3843ac629cf3b8b1";
|
|
28
|
+
private static string defaultImageId = "b5f260d4-2678-4255-b9bd-9136dd3edf36";
|
|
29
|
+
#else
|
|
26
30
|
private static string easyOrgId = "6b62d6e3-9d74-449c-aeac-b4feed2012b1";
|
|
31
|
+
private static string defaultImageId = "64351892-40d4-409b-ab3a-501818213b50";
|
|
32
|
+
#endif
|
|
27
33
|
private bool skipBuild = false;
|
|
28
34
|
|
|
29
35
|
[MenuItem("Airship/Internal/Publish All Platform Gear")]
|
|
@@ -140,7 +146,7 @@ namespace Editor.Accessories.Clothing {
|
|
|
140
146
|
// Create a new class id
|
|
141
147
|
var data = JsonUtility.ToJson(new GearCreateRequest() {
|
|
142
148
|
name = gear.name,
|
|
143
|
-
imageId =
|
|
149
|
+
imageId = defaultImageId,
|
|
144
150
|
description = "Clothing",
|
|
145
151
|
airAssets = new string[] { },
|
|
146
152
|
category = category,
|
|
@@ -5,6 +5,7 @@ using System.IO;
|
|
|
5
5
|
using System.Linq;
|
|
6
6
|
using Code.Bootstrap;
|
|
7
7
|
using Editor.Packages;
|
|
8
|
+
using Editor.Publish.Callback;
|
|
8
9
|
using UnityEditor.Build.Pipeline;
|
|
9
10
|
using UnityEditor.Build.Pipeline.Interfaces;
|
|
10
11
|
using UnityEditor.Build.Pipeline.Tasks;
|
|
@@ -344,9 +345,7 @@ public static class CreateAssetBundles {
|
|
|
344
345
|
addressableNames = addressableNames
|
|
345
346
|
};
|
|
346
347
|
builds.Add(build);
|
|
347
|
-
} else {
|
|
348
|
-
if (assetBundleName != "shared/resources") continue;
|
|
349
|
-
|
|
348
|
+
} else if (assetBundleName == "shared/resources") {
|
|
350
349
|
var assetGuids = AssetDatabase.FindAssets("*", new string[] {"Assets/Resources"}).ToHashSet();
|
|
351
350
|
if (AssetDatabase.AssetPathExists("Assets/Airship.asbuildinfo")) {
|
|
352
351
|
assetGuids.Add(AssetDatabase.AssetPathToGUID("Assets/Airship.asbuildinfo"));
|
|
@@ -416,14 +415,6 @@ public static class CreateAssetBundles {
|
|
|
416
415
|
buildParams.BundleCompression = BuildCompression.LZ4;
|
|
417
416
|
var buildContent = new BundleBuildContent(builds);
|
|
418
417
|
|
|
419
|
-
// Debug.Log("Additional files:");
|
|
420
|
-
// foreach (var pair in buildContent.AdditionalFiles) {
|
|
421
|
-
// Debug.Log(pair.Key + ":");
|
|
422
|
-
// foreach (var p in pair.Value) {
|
|
423
|
-
// Debug.Log(" - " + p.fileAlias);
|
|
424
|
-
// }
|
|
425
|
-
// }
|
|
426
|
-
|
|
427
418
|
ContentPipeline.BuildCallbacks.PostPackingCallback = (parameters, data, arg3) => {
|
|
428
419
|
return ReturnCode.Success;
|
|
429
420
|
};
|
|
@@ -431,6 +422,9 @@ public static class CreateAssetBundles {
|
|
|
431
422
|
AirshipPackagesWindow.buildingPackageId = "game";
|
|
432
423
|
buildingBundles = true;
|
|
433
424
|
AirshipScriptableBuildPipelineConfig.buildingGameBundles = true;
|
|
425
|
+
// Allow other logic to hook into pre build game bundles (used for setting up scriptable shader
|
|
426
|
+
// scripting based on target).
|
|
427
|
+
BuildAirshipGameBundleProcessor.InvokePreBuildGameBundle(buildTarget);
|
|
434
428
|
ReturnCode returnCode = ContentPipeline.BuildAssetBundles(buildParams, buildContent, out var result);
|
|
435
429
|
buildingBundles = false;
|
|
436
430
|
AirshipScriptableBuildPipelineConfig.buildingGameBundles = false;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections.Generic;
|
|
3
|
+
using System.Linq;
|
|
4
|
+
using System.Reflection;
|
|
5
|
+
using UnityEditor;
|
|
6
|
+
using UnityEditor.Build;
|
|
7
|
+
using UnityEngine;
|
|
8
|
+
|
|
9
|
+
namespace Editor.Publish.Callback {
|
|
10
|
+
public interface IBuildAirshipGameBundle : IOrderedCallback {
|
|
11
|
+
/// <summary>
|
|
12
|
+
/// Fired before building asset bundles for game
|
|
13
|
+
/// </summary>
|
|
14
|
+
void OnPreBuildGameBundle(BuildTarget buildTarget);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
[InitializeOnLoad]
|
|
18
|
+
public static class BuildAirshipGameBundleProcessor {
|
|
19
|
+
private static List<IBuildAirshipGameBundle> callbacks;
|
|
20
|
+
|
|
21
|
+
static BuildAirshipGameBundleProcessor() {
|
|
22
|
+
callbacks = GetCallbackInstances();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public static void InvokePreBuildGameBundle(BuildTarget target) {
|
|
26
|
+
foreach (var callback in callbacks) {
|
|
27
|
+
try {
|
|
28
|
+
callback.OnPreBuildGameBundle(target);
|
|
29
|
+
} catch (Exception e) {
|
|
30
|
+
Debug.LogError(e);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/// <summary>
|
|
36
|
+
/// Create instances of each implementation of IBuildAirshipGameBundle
|
|
37
|
+
/// </summary>
|
|
38
|
+
private static List<IBuildAirshipGameBundle> GetCallbackInstances() {
|
|
39
|
+
var instances = new List<IBuildAirshipGameBundle>();
|
|
40
|
+
|
|
41
|
+
var derivedTypes = TypeCache.GetTypesDerivedFrom<IBuildAirshipGameBundle>();
|
|
42
|
+
foreach (var type in derivedTypes) {
|
|
43
|
+
var instance = (IBuildAirshipGameBundle) Activator.CreateInstance(type);
|
|
44
|
+
instances.Add(instance);
|
|
45
|
+
}
|
|
46
|
+
return instances.OrderBy(i => i.callbackOrder).ToList();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
package/Editor/Publish/Deploy.cs
CHANGED
|
@@ -51,21 +51,7 @@ public class Deploy {
|
|
|
51
51
|
// Sort the current platform first to speed up build time
|
|
52
52
|
List<AirshipPlatform> platforms = new();
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
platforms.Add(AirshipPlatform.Windows);
|
|
56
|
-
platforms.Add(AirshipPlatform.Mac);
|
|
57
|
-
#else
|
|
58
|
-
platforms.Add(AirshipPlatform.Windows);
|
|
59
|
-
platforms.Add(AirshipPlatform.Mac);
|
|
60
|
-
#endif
|
|
61
|
-
|
|
62
|
-
var gameConfig = GameConfig.Load();
|
|
63
|
-
if (gameConfig.supportsMobile) {
|
|
64
|
-
platforms.Add(AirshipPlatform.iOS);
|
|
65
|
-
platforms.Add(AirshipPlatform.Android);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
EditorCoroutines.Execute((BuildAndDeploy(platforms.ToArray(), false)));
|
|
54
|
+
EditorCoroutines.Execute(BuildAndDeploy());
|
|
69
55
|
}
|
|
70
56
|
|
|
71
57
|
[MenuItem("Airship/Misc/Build Game Asset Bundle")]
|
|
@@ -86,12 +72,8 @@ public class Deploy {
|
|
|
86
72
|
}
|
|
87
73
|
|
|
88
74
|
[MenuItem("Airship/Publish Game (No Cache)", priority = 51)]
|
|
89
|
-
public static void PublishWithoutCache()
|
|
90
|
-
|
|
91
|
-
// Make sure we generate and write all `NetworkPrefabCollection`s before we
|
|
92
|
-
// build the game.
|
|
93
|
-
// NetworkPrefabManager.WriteAllCollections();
|
|
94
|
-
EditorCoroutines.Execute((BuildAndDeploy(AirshipPlatformUtil.livePlatforms, false, false)));
|
|
75
|
+
public static void PublishWithoutCache() {
|
|
76
|
+
EditorCoroutines.Execute(BuildAndDeploy(false, false));
|
|
95
77
|
}
|
|
96
78
|
|
|
97
79
|
private static string GetDeployKey(DeployAuthType authType) {
|
|
@@ -106,6 +88,28 @@ public class Deploy {
|
|
|
106
88
|
throw new Exception($"[Airship] Unknown auth type: {authType}");
|
|
107
89
|
}
|
|
108
90
|
|
|
91
|
+
/// <summary>
|
|
92
|
+
/// BuildAndDeploy with the target platforms defined in GameConfig. Should only be used in asset deployments
|
|
93
|
+
/// (not code only).
|
|
94
|
+
/// </summary>
|
|
95
|
+
private static IEnumerator BuildAndDeploy(bool skipBuild = false, bool useCache = true, bool dontUpload = false) {
|
|
96
|
+
var platforms = new List<AirshipPlatform>();
|
|
97
|
+
#if UNITY_EDITOR_OSX
|
|
98
|
+
platforms.Add(AirshipPlatform.Windows);
|
|
99
|
+
platforms.Add(AirshipPlatform.Mac);
|
|
100
|
+
#else
|
|
101
|
+
platforms.Add(AirshipPlatform.Windows);
|
|
102
|
+
platforms.Add(AirshipPlatform.Mac);
|
|
103
|
+
#endif
|
|
104
|
+
|
|
105
|
+
var gameConfig = GameConfig.Load();
|
|
106
|
+
if (gameConfig.supportsMobile) {
|
|
107
|
+
platforms.Add(AirshipPlatform.iOS);
|
|
108
|
+
platforms.Add(AirshipPlatform.Android);
|
|
109
|
+
}
|
|
110
|
+
return BuildAndDeploy(platforms.ToArray(), skipBuild, useCache, dontUpload);
|
|
111
|
+
}
|
|
112
|
+
|
|
109
113
|
private static IEnumerator BuildAndDeploy(AirshipPlatform[] platforms, bool skipBuild = false, bool useCache = true, bool dontUpload = false) {
|
|
110
114
|
var possibleKeys = new List<string> { GetDeployKey(DeployAuthType.DeployKey), GetDeployKey(DeployAuthType.EditorAuthToken) };
|
|
111
115
|
possibleKeys.RemoveAll(string.IsNullOrEmpty);
|
|
@@ -345,6 +349,9 @@ public class Deploy {
|
|
|
345
349
|
var success = CreateAssetBundles.BuildPlatforms(platforms, useCache);
|
|
346
350
|
if (!success) {
|
|
347
351
|
Debug.Log("Cancelled publish.");
|
|
352
|
+
|
|
353
|
+
// Switch back to starting build target
|
|
354
|
+
EditorUserBuildSettings.SwitchActiveBuildTarget(startingBuildGroup, startingBuildTarget);
|
|
348
355
|
yield break;
|
|
349
356
|
}
|
|
350
357
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#if UNITY_EDITOR
|
|
2
2
|
using System;
|
|
3
3
|
using UnityEditor;
|
|
4
|
+
using UnityEditor.Build;
|
|
4
5
|
using UnityEngine;
|
|
5
6
|
using UnityEngine.Rendering;
|
|
6
7
|
using UnityEngine.Rendering.Universal;
|
|
@@ -16,7 +17,14 @@ namespace Editor.Quality {
|
|
|
16
17
|
[MenuItem("Airship/Quality/Config Mobile")]
|
|
17
18
|
#endif
|
|
18
19
|
public static void ConfigureLowQualityLevel() {
|
|
19
|
-
|
|
20
|
+
var index = GetOrCreateQualityLevel(LOW_QUALITY_NAME);
|
|
21
|
+
// Switch to it so QualitySettings.* edits apply to the right level
|
|
22
|
+
QualitySettings.SetQualityLevel(index, true);
|
|
23
|
+
ConfigureSupportedPlatforms(index,
|
|
24
|
+
new []{ NamedBuildTarget.Android, NamedBuildTarget.iOS, },
|
|
25
|
+
new []{ NamedBuildTarget.Standalone }
|
|
26
|
+
);
|
|
27
|
+
|
|
20
28
|
ConfigureForLow();
|
|
21
29
|
SaveChangesToQualitySettings();
|
|
22
30
|
}
|
|
@@ -25,11 +33,31 @@ namespace Editor.Quality {
|
|
|
25
33
|
[MenuItem("Airship/Quality/Config Normal")]
|
|
26
34
|
#endif
|
|
27
35
|
public static void ConfigureNormalQualityLevel() {
|
|
28
|
-
|
|
36
|
+
var index = GetOrCreateQualityLevel(NORMAL_QUALITY_NAME);
|
|
37
|
+
// Switch to it so QualitySettings.* edits apply to the right level
|
|
38
|
+
QualitySettings.SetQualityLevel(index, true);
|
|
39
|
+
ConfigureSupportedPlatforms(index,
|
|
40
|
+
new []{ NamedBuildTarget.Standalone },
|
|
41
|
+
new []{ NamedBuildTarget.Android, NamedBuildTarget.iOS, }
|
|
42
|
+
);
|
|
43
|
+
|
|
29
44
|
ConfigureForNormal();
|
|
30
45
|
SaveChangesToQualitySettings();
|
|
31
46
|
}
|
|
32
47
|
|
|
48
|
+
private static void ConfigureSupportedPlatforms(int index, NamedBuildTarget[] included, NamedBuildTarget[] excluded) {
|
|
49
|
+
foreach (var target in included) {
|
|
50
|
+
if (!QualitySettings.TryIncludePlatformAt(target.TargetName, index, out var ex)) {
|
|
51
|
+
Debug.LogError($"Failed to configure included platforms for quality level: {ex}");
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
foreach (var target in excluded) {
|
|
55
|
+
if (!QualitySettings.TryExcludePlatformAt(target.TargetName, index, out var ex)) {
|
|
56
|
+
Debug.LogError($"Failed to configure excluded platforms for quality level: {ex}");
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
33
61
|
private static void ConfigureForLow() {
|
|
34
62
|
// At a value of 1 this reduces the max texture mipmap level to half resolution.
|
|
35
63
|
QualitySettings.globalTextureMipmapLimit = 1;
|
|
@@ -88,21 +116,20 @@ namespace Editor.Quality {
|
|
|
88
116
|
pipeline.shadowCascadeCount = 2;
|
|
89
117
|
pipeline.cascade4Split = new Vector3(0.067f, 0.2f, 0.467f);
|
|
90
118
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
119
|
+
|
|
120
|
+
/// <summary>
|
|
121
|
+
/// Returns the index of the quality level with given name. Will create a new quality level if none
|
|
122
|
+
/// exist with the name.
|
|
123
|
+
/// </summary>
|
|
124
|
+
private static int GetOrCreateQualityLevel(string name) {
|
|
125
|
+
var index = GetQualityIndex(name);
|
|
94
126
|
if (index < 0) {
|
|
95
127
|
if (!TryAddQualityLevel(name, out index)) {
|
|
96
|
-
|
|
97
|
-
return;
|
|
128
|
+
throw new Exception("Failed to create quality level.");
|
|
98
129
|
}
|
|
99
130
|
Debug.Log($"Created quality level '{name}' at index {index}.");
|
|
100
|
-
} else {
|
|
101
|
-
Debug.Log($"Found existing quality level '{name}' at index {index}.");
|
|
102
131
|
}
|
|
103
|
-
|
|
104
|
-
// Switch to it so QualitySettings.* edits apply to the right level
|
|
105
|
-
QualitySettings.SetQualityLevel(index, true);
|
|
132
|
+
return index;
|
|
106
133
|
}
|
|
107
134
|
|
|
108
135
|
private static void SaveChangesToQualitySettings() {
|
|
@@ -38,6 +38,7 @@ public class AirshipSettingsProvider : SettingsProvider
|
|
|
38
38
|
private bool showAutomaticEditorIntegrations = true;
|
|
39
39
|
private bool showLuauOptions = true;
|
|
40
40
|
private bool showNetworkOptions = true;
|
|
41
|
+
private bool showVoxelWorldOptions = false;
|
|
41
42
|
private bool showBetaOptions = false;
|
|
42
43
|
|
|
43
44
|
bool showGithubAccessToken = false;
|
|
@@ -209,6 +210,22 @@ public class AirshipSettingsProvider : SettingsProvider
|
|
|
209
210
|
}
|
|
210
211
|
}
|
|
211
212
|
EditorGUILayout.EndFoldoutHeaderGroup();
|
|
213
|
+
|
|
214
|
+
EditorGUILayout.Space();
|
|
215
|
+
showVoxelWorldOptions = EditorGUILayout.BeginFoldoutHeaderGroup(showVoxelWorldOptions, "Voxel World");
|
|
216
|
+
if (showVoxelWorldOptions) {
|
|
217
|
+
EditorGUILayout.HelpBox("Updating Server View Rendering requires you to restart multiplayer play mode window", MessageType.Warning);
|
|
218
|
+
VoxelWorldEditorConfig.instance.renderVoxelWorldInServerView = EditorGUILayout.Toggle(
|
|
219
|
+
new GUIContent(
|
|
220
|
+
"Server View Rendering",
|
|
221
|
+
"When enabled the Voxel World will be visible in dedicated server view. This is an editor only preference that results in worse performance (but can be useful for debugging)."
|
|
222
|
+
), VoxelWorldEditorConfig.instance.renderVoxelWorldInServerView);
|
|
223
|
+
|
|
224
|
+
if (GUI.changed) {
|
|
225
|
+
VoxelWorldEditorConfig.instance.Modify();
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
EditorGUILayout.EndFoldoutHeaderGroup();
|
|
212
229
|
|
|
213
230
|
// EditorGUILayout.Space();
|
|
214
231
|
// showBetaOptions = EditorGUILayout.BeginFoldoutHeaderGroup(showBetaOptions, "Betas");
|
|
@@ -6,7 +6,7 @@ using UnityEngine.Scripting;
|
|
|
6
6
|
namespace Code {
|
|
7
7
|
[LuauAPI][Preserve]
|
|
8
8
|
public static class AirshipConst {
|
|
9
|
-
public const int playerVersion =
|
|
9
|
+
public const int playerVersion = 21;
|
|
10
10
|
public static readonly IReadOnlyList<string> playerFlags = new string[] {
|
|
11
11
|
"SkipLoading",
|
|
12
12
|
"LagCompCheckIdIsInt",
|
|
@@ -17,6 +17,6 @@ namespace Code {
|
|
|
17
17
|
/// <summary>
|
|
18
18
|
/// The server will kick clients that have a playerVersion lower than this value.
|
|
19
19
|
/// </summary>
|
|
20
|
-
public const int minAcceptedPlayerVersionOnServer =
|
|
20
|
+
public const int minAcceptedPlayerVersionOnServer = 21;
|
|
21
21
|
}
|
|
22
22
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
using Code.Bundles;
|
|
2
|
+
using TMPro;
|
|
3
|
+
using UnityEngine;
|
|
4
|
+
|
|
5
|
+
namespace Code.CoreUI.Components {
|
|
6
|
+
public class AirshipVersionOverlay : MonoBehaviour {
|
|
7
|
+
public TMP_Text versionText;
|
|
8
|
+
|
|
9
|
+
private void Start() {
|
|
10
|
+
#if !AIRSHIP_PLAYER
|
|
11
|
+
if (Application.isEditor) {
|
|
12
|
+
this.versionText.gameObject.SetActive(false);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
#endif
|
|
16
|
+
|
|
17
|
+
var hash = AirshipVersion.GetVersionHash();
|
|
18
|
+
this.versionText.text = Application.version + "-" + hash;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -4,6 +4,7 @@ using System.Runtime.InteropServices;
|
|
|
4
4
|
using Mirror;
|
|
5
5
|
using Code.Util;
|
|
6
6
|
using Code.Zstd;
|
|
7
|
+
using UnityEngine;
|
|
7
8
|
|
|
8
9
|
namespace Assets.Luau {
|
|
9
10
|
[Serializable]
|
|
@@ -100,7 +101,7 @@ namespace Assets.Luau {
|
|
|
100
101
|
NetworkWriterPool.Return(writer);
|
|
101
102
|
NetworkWriterPool.Return(changedByteWriter);
|
|
102
103
|
|
|
103
|
-
// Debug.Log($"Final diff is {bytes.Length} bytes");
|
|
104
|
+
// Debug.Log($"Final diff is {bytes.Length} bytes. Base data was {Data.Length}, new data was {other.Data.Length}. Change bytes: {changeBytes.Length}, Change data: {newByteValues.Length}");
|
|
104
105
|
return bytes;
|
|
105
106
|
}
|
|
106
107
|
|
|
@@ -703,6 +703,9 @@ public partial class LuauCore : MonoBehaviour {
|
|
|
703
703
|
}
|
|
704
704
|
}
|
|
705
705
|
|
|
706
|
+
/// <summary>
|
|
707
|
+
/// Returns field value for a blittable object by directly accessing memory. Won't work for managed types.
|
|
708
|
+
/// </summary>
|
|
706
709
|
private static unsafe T GetFieldValue<T>(object instance, FieldInfo fieldInfo) where T : unmanaged {
|
|
707
710
|
var addr = UnsafeUtility.PinGCObjectAndGetAddress(instance, out ulong handle);
|
|
708
711
|
try {
|
|
@@ -1120,6 +1123,8 @@ public partial class LuauCore : MonoBehaviour {
|
|
|
1120
1123
|
if (cacheData.memberInfo is not FieldInfo fieldInfo) throw new Exception("FastGetAndWriteValueField must be called with FieldInfo.");
|
|
1121
1124
|
|
|
1122
1125
|
var fieldType = cacheData.memberType;
|
|
1126
|
+
// GetFieldValue only works reliably with blittable types
|
|
1127
|
+
if (!UnsafeUtility.IsBlittable(cacheData.objectType)) return false;
|
|
1123
1128
|
|
|
1124
1129
|
if (fieldType == intType) {
|
|
1125
1130
|
var intValue = GetFieldValue<int>(objectReference, fieldInfo);
|
|
@@ -350,13 +350,18 @@ public class GameObjectAPI : BaseLuaAPIClass {
|
|
|
350
350
|
var gameObject = (GameObject)targetObject;
|
|
351
351
|
|
|
352
352
|
Type objectType = LuauCore.CoreInstance.GetTypeFromString(typeName);
|
|
353
|
-
if (objectType == null)
|
|
354
|
-
{
|
|
353
|
+
if (objectType == null) {
|
|
355
354
|
ThreadDataManager.Error(thread);
|
|
356
355
|
Debug.LogError("Error: GetComponentsInChildren component type not found: " + typeName + " (consider registering it?)");
|
|
357
356
|
return 0;
|
|
358
357
|
}
|
|
359
|
-
|
|
358
|
+
|
|
359
|
+
var includeInactive = false;
|
|
360
|
+
if (numParameters >= 2) {
|
|
361
|
+
includeInactive = LuauCore.GetParameterAsBool(1, numParameters, parameterDataPODTypes, parameterDataPtrs, parameterDataSizes, out _);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
var results = gameObject.GetComponentsInChildren(objectType, includeInactive);
|
|
360
365
|
LuauCore.WritePropertyToThread(thread, results, typeof(Component[]));
|
|
361
366
|
return 1;
|
|
362
367
|
}
|
|
@@ -380,7 +385,13 @@ public class GameObjectAPI : BaseLuaAPIClass {
|
|
|
380
385
|
Debug.LogError("Error: GetComponentsInParent component type not found: " + typeName + " (consider registering it?)");
|
|
381
386
|
return 0;
|
|
382
387
|
}
|
|
383
|
-
|
|
388
|
+
|
|
389
|
+
var includeInactive = false;
|
|
390
|
+
if (numParameters >= 2) {
|
|
391
|
+
includeInactive = LuauCore.GetParameterAsBool(1, numParameters, parameterDataPODTypes, parameterDataPtrs, parameterDataSizes, out _);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
var results = gameObject.GetComponentsInParent(objectType, includeInactive);
|
|
384
395
|
LuauCore.WritePropertyToThread(thread, results, typeof(Component[]));
|
|
385
396
|
return 1;
|
|
386
397
|
}
|
|
@@ -135,7 +135,13 @@ public class TransformAPI : BaseLuaAPIClass {
|
|
|
135
135
|
Debug.LogError("Error: GetComponentsInChildren component type not found: " + typeName + " (consider registering it?)");
|
|
136
136
|
return 0;
|
|
137
137
|
}
|
|
138
|
-
|
|
138
|
+
|
|
139
|
+
var includeInactive = false;
|
|
140
|
+
if (numParameters >= 2) {
|
|
141
|
+
includeInactive = LuauCore.GetParameterAsBool(1, numParameters, parameterDataPODTypes, parameterDataPtrs, parameterDataSizes, out _);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
var results = t.GetComponentsInChildren(objectType, includeInactive);
|
|
139
145
|
LuauCore.WritePropertyToThread(thread, results, typeof(Component[]));
|
|
140
146
|
return 1;
|
|
141
147
|
}
|
|
@@ -156,7 +162,13 @@ public class TransformAPI : BaseLuaAPIClass {
|
|
|
156
162
|
Debug.LogError("Error: GetComponentsInParent component type not found: " + typeName + " (consider registering it?)");
|
|
157
163
|
return 0;
|
|
158
164
|
}
|
|
159
|
-
|
|
165
|
+
|
|
166
|
+
var includeInactive = false;
|
|
167
|
+
if (numParameters >= 2) {
|
|
168
|
+
includeInactive = LuauCore.GetParameterAsBool(1, numParameters, parameterDataPODTypes, parameterDataPtrs, parameterDataSizes, out _);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
var results = t.GetComponentsInParent(objectType, includeInactive);
|
|
160
172
|
LuauCore.WritePropertyToThread(thread, results, typeof(Component[]));
|
|
161
173
|
return 1;
|
|
162
174
|
}
|
|
@@ -52,7 +52,15 @@ public class LuauHelper : Singleton<LuauHelper> {
|
|
|
52
52
|
private void SetupUnityAPIClasses() {
|
|
53
53
|
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
|
54
54
|
foreach (var assembly in assemblies) {
|
|
55
|
-
|
|
55
|
+
var validAssembly = false;
|
|
56
|
+
foreach (var refName in assembly.GetReferencedAssemblies()) {
|
|
57
|
+
if (refName.Name == "LuauAPI") {
|
|
58
|
+
validAssembly = true;
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (!validAssembly) {
|
|
56
64
|
continue;
|
|
57
65
|
}
|
|
58
66
|
|
|
@@ -78,9 +78,7 @@ namespace Code.Network.Simulation
|
|
|
78
78
|
|
|
79
79
|
private void LagCompensationCheck(int clientId, int tick, double time, double latency, double bufferTime)
|
|
80
80
|
{
|
|
81
|
-
var
|
|
82
|
-
|
|
83
|
-
var totalBuffer = (latency * 2) + bufferTime + commandBufferTime;
|
|
81
|
+
var totalBuffer = (latency * 2) + bufferTime;
|
|
84
82
|
var lagCompensatedTime = time - (totalBuffer + bufferAdjustment);
|
|
85
83
|
var lagCompensatedTick = AirshipSimulationManager.Instance.GetNearestTickForUnscaledTime(lagCompensatedTime);
|
|
86
84
|
this.SetSnapshot(lagCompensatedTick);
|
|
@@ -205,13 +205,7 @@ namespace Code.Network.Simulation
|
|
|
205
205
|
|
|
206
206
|
// Only resimulate once. Go back to the farthest back time that was requested.
|
|
207
207
|
if (resimBackTo != tick) this.PerformResimulation(resimBackTo);
|
|
208
|
-
|
|
209
|
-
// Perform the standard tick behavior
|
|
210
|
-
OnTick?.Invoke(tick, time, false);
|
|
211
|
-
// Debug.Log($"Simulate call. Main tick {tick}");
|
|
212
|
-
Physics.Simulate(Time.fixedDeltaTime);
|
|
213
|
-
OnCaptureSnapshot?.Invoke(tick, time, false);
|
|
214
|
-
|
|
208
|
+
|
|
215
209
|
// Process any lag compensation requests now that we have completed the ticking and snapshot creation
|
|
216
210
|
// Note: This process is placed after snapshot processing so that changes made to physics (like an impulse)
|
|
217
211
|
// are processed on the _next_ tick. This is safe because the server never resimulates.
|
|
@@ -224,7 +218,7 @@ namespace Code.Network.Simulation
|
|
|
224
218
|
// Debug.LogWarning("Server lag compensation rolling back for client " + entry.Key.connectionId);
|
|
225
219
|
// commandBufferTime is the additional time we queue commands locally on the server before processing them
|
|
226
220
|
var commandBufferTime = (NetworkServer.sendInterval * (entry.Key.bufferTimeMultiplier / 2f));
|
|
227
|
-
OnLagCompensationCheck?.Invoke(entry.Key.connectionId,
|
|
221
|
+
OnLagCompensationCheck?.Invoke(entry.Key.connectionId, previousTicks[^1], previousTimes[^1], entry.Key.rtt / 2f, entry.Key.bufferTime + commandBufferTime);
|
|
228
222
|
|
|
229
223
|
var requests = entry.Value;
|
|
230
224
|
for (var i = 0; i < requests.Count; i++) {
|
|
@@ -240,9 +234,10 @@ namespace Code.Network.Simulation
|
|
|
240
234
|
// If we processed lag compensation, we have some additional work to do
|
|
241
235
|
if (processedLagCompensation)
|
|
242
236
|
{
|
|
243
|
-
// Debug.LogWarning("Server completed " + this.lagCompensationRequests.Count + " lag compensation requests. Resetting to current tick (" +
|
|
237
|
+
// Debug.LogWarning("Server completed " + this.lagCompensationRequests.Count + " lag compensation requests. Resetting to current tick (" + previousTimes[^1] + ") and finalizing.");
|
|
244
238
|
// Reset back to the server view of the world at the current time.
|
|
245
|
-
OnSetSnapshot?.Invoke(
|
|
239
|
+
OnSetSnapshot?.Invoke(previousTicks[^1]);
|
|
240
|
+
Physics.SyncTransforms();
|
|
246
241
|
// Invoke all of the callbacks for modifying physics that should be applied in the next tick.
|
|
247
242
|
foreach (var entry in this.lagCompensationRequests)
|
|
248
243
|
{
|
|
@@ -261,6 +256,12 @@ namespace Code.Network.Simulation
|
|
|
261
256
|
this.lagCompensationRequests.Clear();
|
|
262
257
|
}
|
|
263
258
|
|
|
259
|
+
// Perform the standard tick behavior
|
|
260
|
+
OnTick?.Invoke(tick, time, false);
|
|
261
|
+
// Debug.Log($"Simulate call. Main tick {tick}");
|
|
262
|
+
Physics.Simulate(Time.fixedDeltaTime);
|
|
263
|
+
OnCaptureSnapshot?.Invoke(tick, time, false);
|
|
264
|
+
|
|
264
265
|
// Add our completed tick time into our history
|
|
265
266
|
this.previousTicks.Add(tick);
|
|
266
267
|
this.previousTimes.Add(time);
|
|
@@ -210,7 +210,7 @@ namespace Code.Network.Simulation
|
|
|
210
210
|
*/
|
|
211
211
|
public T[] GetAllAfter(int tick)
|
|
212
212
|
{
|
|
213
|
-
if (this.history.Keys.Count == 0 || tick
|
|
213
|
+
if (this.history.Keys.Count == 0 || tick >= this.history.Keys[^1])
|
|
214
214
|
{
|
|
215
215
|
return new T[] {};
|
|
216
216
|
}
|
|
@@ -219,7 +219,7 @@ namespace Code.Network.Simulation
|
|
|
219
219
|
// Iterate in reverse since our return values will likely include the end
|
|
220
220
|
for (var i = this.history.Count - 1; i >= 0; i--)
|
|
221
221
|
{
|
|
222
|
-
if (this.history.Keys[i]
|
|
222
|
+
if (this.history.Keys[i] <= tick)
|
|
223
223
|
{
|
|
224
224
|
after.Reverse();
|
|
225
225
|
return after.ToArray();
|
|
@@ -270,4 +270,4 @@ namespace Code.Network.Simulation
|
|
|
270
270
|
}
|
|
271
271
|
}
|
|
272
272
|
}
|
|
273
|
-
}
|
|
273
|
+
}
|
|
@@ -54,8 +54,10 @@ namespace Code.Network.StateSystem
|
|
|
54
54
|
|
|
55
55
|
private double lastServerSend = 0;
|
|
56
56
|
|
|
57
|
-
// The local
|
|
57
|
+
// The local tick of the most recent data that was sent to the server.
|
|
58
58
|
private int clientLastSentLocalTick = 0;
|
|
59
|
+
// The local tick of the last data that was sent the the server a second time.
|
|
60
|
+
private int clientLastResentLocalTick = 0;
|
|
59
61
|
|
|
60
62
|
// Server processing for commands
|
|
61
63
|
private Input lastProcessedCommand;
|
|
@@ -126,10 +128,10 @@ namespace Code.Network.StateSystem
|
|
|
126
128
|
protected Action<Diff> OnClientReceiveDiff;
|
|
127
129
|
protected Action<int> OnServerReceiveFullSnapshotRequest;
|
|
128
130
|
protected Action<State> OnServerReceiveSnapshot;
|
|
129
|
-
protected Action<Input> OnServerReceiveInput;
|
|
131
|
+
protected Action<Input[]> OnServerReceiveInput;
|
|
130
132
|
|
|
131
133
|
// Functions to be implemented by subclass that perform networking actions
|
|
132
|
-
public abstract void SendClientInputToServer(Input input);
|
|
134
|
+
public abstract void SendClientInputToServer(Input[] input);
|
|
133
135
|
public abstract void SendClientSnapshotToServer(State snapshot);
|
|
134
136
|
|
|
135
137
|
/// <summary>
|
|
@@ -253,27 +255,27 @@ namespace Code.Network.StateSystem
|
|
|
253
255
|
// We will sometimes resend unconfirmed commands. The server should ignore these if
|
|
254
256
|
// it has them already.
|
|
255
257
|
var commands =
|
|
256
|
-
this.inputHistory.GetAllAfter((int)Math.Max(0,
|
|
257
|
-
(clientLastSentLocalTick - (NetworkClient.sendInterval / Time.fixedUnscaledDeltaTime))));
|
|
258
|
+
this.inputHistory.GetAllAfter((int)Math.Max(0,clientLastResentLocalTick)); // Send all inputs that haven't been sent as well as ones that have been sent only once
|
|
258
259
|
if (commands.Length > 0) {
|
|
259
|
-
this.
|
|
260
|
+
this.clientLastResentLocalTick = this.clientLastSentLocalTick; // Store the last tick that was resent
|
|
261
|
+
this.clientLastSentLocalTick = this.inputHistory.Keys[^1]; // Store which tick was sent
|
|
262
|
+
this.SendClientInputToServer(commands);
|
|
260
263
|
}
|
|
261
264
|
|
|
262
265
|
// print($"Sending {commands.Length} cmds to the server");
|
|
263
266
|
|
|
264
|
-
// We make multiple calls so that Mirror can batch the commands efficiently.
|
|
265
|
-
foreach (var command in commands) {
|
|
266
|
-
|
|
267
|
-
}
|
|
267
|
+
// // We make multiple calls so that Mirror can batch the commands efficiently.
|
|
268
|
+
// foreach (var command in commands) {
|
|
269
|
+
// this.SendClientInputToServer(command);
|
|
270
|
+
// }
|
|
268
271
|
}
|
|
269
272
|
|
|
270
273
|
// We are an authoritative client and should send our latest state
|
|
271
274
|
if (isClient && isOwned && !serverAuth) {
|
|
272
275
|
if (this.stateHistory.Keys.Count == 0) return;
|
|
273
|
-
var states = this.stateHistory.GetAllAfter((int)Math.Max(0,
|
|
274
|
-
(NetworkClient.sendInterval /
|
|
275
|
-
Time.fixedUnscaledDeltaTime))));
|
|
276
|
+
var states = this.stateHistory.GetAllAfter((int)Math.Max(0, clientLastResentLocalTick));
|
|
276
277
|
if (states.Length > 0) {
|
|
278
|
+
this.clientLastResentLocalTick = this.clientLastSentLocalTick;
|
|
277
279
|
this.clientLastSentLocalTick = this.stateHistory.Keys[^1];
|
|
278
280
|
}
|
|
279
281
|
|
|
@@ -1218,9 +1220,13 @@ namespace Code.Network.StateSystem
|
|
|
1218
1220
|
this.serverCommandBuffer.Add(command.commandNumber, command);
|
|
1219
1221
|
}
|
|
1220
1222
|
|
|
1221
|
-
private void ServerReceiveInputCommand(Input
|
|
1223
|
+
private void ServerReceiveInputCommand(Input[] commands)
|
|
1222
1224
|
{
|
|
1223
|
-
|
|
1225
|
+
foreach (var command in commands)
|
|
1226
|
+
{
|
|
1227
|
+
ProcessClientInputOnServer(command);
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1224
1230
|
}
|
|
1225
1231
|
|
|
1226
1232
|
private void ServerReceiveSnapshot(State snapshot)
|