@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.
- package/GravityController.rbxmx +102 -3
- package/out/index.d.ts +13 -1
- package/out/init.lua +7 -1
- package/package.json +1 -1
package/GravityController.rbxmx
CHANGED
|
@@ -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
|