@rbxts/gravity-controller 1.0.2 → 1.0.3

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.
@@ -2379,11 +2379,29 @@ local Control = require(CharacterModules:WaitForChild("Control"))
2379
2379
  local Collider = require(script:WaitForChild("Collider"))
2380
2380
  local StateTracker = require(script:WaitForChild("StateTracker"))
2381
2381
 
2382
- -- CONSTANTS
2382
+ -- CONSTANTS (can be configured via SetConstants)
2383
2383
 
2384
2384
  local TRANSITION = 0.15
2385
2385
  local WALK_FORCE = 200 / 3
2386
2386
  local JUMP_MODIFIER = 1.2
2387
+ local USE_BODY_POSITION_LOCK = false -- Use BodyPosition to prevent sliding on aligned surfaces
2388
+
2389
+ -- Module-level configuration function
2390
+ local function SetConstants(config)
2391
+ if config.Transition ~= nil then
2392
+ TRANSITION = config.Transition
2393
+ end
2394
+ if config.WalkForce ~= nil then
2395
+ WALK_FORCE = config.WalkForce
2396
+ end
2397
+ if config.JumpModifier ~= nil then
2398
+ JUMP_MODIFIER = config.JumpModifier
2399
+ end
2400
+ if config.UseBodyPositionLock ~= nil then
2401
+ USE_BODY_POSITION_LOCK = config.UseBodyPositionLock
2402
+ end
2403
+ -- print("Set constants", config, WALK_FORCE, USE_BODY_POSITION_LOCK)
2404
+ end
2387
2405
 
2388
2406
  local ZERO3 = Vector3.new(0, 0, 0)
2389
2407
  local UNIT_Y = Vector3.new(0, 1, 0)
@@ -2443,6 +2461,10 @@ end
2443
2461
 
2444
2462
  local function onJumpRequest(self)
2445
2463
  if not self.StateTracker.Jumped and self._collider:IsGrounded(true) then
2464
+ -- Release horizontal lock before jumping
2465
+ if USE_BODY_POSITION_LOCK then
2466
+ self._collider:SetHorizontalLock(false)
2467
+ end
2446
2468
  local vel = self.HRP.Velocity
2447
2469
  self.HRP.Velocity = vel + self._gravityUp*self.Humanoid.JumpPower*JUMP_MODIFIER
2448
2470
  self.StateTracker:RequestJump()
@@ -2531,6 +2553,29 @@ local function onGravityStep(self, dt)
2531
2553
 
2532
2554
  local charRotation = newCharRotation * newCharCF
2533
2555
 
2556
+ -- Check if we should lock horizontal position to prevent sliding
2557
+ if USE_BODY_POSITION_LOCK then
2558
+ local isGrounded = self._collider:IsGrounded(false)
2559
+ local surfaceNormal = isGrounded and self._collider:GetSurfaceNormal()
2560
+ local isJumping = self.StateTracker.Jumped or self.StateTracker.State == Enum.HumanoidStateType.Jumping
2561
+
2562
+ -- Don't lock when jumping or not on aligned surface with no input
2563
+ if isGrounded and not isInputMoving and not isJumping and surfaceNormal then
2564
+ local gravityAlignment = math.abs(surfaceNormal:Dot(self._gravityUp))
2565
+ if gravityAlignment > 0.99 then
2566
+ -- Lock horizontal position to prevent sliding
2567
+ self._collider:SetHorizontalLock(true, self.HRP.Position, surfaceNormal)
2568
+ else
2569
+ self._collider:SetHorizontalLock(false)
2570
+ end
2571
+ else
2572
+ self._collider:SetHorizontalLock(false)
2573
+ end
2574
+ else
2575
+ -- Ensure lock is disabled if not using this approach
2576
+ self._collider:SetHorizontalLock(false)
2577
+ end
2578
+
2534
2579
  self.StateTracker:Update(self._gravityUp, self._collider:IsGrounded(false), isInputMoving)
2535
2580
  self._collider:Update(walkForce + gForce, charRotation)
2536
2581
  end
@@ -2573,6 +2618,10 @@ end
2573
2618
 
