gg.easy.airship 0.1.2167 → 0.1.2168

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.
@@ -158,7 +158,7 @@ namespace Editor.AirAsset {
158
158
  var buildOutputFile = $"bundles/airassetbundle/{airId}_{AirshipPlatformUtil.GetStringName(platform)}.bundle";
159
159
  var sourceFolderPath = Path.GetRelativePath(".", Directory.GetParent(AssetDatabase.GetAssetPath(airAssetBundle))!.FullName);
160
160
 
161
- List<AssetBundleBuild> builds = CreateAssetBundles.GetPackageAssetBundleBuilds();
161
+ List<AssetBundleBuild> builds = CreateAssetBundles.GetPackageAssetBundleBuilds(false);
162
162
 
163
163
  var assetGuids = AssetDatabase.FindAssets("*", new string[] {sourceFolderPath}).ToList();
164
164
  var assetPaths = assetGuids
@@ -173,7 +173,7 @@ public static class CreateAssetBundles {
173
173
  /// Creates an AssetBundleBuild for every AirshipPackage in the project.
174
174
  /// </summary>
175
175
  /// <returns></returns>
176
- public static List<AssetBundleBuild> GetPackageAssetBundleBuilds() {
176
+ public static List<AssetBundleBuild> GetPackageAssetBundleBuilds(bool compileURPShaders) {
177
177
  List<AssetBundleBuild> builds = new();
178
178
 
179
179
  if (!Directory.Exists(Path.Join("Assets", "AirshipPackages"))) {
@@ -197,7 +197,7 @@ public static class CreateAssetBundles {
197
197
  assetGuids.AddRange(urpGuids);
198
198
  });
199
199
 
200
- if (!EditorIntegrationsConfig.instance.selfCompileAllShaders) {
200
+ if (!compileURPShaders) {
201
201
  Debug.Log("Adding URP assets to CoreMaterials bundle.");
202
202
  addUrpFiles("Packages/com.unity.render-pipelines.universal/Shaders");
203
203
  addUrpFiles("Packages/com.unity.render-pipelines.universal/ShaderLibrary");
@@ -297,7 +297,7 @@ public static class CreateAssetBundles {
297
297
  // Act as if we are building all asset bundles (including CoreMaterials).
298
298
  // This is so our current build target will have references to those asset bundles.
299
299
  // This is paired with changes to Scriptable Build Pipeline that prevent these bundles from actually being built.
300
- List<AssetBundleBuild> builds = GetPackageAssetBundleBuilds();
300
+ List<AssetBundleBuild> builds = GetPackageAssetBundleBuilds(gameConfig.compileURPShaders);
301
301
 
302
302
  // Make a fake asset bundle with all package content. This makes the build have the correct dependency data.
303
303
  // {
@@ -39,8 +39,6 @@ public class EditorIntegrationsConfig : ScriptableSingleton<EditorIntegrationsCo
39
39
  [SerializeField]
40
40
  public bool safeguardBundleModification = true;
41
41
 
42
- [SerializeField] public bool selfCompileAllShaders = false;
43
-
44
42
  [SerializeField] internal bool useProjectReconcileOption = false;
45
43
  [FormerlySerializedAs("reconcilerVersion")] [SerializeField] internal ReconcilerVersion projectReconcilerVersion = ReconcilerVersion.Default;
46
44
 
@@ -18,6 +18,7 @@ public class GameConfigEditor : UnityEditor.Editor {
18
18
  private Action requestRefresh;
19
19
 
20
20
  private SerializedProperty supportsMobile;
21
+ private SerializedProperty compileURPShaders;
21
22
 
22
23
  Rect buttonRect;
23
24
  public override void OnInspectorGUI() {
@@ -51,6 +52,12 @@ public class GameConfigEditor : UnityEditor.Editor {
51
52
  EditorGUILayout.PropertyField(this.supportsMobile, new GUIContent("Mobile"));
52
53
  GUILayout.Space(20);
53
54
 
55
+ EditorGUILayout.LabelField("Shaders", EditorStyles.boldLabel);
56
+ EditorGUILayout.PropertyField(this.compileURPShaders, new GUIContent("Compile URP Shaders") {
57
+ tooltip = "By default, your game will use a precompiled set of URP shaders for basic usage. Checking this box will compile URP shaders specifically for your game. If you have any advanced URP materials (or notice invisible materials on published games), you should check this box."
58
+ });
59
+ GUILayout.Space(20);
60
+
54
61
  foreach (var field in typeof(GameConfig).GetFields()) {
55
62
  if (field.Name is "gameId" or "gameLayers" || Attribute.IsDefined(field, typeof(HideInInspector))) continue; // Rendered above
56
63
 
@@ -107,6 +114,7 @@ public class GameConfigEditor : UnityEditor.Editor {
107
114
  }
108
115
 
109
116
  this.supportsMobile = serializedObject.FindProperty("supportsMobile");
117
+ this.compileURPShaders = serializedObject.FindProperty("compileURPShaders");
110
118
 
111
119
  updateSelectedGame += (update) => {
112
120
  var gameId = update.gameId;
@@ -416,7 +416,7 @@ namespace Editor.Packages {
416
416
  // Act as if we are building all asset bundles (including CoreMaterials).
417
417
  // This is so our current build target will have references to those asset bundles.
418
418
  // This is paired with changes to Scriptable Build Pipeline that prevent these bundles from actually being built.
419
- List<AssetBundleBuild> builds = CreateAssetBundles.GetPackageAssetBundleBuilds();
419
+ List<AssetBundleBuild> builds = CreateAssetBundles.GetPackageAssetBundleBuilds(true);
420
420
 
421
421
  foreach (var platform in platforms) {
422
422
  var st = Stopwatch.StartNew();
@@ -153,8 +153,7 @@ public class AirshipSettingsProvider : SettingsProvider
153
153
  EditorIntegrationsConfig.instance.autoUpdatePackages = EditorGUILayout.Toggle(new GUIContent("Auto Update Packages", "Airship Packages will automatically update whenever a new update is available."), EditorIntegrationsConfig.instance.autoUpdatePackages);
154
154
  EditorIntegrationsConfig.instance.enableMainMenu = EditorGUILayout.Toggle(new GUIContent("Enable Main Menu", "When true, the main menu will show when pressing [Escape]."), EditorIntegrationsConfig.instance.enableMainMenu);
155
155
  EditorIntegrationsConfig.instance.buildWithoutUpload = EditorGUILayout.Toggle(new GUIContent("Build Without Upload", "When publishing, this will build the asset bundles but won't upload them to Airship. This is useful for testing file sizes with AssetBundle Browser."), EditorIntegrationsConfig.instance.buildWithoutUpload);
156
- EditorIntegrationsConfig.instance.selfCompileAllShaders = EditorGUILayout.Toggle(new GUIContent("Self Compile All Shaders", "Instead of using pre-compiled shaders from CoreMaterials, you will compile all needed URP shaders when publishing. This makes publishing take significantly longer but reduces shader stripping issues."), EditorIntegrationsConfig.instance.selfCompileAllShaders);
157
-
156
+
158
157
  // EditorIntegrationsConfig.instance.manageTypescriptProject = EditorGUILayout.Toggle(new GUIContent("Manage Typescript Projects", "Automatically update Typescript configuration files. (package.json, tsconfig.json)"), EditorIntegrationsConfig.instance.manageTypescriptProject);
159
158
 
160
159
  // EditorIntegrationsConfig.instance.typescriptAutostartCompiler = EditorGUILayout.Toggle(
@@ -6,6 +6,7 @@ using Code.GameBundle;
6
6
  using UnityEditor;
7
7
  #endif
8
8
  using UnityEngine;
9
+ using UnityEngine.Serialization;
9
10
  using Object = UnityEngine.Object;
10
11
 
11
12
  [CreateAssetMenu(fileName = "GameConfig", menuName = "Airship/GameConfig", order = 100)]
@@ -38,6 +39,8 @@ public class GameConfig : ScriptableObject
38
39
 
39
40
  [HideInInspector] public bool supportsMobile;
40
41
 
42
+ [HideInInspector] public bool compileURPShaders = false;
43
+
41
44
  private const string TagPrefix = "AirshipTag";
42
45
  public const int MaximumTags = 64;
43
46
 
@@ -0,0 +1,17 @@
1
+ namespace Luau {
2
+ /// <summary>
3
+ /// Represents a Luau buffer value. Any C# method that takes LuauBuffer as a parameter
4
+ /// will automatically accept "buffer" types from Luau. Similarly, any C# method that
5
+ /// returns a LuauBuffer will return a buffer type to Luau.
6
+ /// </summary>
7
+ public struct LuauBuffer {
8
+ public readonly byte[] Data;
9
+
10
+ public LuauBuffer(byte[] data) {
11
+ Data = data;
12
+ }
13
+
14
+ public static implicit operator byte[](LuauBuffer buffer) => buffer.Data;
15
+ public static implicit operator LuauBuffer(byte[] data) => new (data);
16
+ }
17
+ }
@@ -0,0 +1,3 @@
1
+ fileFormatVersion: 2
2
+ guid: e4fff37edb924b9885f68d18cf643b6a
3
+ timeCreated: 1754634257
@@ -44,6 +44,7 @@ public partial class LuauCore : MonoBehaviour {
44
44
  POD_VECTOR4 = 15,
45
45
  POD_FLOAT = 16,
46
46
  POD_AIRSHIP_COMPONENT = 17,
47
+ POD_BUFFER = 18,
47
48
  };
48
49
 
49
50
  private static bool s_shutdown = false;
@@ -80,6 +81,7 @@ public partial class LuauCore : MonoBehaviour {
80
81
  private static Type planeType = typeof(UnityEngine.Plane);
81
82
  private static Type colorType = typeof(UnityEngine.Color);
82
83
  private static Type binaryBlobType = typeof(Assets.Luau.BinaryBlob);
84
+ private static Type luauBufferType = typeof(LuauBuffer);
83
85
  private static Type actionType = typeof(Action);
84
86
 
85
87
  private static readonly string[] protectedScenesNames = {
@@ -639,6 +639,19 @@ public partial class LuauCore : MonoBehaviour {
639
639
  }
640
640
  break;
641
641
  }
642
+
643
+ case PODTYPE.POD_BUFFER: {
644
+ if (t.IsAssignableFrom(luauBufferType)) {
645
+ if (field != null) {
646
+ field.SetValue(objectReference, NewLuauBufferFromPointer(propertyData, propertyDataSize));
647
+ } else {
648
+ SetValue<LuauBuffer>(objectReference, NewLuauBufferFromPointer(propertyData, propertyDataSize), property);
649
+ }
650
+
651
+ return 0;
652
+ }
653
+ break;
654
+ }
642
655
  }
643
656
  }
644
657
 
@@ -471,6 +471,14 @@ public partial class LuauCore : MonoBehaviour
471
471
  WritePropertyToThreadInt32(thread, (int) value);
472
472
  return true;
473
473
  }
474
+
475
+ if (t == luauBufferType) {
476
+ var buf = (LuauBuffer)value;
477
+ fixed (byte* bytesPtr = buf.Data) {
478
+ LuauPlugin.LuauPushValueToThread(thread, (int)PODTYPE.POD_BUFFER, new IntPtr(bytesPtr), buf.Data.Length);
479
+ }
480
+ return true;
481
+ }
474
482
 
475
483
  if (t.IsEnum) {
476
484
  System.Int32 integer = (System.Int32)value;
@@ -1011,6 +1019,10 @@ public partial class LuauCore : MonoBehaviour
1011
1019
  parsedData[paramIndex] = NewMatrixFromPointer(intPtrs[i]);
1012
1020
  continue;
1013
1021
  }
1022
+ case PODTYPE.POD_BUFFER: {
1023
+ parsedData[paramIndex] = NewLuauBufferFromPointer(intPtrs[i], sizes[i]);
1024
+ continue;
1025
+ }
1014
1026
  }
1015
1027
 
1016
1028
  Debug.LogError("Param " + paramIndex + " " + podTypes[i] + " not valid type for this parameter/unhandled so far.");
@@ -1373,6 +1385,11 @@ public partial class LuauCore : MonoBehaviour
1373
1385
  continue;
1374
1386
  }
1375
1387
  break;
1388
+ case PODTYPE.POD_BUFFER:
1389
+ if (sourceParamType.IsAssignableFrom(luauBufferType)) {
1390
+ continue;
1391
+ }
1392
+ break;
1376
1393
  }
1377
1394
  return false;
1378
1395
  }
@@ -1563,6 +1580,12 @@ public partial class LuauCore : MonoBehaviour
1563
1580
  return 16 * sizeof(float);
1564
1581
  }
1565
1582
 
1583
+ public static LuauBuffer NewLuauBufferFromPointer(IntPtr data, int size) {
1584
+ var bytes = new byte[size];
1585
+ Marshal.Copy(data, bytes, 0, size);
1586
+ return new LuauBuffer(bytes);
1587
+ }
1588
+
1566
1589
  public static Plane NewPlaneFromPointer(IntPtr data) {
1567
1590
  Marshal.Copy(data, VectorData, 0, 4);
1568
1591
  return new Plane(new Vector3(VectorData[0], VectorData[1], VectorData[2]), VectorData[3]);
@@ -3,19 +3,16 @@ using Code.Player.Character.MovementSystems.Character;
3
3
  using Mirror;
4
4
  using UnityEngine;
5
5
 
6
- namespace Code.Player.Character.NetworkedMovement
7
- {
6
+ namespace Code.Player.Character.NetworkedMovement {
8
7
  [LuauAPI]
9
- public class CharacterAnimationHelper : MonoBehaviour
10
- {
11
- public enum CharacterAnimationLayer
12
- {
8
+ public class CharacterAnimationHelper : MonoBehaviour {
9
+ public enum CharacterAnimationLayer {
13
10
  OVERRIDE_1 = 1,
14
11
  OVERRIDE_2 = 2,
15
12
  OVERRIDE_3 = 3,
16
13
  OVERRIDE_4 = 4,
17
14
  UPPER_BODY_1 = 5,
18
- UPPER_BODY_2 = 6,
15
+ UPPER_BODY_2 = 6
19
16
  }
20
17
 
21
18
  [Header("References")]
@@ -39,6 +36,7 @@ namespace Code.Player.Character.NetworkedMovement
39
36
 
40
37
  [Header("Animation Calibration")]
41
38
  public float animWalkSpeed = 4.4444445f;
39
+
42
40
  public float animRunSpeed = 6.6666667f;
43
41
  public float animCrouchSpeed = 2.1233335f;
44
42
 
@@ -59,27 +57,22 @@ namespace Code.Player.Character.NetworkedMovement
59
57
 
60
58
  private void Awake() {
61
59
  // Make a new instance of the animator override controller
62
- if (!this.animatorOverride)
63
- {
64
- if (this.animator.runtimeAnimatorController is AnimatorOverrideController over)
65
- {
60
+ if (!animatorOverride) {
61
+ if (animator.runtimeAnimatorController is AnimatorOverrideController over) {
66
62
  // Copy all the overrides if we already have an override controller in use
67
63
  var overrides = new List<KeyValuePair<AnimationClip, AnimationClip>>(over.overridesCount);
68
64
  over.GetOverrides(overrides);
69
- this.animatorOverride = new AnimatorOverrideController(animator.runtimeAnimatorController);
70
- this.animator.runtimeAnimatorController = this.animatorOverride;
71
- this.animatorOverride.ApplyOverrides(overrides);
72
- }
73
- else if (animator.runtimeAnimatorController)
74
- {
75
- this.animatorOverride = new AnimatorOverrideController(animator.runtimeAnimatorController);
76
- this.animator.runtimeAnimatorController = this.animatorOverride;
65
+ animatorOverride = new AnimatorOverrideController(animator.runtimeAnimatorController);
66
+ animator.runtimeAnimatorController = animatorOverride;
67
+ animatorOverride.ApplyOverrides(overrides);
68
+ } else if (animator.runtimeAnimatorController) {
69
+ animatorOverride = new AnimatorOverrideController(animator.runtimeAnimatorController);
70
+ animator.runtimeAnimatorController = animatorOverride;
77
71
  }
78
72
  }
79
73
  }
80
74
 
81
- private void Start()
82
- {
75
+ private void Start() {
83
76
  // AnimatorOverrideController animatorOverrideController =
84
77
  // new AnimatorOverrideController(this.animator.runtimeAnimatorController);
85
78
  // this.animator.runtimeAnimatorController = animatorOverrideController;
@@ -89,63 +82,51 @@ namespace Code.Player.Character.NetworkedMovement
89
82
  animator.SetFloat("AnimationOffset", offset);
90
83
  }
91
84
 
92
- public void SetFirstPerson(bool firstPerson)
93
- {
85
+ public void SetFirstPerson(bool firstPerson) {
94
86
  this.firstPerson = firstPerson;
95
- if (this.firstPerson)
96
- {
87
+ if (this.firstPerson) {
97
88
  animator.SetLayerWeight(0, 0);
98
- }
99
- else
100
- {
89
+ } else {
101
90
  animator.SetLayerWeight(0, 1);
102
- this.SetState(new() { state = this.currentState });
91
+ SetState(new CharacterAnimationSyncData { state = currentState });
103
92
  }
104
93
  }
105
94
 
106
- private void LateUpdate()
107
- {
95
+ private void LateUpdate() {
108
96
  UpdateAnimationState();
109
97
  }
110
98
 
111
- private void OnEnable()
112
- {
113
- this.animator.Rebind();
99
+ private void OnEnable() {
100
+ animator.Rebind();
114
101
  GetRandomReactionLength();
115
102
 
116
103
  //Enter default state
117
104
  SetState(new CharacterAnimationSyncData());
118
105
  }
119
106
 
120
- public bool IsInParticleDistance()
121
- {
107
+ public bool IsInParticleDistance() {
122
108
  return true;
123
109
  }
124
110
 
125
- private void UpdateAnimationState()
126
- {
127
- if (!enabled || !this.gameObject.activeInHierarchy)
128
- {
111
+ private void UpdateAnimationState() {
112
+ if (!enabled || !gameObject.activeInHierarchy) {
129
113
  return;
130
114
  }
131
115
 
132
116
  //Don't vary animation speeds if we are in the air or not moving
133
- if (currentState == CharacterState.Airborne)
134
- {
117
+ if (currentState == CharacterState.Airborne) {
135
118
  targetPlaybackSpeed = 1;
136
- }
137
- else if ((currentState == CharacterState.Crouching && targetPlaybackSpeed < .1) ||
138
- targetPlaybackSpeed < .03)
139
- {
119
+ } else if ((currentState == CharacterState.Crouching && targetPlaybackSpeed < .1) ||
120
+ targetPlaybackSpeed < .03) {
140
121
  targetVelNormalized = Vector2.zero;
141
122
  targetPlaybackSpeed = 1;
142
123
  }
143
124
 
144
- float currentMagnitude = currentVelNormalized.magnitude;
145
- float targetMagnitude = targetVelNormalized.magnitude;
146
- float blendMod = targetMagnitude > currentMagnitude
147
- ? this.directionalBlendLerpMod
148
- : this.directionalBlendLerpMod / 2f;
125
+ var currentMagnitude = currentVelNormalized.magnitude;
126
+ var targetMagnitude = targetVelNormalized.magnitude;
127
+ var blendMod = targetMagnitude > currentMagnitude
128
+ ? directionalBlendLerpMod
129
+ : directionalBlendLerpMod / 2f;
149
130
 
150
131
  //RUNNING SPEED
151
132
  //Speed up animations based on actual speed vs target speed
@@ -153,31 +134,28 @@ namespace Code.Player.Character.NetworkedMovement
153
134
  animator.SetFloat("MovementPlaybackSpeed", currentPlaybackSpeed);
154
135
 
155
136
  //Blend directional influence
156
- float smoothXVelocity = 0f;
157
- float smoothYVelocity = 0f;
158
- float smoothTime = 0.025f;
137
+ var smoothXVelocity = 0f;
138
+ var smoothYVelocity = 0f;
139
+ var smoothTime = 0.025f;
159
140
 
160
141
  currentVelNormalized.x = Mathf.SmoothDamp(currentVelNormalized.x, targetVelNormalized.x,
161
142
  ref smoothXVelocity, smoothTime, Mathf.Infinity, Time.deltaTime);
162
143
  currentVelNormalized.y = Mathf.SmoothDamp(currentVelNormalized.y, targetVelNormalized.y,
163
144
  ref smoothYVelocity, smoothTime, Mathf.Infinity, Time.deltaTime);
164
- float velX = Mathf.Abs(currentVelNormalized.x) < 0.01f ? 0 : currentVelNormalized.x;
165
- float velZ = Mathf.Abs(currentVelNormalized.y) < 0.01f ? 0 : currentVelNormalized.y;
145
+ var velX = Mathf.Abs(currentVelNormalized.x) < 0.01f ? 0 : currentVelNormalized.x;
146
+ var velZ = Mathf.Abs(currentVelNormalized.y) < 0.01f ? 0 : currentVelNormalized.y;
166
147
  animator.SetFloat("VelX", velX);
167
148
  animator.SetFloat("VelY", Mathf.Lerp(animator.GetFloat("VelY"), verticalVel, Time.deltaTime * 1.5f));
168
149
  animator.SetFloat("VelZ", velZ);
169
150
  animator.SetFloat("Speed", targetMagnitude);
170
151
 
171
152
 
172
- if (grounded)
173
- {
153
+ if (grounded) {
174
154
  lastGroundedTime = Time.time;
175
155
  isSkidding = currentSpeed >= skiddingSpeed;
176
156
  animator.SetBool("Skidding", isSkidding);
177
157
  animator.SetBool("Airborne", false);
178
- }
179
- else
180
- {
158
+ } else {
181
159
  animator.SetBool("Skidding", false);
182
160
  animator.SetBool("Airborne", Time.time - lastGroundedTime > minAirborneTime);
183
161
  }
@@ -196,65 +174,59 @@ namespace Code.Player.Character.NetworkedMovement
196
174
  // }
197
175
  }
198
176
 
199
- private void GetRandomReactionLength()
200
- {
201
- nextIdleReactionLength = this.idleRectionLength +
202
- Random.Range(-this.idleRectionLength / 2, this.idleRectionLength / 2);
177
+ private void GetRandomReactionLength() {
178
+ nextIdleReactionLength = idleRectionLength +
179
+ Random.Range(-idleRectionLength / 2, idleRectionLength / 2);
203
180
  }
204
181
 
205
- public void SetVelocity(Vector3 localVel)
206
- {
182
+ public void SetVelocity(Vector3 localVel) {
207
183
  currentSpeed = new Vector2(localVel.x, localVel.z).magnitude;
208
184
  //The target speed is the movement speed the animations were built for
209
185
  var targetSpeed = animWalkSpeed;
210
- if (currentState == CharacterState.Sprinting)
211
- {
186
+ if (currentState == CharacterState.Sprinting) {
212
187
  if (currentSpeed < animWalkSpeed) {
213
188
  //We will walk instead of run even though we are trying to run
214
189
  } else {
215
190
  targetSpeed = animRunSpeed;
216
191
  }
217
- }
218
- else if (currentState == CharacterState.Crouching)
219
- {
192
+ } else if (currentState == CharacterState.Crouching) {
220
193
  targetSpeed = animCrouchSpeed;
221
194
  }
222
-
195
+
223
196
  //Have to update sprinting state dynamically because low speeds can disable it
224
197
  animator.SetBool("Sprinting",
225
198
  currentState == CharacterState.Sprinting && currentSpeed >= animWalkSpeed);
226
199
 
227
- this.targetPlaybackSpeed = currentSpeed / targetSpeed;
200
+ targetPlaybackSpeed = currentSpeed / targetSpeed;
228
201
  targetVelNormalized = new Vector2(localVel.x, localVel.z).normalized;
229
202
  verticalVel = Mathf.Clamp(localVel.y, -10, 10);
230
203
  //print("currentSpeed: " + currentSpeed + " targetSpeed: " + targetSpeed + " playbackSpeed: " + targetPlaybackSpeed + " velNormalized: " + targetVelNormalized);
231
204
  }
232
205
 
233
- public void SetState(CharacterAnimationSyncData syncedState)
234
- {
235
- if (!enabled || !this.gameObject.activeInHierarchy)
236
- {
206
+ public void SetState(CharacterAnimationSyncData syncedState) {
207
+ if (!enabled || !gameObject.activeInHierarchy) {
237
208
  return;
238
209
  }
239
210
 
240
211
  var newState = syncedState.state;
241
- this.grounded = syncedState.grounded;
212
+ grounded = syncedState.grounded;
242
213
  animator.SetBool("Grounded", grounded);
214
+ // print("New State. Grounded: " + grounded + " state: " + syncedState.state + " Jumping: " +
215
+ // syncedState.jumping);
243
216
  animator.SetBool("Crouching", syncedState.crouching || syncedState.state == CharacterState.Crouching);
244
217
 
245
218
  if (syncedState.jumping) {
246
219
  SetTrigger("Jump");
247
220
  }
248
221
 
249
- if (this.firstPerson)
250
- {
222
+ if (firstPerson) {
251
223
  animator.SetLayerWeight(0, 0);
252
224
  }
253
225
 
254
226
  lastStateTime = Time.time;
255
227
  currentState = newState;
256
228
 
257
- this.SetVelocity(syncedState.localVelocity);
229
+ SetVelocity(syncedState.localVelocity);
258
230
  //print("Set state: " + currentState);
259
231
  }
260
232
 
@@ -267,16 +239,13 @@ namespace Code.Player.Character.NetworkedMovement
267
239
  animator.SetTrigger(trigger);
268
240
  }
269
241
 
270
- public void SetLayerWeight(CharacterAnimationLayer layer, float weight)
271
- {
242
+ public void SetLayerWeight(CharacterAnimationLayer layer, float weight) {
272
243
  var layerName = "Override" + (int)layer;
273
244
  animator.SetLayerWeight(animator.GetLayerIndex(layerName), weight);
274
245
  }
275
246
 
276
- public void PlayAnimation(AnimationClip clip, CharacterAnimationLayer layer, float fixedTransitionDuration)
277
- {
278
- if (!enabled || !this.gameObject.activeInHierarchy)
279
- {
247
+ public void PlayAnimation(AnimationClip clip, CharacterAnimationLayer layer, float fixedTransitionDuration) {
248
+ if (!enabled || !gameObject.activeInHierarchy) {
280
249
  return;
281
250
  }
282
251
 
@@ -291,10 +260,8 @@ namespace Code.Player.Character.NetworkedMovement
291
260
  animator.GetLayerIndex(stateName));
292
261
  }
293
262
 
294
- public void StopAnimation(CharacterAnimationLayer layer, float fixedTransitionDuration)
295
- {
296
- if (!enabled || !this.gameObject.activeInHierarchy)
297
- {
263
+ public void StopAnimation(CharacterAnimationLayer layer, float fixedTransitionDuration) {
264
+ if (!enabled || !gameObject.activeInHierarchy) {
298
265
  return;
299
266
  }
300
267
 
@@ -302,9 +269,8 @@ namespace Code.Player.Character.NetworkedMovement
302
269
  animator.SetBool("Override" + (int)layer + "Looping", false);
303
270
  }
304
271
 
305
- public float GetPlaybackSpeed()
306
- {
307
- return this.targetPlaybackSpeed;
272
+ public float GetPlaybackSpeed() {
273
+ return targetPlaybackSpeed;
308
274
  }
309
275
  }
310
276
  }
@@ -28,8 +28,13 @@ namespace Code.Player.Character.MovementSystems.Character {
28
28
  CharacterInputData> {
29
29
  [FormerlySerializedAs("rigidbody")] public Rigidbody rb;
30
30
  public Transform rootTransform;
31
- public Transform airshipTransform; // The visual transform controlled by this script. This always has the exact rotations used for movement
32
- public Transform graphicTransform; // A transform that games can animate. This may have slightly altered rotation for visuals
31
+
32
+ public Transform
33
+ airshipTransform; // The visual transform controlled by this script. This always has the exact rotations used for movement
34
+
35
+ public Transform
36
+ graphicTransform; // A transform that games can animate. This may have slightly altered rotation for visuals
37
+
33
38
  public CharacterMovementSettings movementSettings;
34
39
  public BoxCollider mainCollider;
35
40
 
@@ -66,7 +71,8 @@ namespace Code.Player.Character.MovementSystems.Character {
66
71
  [Tooltip("If true, the character body will automatically rotate in the direction of the look vector.")]
67
72
  public bool rotateAutomatically = true;
68
73
 
69
- [Tooltip("If enabled, the head will be rotated to look in the same direction as the look vector. The body will rotate only when needed. \"Rotate Automatically\" must also be checked.")]
74
+ [Tooltip(
75
+ "If enabled, the head will be rotated to look in the same direction as the look vector. The body will rotate only when needed. \"Rotate Automatically\" must also be checked.")]
70
76
  public bool rotateHeadToLookVector = true;
71
77
 
72
78
  [Tooltip("How much influence the look vector has on the look rotation.")]
@@ -75,7 +81,7 @@ namespace Code.Player.Character.MovementSystems.Character {
75
81
 
76
82
  [Tooltip("How far the head can rotate before the body rotates in degrees.")] [Range(0, 180)]
77
83
  public int headRotationThreshold = 60;
78
-
84
+
79
85
  [Tooltip(
80
86
  "If true animations will be played on the server. This should be true if you care about character movement animations server-side (like for hit boxes).")]
81
87
  public bool playAnimationOnServer = true;
@@ -225,7 +231,7 @@ namespace Code.Player.Character.MovementSystems.Character {
225
231
  }
226
232
 
227
233
  _rig = GetComponentInChildren<CharacterRig>();
228
-
234
+
229
235
  // Verify rig is setup correctly for rotateHeadToLookVector
230
236
  if (rotateHeadToLookVector) {
231
237
  if (_rig == null || _rig.head == null || _rig.spine == null) {
@@ -236,7 +242,7 @@ namespace Code.Player.Character.MovementSystems.Character {
236
242
  initialHeadRotation = _rig.head.rotation;
237
243
  }
238
244
  }
239
-
245
+
240
246
  _cameraTransform = Camera.main.transform;
241
247
  }
242
248
 
@@ -302,9 +308,9 @@ namespace Code.Player.Character.MovementSystems.Character {
302
308
  if (!rb.isKinematic) {
303
309
  rb.linearVelocity = snapshot.velocity;
304
310
  }
305
-
311
+
306
312
  HandleCharacterRotation(snapshot.lookVector);
307
-
313
+
308
314
  OnSetSnapshot?.Invoke(snapshot);
309
315
  }
310
316
 
@@ -455,18 +461,15 @@ namespace Code.Player.Character.MovementSystems.Character {
455
461
  currentMoveSnapshot.canJump = (byte)Math.Max(currentMoveSnapshot.canJump - 1, 0);
456
462
  }
457
463
 
458
- var groundSlopeDir = detectedGround
459
- ? Vector3.Cross(Vector3.Cross(groundHit.normal, Vector3.down), groundHit.normal).normalized
460
- : transform.forward;
461
- var slopeDot = 1 - Mathf.Max(0, Vector3.Dot(groundHit.normal, Vector3.up));
462
464
 
463
465
  var canStand = physics.CanStand();
464
-
465
- var normalizedMoveDir = Vector3.ClampMagnitude(command.moveDir, 1);
466
+ var originalMoveDir = Vector3.ClampMagnitude(command.moveDir, 1);
467
+ var normalizedMoveDir = originalMoveDir;
466
468
  var characterMoveVelocity = normalizedMoveDir;
467
469
  //Save the crouching var
468
470
  currentMoveSnapshot.isCrouching = command.crouch;
469
471
 
472
+
470
473
  #region GRAVITY
471
474
 
472
475
  if (movementSettings.useGravity) {
@@ -572,7 +575,7 @@ namespace Code.Player.Character.MovementSystems.Character {
572
575
  */
573
576
  var isMoving = currentVelocity.sqrMagnitude > .1f;
574
577
  var inAir = didJump || (!detectedGround && !currentMoveSnapshot.prevStepUp);
575
- var tryingToSprint = movementSettings.onlySprintForward
578
+ var tryingToSprint = movementSettings.onlySprintForward
576
579
  ? command.sprint && airshipTransform.InverseTransformVector(command.moveDir).z > 0.1f
577
580
  : //Only sprint if you are moving forward
578
581
  command.sprint && command.moveDir.magnitude > 0.1f; //Only sprint if you are moving
@@ -706,6 +709,67 @@ namespace Code.Player.Character.MovementSystems.Character {
706
709
 
707
710
  #endregion
708
711
 
712
+
713
+ #region SLOPE
714
+
715
+ if (drawDebugGizmos_GROUND) {
716
+ GizmoUtils.DrawSphere(transform.position + new Vector3(0, 1, 0), .1f, inAir ? Color.cyan : Color.white,
717
+ 4, 5);
718
+ }
719
+ if (movementSettings.detectSlopes && grounded) {
720
+ var groundSlopeDir = Vector3.Cross(Vector3.Cross(groundHit.normal, Vector3.down), groundHit.normal)
721
+ .normalized;
722
+ var slopeDot = 1 - Mathf.Max(0, Vector3.Dot(groundHit.normal, Vector3.up));
723
+
724
+ if (drawDebugGizmos_GROUND) {
725
+ Debug.DrawLine(rootPosition, rootPosition + groundSlopeDir, Color.black, 5);
726
+ }
727
+
728
+ //Push the character based on the slope amount
729
+ if (slopeDot < 1 && movementSettings.slopeForce > 0) {
730
+ var slopeVel = groundSlopeDir.normalized * slopeDot * slopeDot * movementSettings.slopeForce;
731
+ if (slopeDot > movementSettings.maxSlopeDelta) {
732
+ slopeVel.y = 0;
733
+ }
734
+
735
+ newVelocity += slopeVel;
736
+ }
737
+
738
+ //Project movement onto the slope
739
+ if (characterMoveVelocity.sqrMagnitude > .1 && groundHit.normal.y > 0) {
740
+ //Adjust movement based on the slope of the ground you are on
741
+ var newMoveDir = Vector3.ProjectOnPlane(normalizedMoveDir, groundHit.normal);
742
+ //Only adjust for downward slopes
743
+ //newMoveVector.y = Mathf.Min(0, newMoveVector.y);
744
+
745
+ //Ignore tiny float imprecision's
746
+ if (Mathf.Abs(newMoveDir.y) > .1f) {
747
+ //Take the new direction and make it as fast as the intended move velocity
748
+ normalizedMoveDir = newMoveDir;
749
+ characterMoveVelocity = newMoveDir;
750
+ grounded = true;
751
+ if (drawDebugGizmos_GROUND) {
752
+ Debug.DrawLine(rootPosition, rootPosition + normalizedMoveDir * .5f, Color.magenta,
753
+ 5);
754
+ Debug.DrawLine(groundHit.point, groundHit.point + groundHit.normal * .5f, Color.red,
755
+ 5);
756
+ }
757
+ //}
758
+ }
759
+ }
760
+
761
+ if (useExtraLogging && characterMoveVelocity.y < 0) {
762
+ //print("Move Vector After: " + characterMoveVelocity + " groundHit.normal: " + groundHit.normal + " hitGround: " + groundHit.collider.gameObject.name);
763
+ }
764
+
765
+ if (slopeVisualizer) {
766
+ slopeVisualizer.LookAt(slopeVisualizer.position +
767
+ (groundSlopeDir.sqrMagnitude < .1f ? transform.forward : groundSlopeDir));
768
+ }
769
+ }
770
+
771
+ #endregion
772
+
709
773
  #region MOVEMENT
710
774
 
711
775
  // Find speed
@@ -744,7 +808,7 @@ namespace Code.Player.Character.MovementSystems.Character {
744
808
  currentMoveSnapshot.velocity.z);
745
809
  var draggedHorizontal = horizontalVelocity * additionalDragMultiplier;
746
810
 
747
- characterMoveVelocity = new Vector3(draggedHorizontal.x, currentMoveSnapshot.velocity.y,
811
+ characterMoveVelocity = new Vector3(draggedHorizontal.x, 0,
748
812
  draggedHorizontal.z);
749
813
  } else {
750
814
  var targetVelocity = normalizedMoveDir * currentMoveSnapshot.currentSpeed;
@@ -762,57 +826,20 @@ namespace Code.Player.Character.MovementSystems.Character {
762
826
  var velocityChange = Vector3.ClampMagnitude(velocityDiff, maxDelta * reverseScale);
763
827
 
764
828
  characterMoveVelocity = currentMoveSnapshot.velocity + velocityChange;
829
+ characterMoveVelocity.y = 0;
765
830
  }
766
831
  } else {
767
832
  characterMoveVelocity *= currentMoveSnapshot.currentSpeed;
768
833
  }
769
834
  }
770
835
 
771
- #region SLOPE
772
-
773
- if (movementSettings.detectSlopes && detectedGround) {
774
- //On Ground and detecting slopes
775
- if (slopeDot < 1 && slopeDot > movementSettings.minSlopeDelta) {
776
- var slopeVel = groundSlopeDir.normalized * slopeDot * slopeDot * movementSettings.slopeForce;
777
- if (slopeDot > movementSettings.maxSlopeDelta) {
778
- slopeVel.y = 0;
779
- }
780
-
781
- newVelocity += slopeVel;
782
- }
783
-
784
-
785
- //Project movement onto the slope
786
- if (characterMoveVelocity.sqrMagnitude > 0 && groundHit.normal.y > 0) {
787
- //Adjust movement based on the slope of the ground you are on
788
- var newMoveVector = Vector3.ProjectOnPlane(characterMoveVelocity, groundHit.normal);
789
- newMoveVector.y = Mathf.Min(0, newMoveVector.y);
790
- characterMoveVelocity = newMoveVector;
791
- if (drawDebugGizmos_STEPUP) {
792
- Debug.DrawLine(rootPosition, rootPosition + characterMoveVelocity * 2, Color.red);
793
- }
794
- //characterMoveVector.y = Mathf.Clamp( characterMoveVector.y, 0, moveData.maxSlopeSpeed);
795
- }
796
-
797
- if (useExtraLogging && characterMoveVelocity.y < 0) {
798
- //print("Move Vector After: " + characterMoveVelocity + " groundHit.normal: " + groundHit.normal + " hitGround: " + groundHit.collider.gameObject.name);
799
- }
800
- }
801
-
802
- if (slopeVisualizer) {
803
- slopeVisualizer.LookAt(slopeVisualizer.position +
804
- (groundSlopeDir.sqrMagnitude < .1f ? transform.forward : groundSlopeDir));
805
- }
806
-
807
- #endregion
808
-
809
836
 
810
837
  #region MOVE_FORCE
811
838
 
812
839
  //Clamp directional movement to not add forces if you are already moving in that direction
813
840
  var flatVelocity = new Vector3(newVelocity.x, 0, newVelocity.z);
814
- var tryingToMove = normalizedMoveDir.sqrMagnitude > .1f;
815
- var rawMoveDot = Vector3.Dot(flatVelocity.normalized, normalizedMoveDir);
841
+ var tryingToMove = originalMoveDir.sqrMagnitude > .1f;
842
+ var rawMoveDot = Vector3.Dot(flatVelocity.normalized, originalMoveDir.normalized);
816
843
  //print("Directional Influence: " + (characterMoveVector - newVelocity) + " mag: " + (characterMoveVector - currentVelocity).magnitude);
817
844
  var bumpSize = characterRadius + .15f;
818
845
 
@@ -958,9 +985,16 @@ namespace Code.Player.Character.MovementSystems.Character {
958
985
  // if(Mathf.Abs(characterMoveVelocity.z) > Mathf.Abs(newVelocity.z)){
959
986
  // newVelocity.z = characterMoveVelocity.z;
960
987
  // }
988
+
989
+ //If our current flat velocity is less then our intended velocity we can use our move velocity
961
990
  if (moveMagnitude + .5f >= flatVelMagnitude) {
991
+ //Snap velocity to our target move velocity
962
992
  newVelocity.x = characterMoveVelocity.x;
963
993
  newVelocity.z = characterMoveVelocity.z;
994
+ if (grounded && !didJump && !currentMoveSnapshot.airborneFromImpulse &&
995
+ !currentMoveSnapshot.prevStepUp) {
996
+ newVelocity.y = characterMoveVelocity.y;
997
+ }
964
998
  }
965
999
  }
966
1000
  } else {
@@ -979,10 +1013,10 @@ namespace Code.Player.Character.MovementSystems.Character {
979
1013
  if (flatVelMagnitude + addedForce < currentMoveSnapshot.currentSpeed) {
980
1014
  forwardMod = 1;
981
1015
  }
982
-
1016
+
983
1017
  //Apply the force
984
1018
  newVelocity += normalizedMoveDir * forwardMod * addedForce;
985
-
1019
+
986
1020
  //Never get faster than you've been impulsed
987
1021
  var flatVel = Vector3.ClampMagnitude(new Vector3(newVelocity.x, 0, newVelocity.z),
988
1022
  Mathf.Max(addedForce, flatVelMagnitude));
@@ -1017,18 +1051,18 @@ namespace Code.Player.Character.MovementSystems.Character {
1017
1051
  SnapToY(pointOnRamp.y);
1018
1052
  //airshipTransform.position = Vector3.MoveTowards(oldPos, transform.position, deltaTime);
1019
1053
  }
1020
-
1054
+
1021
1055
  //print("STEPPED UP. Vel before: " + newVelocity);
1022
1056
  newVelocity = Vector3.ClampMagnitude(
1023
1057
  new Vector3(stepUpVel.x, Mathf.Max(stepUpVel.y, newVelocity.y), stepUpVel.z),
1024
1058
  newVelocity.magnitude);
1025
1059
  //print("PointOnRamp: " + pointOnRamp + " position: " + rootPosition + " vel: " + newVelocity);
1026
-
1060
+
1027
1061
  if (drawDebugGizmos_STEPUP) {
1028
1062
  GizmoUtils.DrawSphere(oldPos, .01f, Color.red, 4, 4);
1029
1063
  GizmoUtils.DrawSphere(rootPosition + newVelocity, .03f, new Color(1, .5f, .5f), 4, 4);
1030
1064
  }
1031
-
1065
+
1032
1066
  currentMoveSnapshot.state =
1033
1067
  groundedState; //Force grounded state since we are in the air for the step up
1034
1068
  grounded = true;
@@ -1202,7 +1236,7 @@ namespace Code.Player.Character.MovementSystems.Character {
1202
1236
  var forwardVector = flatVelocity.normalized * Mathf.Max(forwardDistance, bumpSize);
1203
1237
  //print("Forward vec: " + forwardVector);
1204
1238
 
1205
- //Do raycasting after we have claculated our move direction
1239
+ //Do raycasting after we have calculated our move direction
1206
1240
  var forwardHits =
1207
1241
  physics.CheckAllForwardHits(rootPosition - flatVelocity.normalized * -forwardMargin, forwardVector,
1208
1242
  true,
@@ -1364,6 +1398,8 @@ namespace Code.Player.Character.MovementSystems.Character {
1364
1398
  //Execute the forces onto the rigidbody
1365
1399
  // if (isImpulsing) print("Impulsed velocity resulted in " + newVelocity);
1366
1400
  rb.linearVelocity = newVelocity;
1401
+ // Debug.DrawLine(transform.position, transform.position + rb.linearVelocity * Time.fixedDeltaTime,
1402
+ // Color.green, 5);
1367
1403
 
1368
1404
  #endregion
1369
1405
 
@@ -1478,7 +1514,7 @@ namespace Code.Player.Character.MovementSystems.Character {
1478
1514
  return;
1479
1515
  }
1480
1516
 
1481
- HandleCharacterRotation(this.lookVector);
1517
+ HandleCharacterRotation(lookVector);
1482
1518
  }
1483
1519
 
1484
1520
  /**
@@ -1486,7 +1522,10 @@ namespace Code.Player.Character.MovementSystems.Character {
1486
1522
  * transform and visual rotation based on the configuration of the character.
1487
1523
  */
1488
1524
  private void HandleCharacterRotation(Vector3 lookVector) {
1489
- if (!rotateAutomatically) return;
1525
+ if (!rotateAutomatically) {
1526
+ return;
1527
+ }
1528
+
1490
1529
  UpdateCharacterRotation(lookVector);
1491
1530
  }
1492
1531
 
@@ -1513,49 +1552,49 @@ namespace Code.Player.Character.MovementSystems.Character {
1513
1552
  airshipTransform.rotation = Quaternion.LookRotation(lookTarget).normalized;
1514
1553
  return;
1515
1554
  }
1516
-
1555
+
1517
1556
  UpdateBodyRotation(lookTarget);
1518
1557
  UpdateHeadRotation(lookDirection);
1519
1558
  }
1520
-
1559
+
1521
1560
  private void UpdateBodyRotation(Vector3 direction) {
1522
1561
  direction.y = 0; // Don't rotate the character off the ground
1523
-
1562
+
1524
1563
  // If we are moving, start rotating towards the correct direction immediately. Don't negate any additional rotation
1525
- if (this.currentMoveSnapshot.velocity.magnitude > 0) {
1564
+ if (currentMoveSnapshot.velocity.magnitude > 0) {
1526
1565
  airshipTransform.rotation = Quaternion.LookRotation(direction).normalized;
1527
- graphicTransform.rotation = Quaternion.Slerp(graphicTransform.rotation, airshipTransform.rotation, smoothedRotationSpeed * Mathf.Deg2Rad * Time.deltaTime);
1566
+ graphicTransform.rotation = Quaternion.Slerp(graphicTransform.rotation, airshipTransform.rotation,
1567
+ smoothedRotationSpeed * Mathf.Deg2Rad * Time.deltaTime);
1528
1568
  return;
1529
1569
  }
1530
-
1570
+
1531
1571
  // Since graphicTransform is a child of the airship transform, we "undo" the
1532
1572
  // change we are going to apply so that we can rotate the graphicTransform independently
1533
- Quaternion previousParentRotation = airshipTransform.rotation;
1573
+ var previousParentRotation = airshipTransform.rotation;
1534
1574
  airshipTransform.rotation = Quaternion.LookRotation(direction).normalized;
1535
- Quaternion deltaRotation = airshipTransform.rotation * Quaternion.Inverse(previousParentRotation);
1575
+ var deltaRotation = airshipTransform.rotation * Quaternion.Inverse(previousParentRotation);
1536
1576
  graphicTransform.rotation = Quaternion.Inverse(deltaRotation) * graphicTransform.rotation;
1537
-
1577
+
1538
1578
  // Now calculate if we need to rotate the graphicTransform (body) or if the head
1539
1579
  // rotation will be enough.
1540
- Vector3 currentForward = graphicTransform.rotation * Vector3.forward;
1580
+ var currentForward = graphicTransform.rotation * Vector3.forward;
1541
1581
  currentForward.y = 0;
1542
-
1582
+
1543
1583
  currentForward.Normalize();
1544
1584
  direction.Normalize();
1545
1585
 
1546
- float angle = Vector3.SignedAngle(currentForward, direction, Vector3.up);
1547
- if (Mathf.Abs(angle) > headRotationThreshold)
1548
- {
1549
- float rotateAmount = Mathf.Abs(angle) - headRotationThreshold;
1550
- float sign = Mathf.Sign(angle);
1586
+ var angle = Vector3.SignedAngle(currentForward, direction, Vector3.up);
1587
+ if (Mathf.Abs(angle) > headRotationThreshold) {
1588
+ var rotateAmount = Mathf.Abs(angle) - headRotationThreshold;
1589
+ var sign = Mathf.Sign(angle);
1551
1590
 
1552
1591
  // We only rotate just enough to allow us to not snap our neck, but don't rotate the body
1553
1592
  // any more than that.
1554
- Quaternion partialRotation = Quaternion.AngleAxis(rotateAmount * sign, Vector3.up);
1593
+ var partialRotation = Quaternion.AngleAxis(rotateAmount * sign, Vector3.up);
1555
1594
  graphicTransform.rotation = partialRotation * graphicTransform.rotation;
1556
1595
  }
1557
1596
  }
1558
-
1597
+
1559
1598
  /**
1560
1599
  * Sets the head look direction independently of the body using "Look Vector Influence". Does _NOT_ limit the
1561
1600
  * amount of rotation from the body forward direction. Use UpdateCharacterRotation for rotation that take the configured
@@ -1567,9 +1606,11 @@ namespace Code.Player.Character.MovementSystems.Character {
1567
1606
  if (direction.magnitude == 0) {
1568
1607
  direction = new Vector3(0, 0, 0.01f);
1569
1608
  }
1570
-
1609
+
1571
1610
  var characterUp = _rig.spine ? _rig.spine.up : Vector3.up;
1572
- var lerpedLookRotation = Vector3.Lerp(Quaternion.Inverse(initialHeadRotation) * _rig.head.rotation * Vector3.forward, direction, lookVectorInfluence);
1611
+ var lerpedLookRotation
1612
+ = Vector3.Lerp(Quaternion.Inverse(initialHeadRotation) * _rig.head.rotation * Vector3.forward,
1613
+ direction, lookVectorInfluence);
1573
1614
  _rig.head.rotation = initialHeadRotation * Quaternion.LookRotation(lerpedLookRotation, characterUp);
1574
1615
  }
1575
1616
 
@@ -164,15 +164,12 @@ namespace Code.Player.Character.MovementSystems.Character {
164
164
 
165
165
 
166
166
  [Header("Slopes")]
167
- [Tooltip("Auto detect slopes to create a downward drag. Disable as an optimization to skip raycast checks")]
167
+ [Tooltip("Detect slopes for smooth movement on ramps. Disable as an optimization to skip raycast checks")]
168
168
  public bool detectSlopes = false;
169
169
 
170
- [Tooltip("The maximum force that pushes against the character when on a slope")] [Min(0f)]
170
+ [Tooltip("Increase to have slopes push the character downhill")] [Min(0f)]
171
171
  public float slopeForce = 45;
172
172
 
173
- [Tooltip("Slopes below this threshold will be ignored. O is flat ground, 1 is a vertical wall")] [Range(0, 1)]
174
- public float minSlopeDelta = .1f;
175
-
176
173
  [Tooltip("Slopes above this threshold will be treated as walls")] [Range(0, 1)]
177
174
  public float maxSlopeDelta = .3f;
178
175
  }
@@ -88,6 +88,8 @@ namespace Code.Player.Character.MovementSystems.Character {
88
88
  Vector3 vel,
89
89
  Vector3 moveDir) {
90
90
  //start the cast slightly off to account for clipping into colliders when falling very fast
91
+ var gravityDir = -_movement.transform.up;
92
+ var gravityDirOffset = gravityDir.normalized * .1f;
91
93
  var verticalOffset = 1 + Mathf.Max(-vel.y, 0);
92
94
  var intersectionMargin = .075f;
93
95
  var castDistance = .2f + verticalOffset;
@@ -99,8 +101,6 @@ namespace Code.Player.Character.MovementSystems.Character {
99
101
  Mathf.Max(0, -vel.y) +
100
102
  offsetMargin; // Mathf.Min(0, movement.transform.InverseTransformVector(vel).y); //Need this part of we change gravity dir
101
103
 
102
- var gravityDir = -_movement.transform.up;
103
- var gravityDirOffset = gravityDir.normalized * .1f;
104
104
 
105
105
  //Check directly below character as an early out and for comparison information
106
106
  if (Physics.Raycast(castStartPos, gravityDir, out var rayHitInfo, castDistance,
@@ -150,7 +150,7 @@ namespace Code.Player.Character.MovementSystems.Character {
150
150
  if (!ignoredColliders.ContainsKey(hitInfo.collider.GetInstanceID())) {
151
151
  //Physics Casts give you interpolated normals. This uses a ray to find an exact normal
152
152
  hitInfo.normal = CalculateRealNormal(hitInfo.normal,
153
- hitInfo.point + gravityDirOffset + moveDir.normalized * .01f, gravityDir, .11f,
153
+ currentPos, hitInfo.point - currentPos, .11f,
154
154
  _movement.movementSettings.groundCollisionLayerMask);
155
155
 
156
156
  if (_movement.drawDebugGizmos_GROUND) {
@@ -7,6 +7,7 @@ using System.Threading.Tasks;
7
7
  using System.Xml;
8
8
  using Code.Luau;
9
9
  using HandlebarsDotNet;
10
+ using Luau;
10
11
  using Unity.VisualScripting;
11
12
  using UnityEditor;
12
13
  using UnityEngine;
@@ -570,6 +571,10 @@ namespace CsToTs.TypeScript {
570
571
  return enumDef != null ? enumDef.Name : "unknown";
571
572
  }
572
573
 
574
+ if (type == typeof(LuauBuffer)) {
575
+ return "buffer";
576
+ }
577
+
573
578
  var typeCode = Type.GetTypeCode(type);
574
579
  if (typeCode != TypeCode.Object)
575
580
  return GetPrimitiveMemberType(typeCode, context.Options);
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gg.easy.airship",
3
- "version": "0.1.2167",
3
+ "version": "0.1.2168",
4
4
  "displayName": "Airship",
5
5
  "unity": "2021.3",
6
6
  "unityRelease": "12f1",