2574
2619
  -- Public Methods
2575
2620
 
2621
+ function GravityControllerClass.SetConstants(_self, config)
2622
+ SetConstants(config)
2623
+ end
2624
+
2576
2625
  function GravityControllerClass:ResetGravity(gravity)
2577
2626
  self._gravityUp = gravity
2578
2627
  self._fallStart = self.HRP.Position:Dot(gravity)
@@ -2746,7 +2795,7 @@ function ColliderClass.new(controller)
2746
2795
 
2747
2796
  self.Model = Instance.new("Model")
2748
2797
 
2749
- local sphere, vForce, floor, floor2, gryo = create(self, controller)
2798
+ local sphere, vForce, floor, floor2, gryo, bodyPosition = create(self, controller)
2750
2799
 
2751
2800
  self._maid = Maid.new()
2752
2801
 
@@ -2757,6 +2806,7 @@ function ColliderClass.new(controller)
2757
2806
  self.FloorDetector = floor
2758
2807
  self.JumpDetector = floor2
2759
2808
  self.Gyro = gryo
2809
+ self.BodyPosition = bodyPosition
2760
2810
 
2761
2811
  init(self)
2762
2812
 
@@ -2836,6 +2886,13 @@ function create(self, controller)
2836
2886
  gyro.CFrame = controller.HRP.CFrame
2837
2887
  gyro.Parent = controller.HRP
2838
2888
 
2889
+ local bodyPosition = Instance.new("BodyPosition")
2890
+ bodyPosition.MaxForce = Vector3.new(0, 0, 0) -- Disabled by default
2891
+ bodyPosition.Position = controller.HRP.Position
2892
+ bodyPosition.P = 100000
2893
+ bodyPosition.D = 10000
2894
+ bodyPosition.Parent = controller.HRP
2895
+
2839
2896
  floor.Touched:Connect(function() end)
2840
2897
  floor2.Touched:Connect(function() end)
2841
2898
 
@@ -2843,7 +2900,7 @@ function create(self, controller)
2843
2900
  floor.Parent = self.Model
2844
2901
  floor2.Parent = self.Model
2845
2902
 
2846
- return sphere, vForce, floor, floor2, gyro
2903
+ return sphere, vForce, floor, floor2, gyro, bodyPosition
2847
2904
  end
2848
2905
 
2849
2906
  function init(self)
@@ -2851,6 +2908,7 @@ function init(self)
2851
2908
  self._maid:Mark(self.VForce)
2852
2909
  self._maid:Mark(self.FloorDetector)
2853
2910
  self._maid:Mark(self.Gyro)
2911
+ self._maid:Mark(self.BodyPosition)
2854
2912
  self.Model.Name = "Collider"
2855
2913
  self.Model.Parent = self.Controller.Character
2856
2914
  end
@@ -2862,6 +2920,35 @@ function ColliderClass:Update(force, cframe)
2862
2920
  self.Gyro.CFrame = cframe
2863
2921
  end
2864
2922
 
2923
+ function ColliderClass:SetHorizontalLock(enabled, lockPosition, surfaceNormal)
2924
+ if enabled then
2925
+ -- Lock position to prevent sliding when on aligned surface with no input
2926
+ -- Only lock if we don't already have a lock, or update it
2927
+ if self.BodyPosition.MaxForce.Magnitude == 0 then
2928
+ -- Setting initial lock position
2929
+ self._lockedPosition = lockPosition
2930
+ end
2931
+ -- Keep position locked (update to current position to allow vertical adjustments)
2932
+ -- But constrain horizontal movement by only allowing movement along surface normal
2933
+ local currentPos = self.Controller.HRP.Position
2934
+ local positionAlongNormal = currentPos:Dot(surfaceNormal)*surfaceNormal
2935
+ -- Keep horizontal position from when lock was enabled
2936
+ if self._lockedPosition then
2937
+ local lockedPosAlongNormal = self._lockedPosition:Dot(surfaceNormal)*surfaceNormal
2938
+ local lockedHorizontalPos = self._lockedPosition - lockedPosAlongNormal
2939
+ -- Combine: use current vertical position but locked horizontal position
2940
+ self.BodyPosition.Position = lockedHorizontalPos + positionAlongNormal
2941
+ else
2942
+ self.BodyPosition.Position = lockPosition
2943
+ end
2944
+ self.BodyPosition.MaxForce = Vector3.new(100000, 100000, 100000)
2945
+ else
2946
+ -- Disable constraint
2947
+ self.BodyPosition.MaxForce = Vector3.new(0, 0, 0)
2948
+ self._lockedPosition = nil
2949
+ end
2950
+ end
2951
+
2865
2952
  function ColliderClass:IsGrounded(isJumpCheck)
2866
2953
  local parts = (isJumpCheck and self.JumpDetector or self.FloorDetector):GetTouchingParts()
2867
2954
  for _, part in pairs(parts) do
@@ -2893,6 +2980,18 @@ function ColliderClass:GetStandingPart()
2893
2980
  return result and result.Instance
2894
2981
  end
2895
2982
 
2983
+ function ColliderClass:GetSurfaceNormal()
2984
+ params2.FilterDescendantsInstances = {self.Controller.Character}
2985
+
2986
+ local gravityUp = self.Controller._gravityUp
2987
+ local result = workspace:Raycast(self.Sphere.Position, -1.1*gravityUp, params2)
2988
+
2989
+ if result and result.Normal then
2990
+ return result.Normal
2991
+ end
2992
+ return nil
2993
+ end
2994
+
2896
2995
  function ColliderClass:Destroy()
2897
2996
  self._maid:Sweep()
2898
2997
  end
package/out/index.d.ts CHANGED
@@ -15,8 +15,20 @@ export interface GravityController extends Instance {
15
15
  }
16
16
  export interface GravityControllerClass {
17
17
  new (player: Player): GravityController;
18
+ SetConstants(config: {
19
+ Transition?: number;
20
+ WalkForce?: number;
21
+ JumpModifier?: number;
22
+ UseBodyPositionLock?: boolean;
23
+ }): void;
24
+ }
25
+ export interface GravityControllerConfig {
26
+ Transition?: number;
27
+ WalkForce?: number;
28
+ JumpModifier?: number;
29
+ UseBodyPositionLock?: boolean;
18
30
  }
19
31
  export declare let gravityControllerClass: GravityControllerClass;
20
- export declare function installGravityControllerClass(): GravityControllerClass;
32
+ export declare function installGravityControllerClass(config?: GravityControllerConfig): GravityControllerClass;
21
33
  export declare function getGroundNormal(cframe: CFrame, originOffset: Vector3, oldGravityUp: Vector3): Vector3;
22
34
  export declare function getGravityControllerUp(gravityController: GravityController, oldGravityUp: Vector3): Vector3;
package/out/init.lua CHANGED
@@ -6,8 +6,11 @@ local Players = _services.Players
6
6
  local ReplicatedStorage = _services.ReplicatedStorage
7
7
  local RunService = _services.RunService
8
8
  local StarterPlayer = _services.StarterPlayer
9
- local function installGravityControllerClass()
9
+ local function installGravityControllerClass(config)
10
10
  if exports.gravityControllerClass then
11
+ if config then
12
+ exports.gravityControllerClass:SetConstants(config)
13
+ end
11
14
  return exports.gravityControllerClass
12
15
  end
13
16
  if RunService:IsServer() then
@@ -36,6 +39,9 @@ local function installGravityControllerClass()
36
39
  parent:WaitForChild("GravityController").Parent = ReplicatedStorage
37
40
  end
38
41
  exports.gravityControllerClass = require(ReplicatedStorage:WaitForChild("GravityController"))
42
+ if config and exports.gravityControllerClass.SetConstants then
43
+ exports.gravityControllerClass:SetConstants(config)
44
+ end
39
45
  return exports.gravityControllerClass
40
46
  end
41
47
  local PI2 = math.pi * 2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rbxts/gravity-controller",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "main": "out/init.lua",
5
5
  "keywords": [
6
6
  "gravity",