@quenty/ragdoll 15.23.0 → 15.23.1-canary.545.2374fb2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/package.json +32 -32
- package/src/Client/Classes/RagdollCameraShakeClient.lua +1 -1
- package/src/Client/Classes/RagdollHumanoidOnDeathClient.lua +2 -2
- package/src/Client/RagdollBindersClient.lua +1 -0
- package/src/Client/RagdollServiceClient.lua +9 -8
- package/src/Server/Classes/RagdollCameraShake.lua +1 -1
- package/src/Server/RagdollService.lua +13 -10
- package/src/Shared/Classes/BindableRagdollHumanoidOnFall.lua +3 -5
- package/src/Shared/Classes/RagdollableBase.lua +1 -1
- package/src/Shared/Rigging/RagdollAdditionalAttachmentUtils.lua +1 -1
- package/src/Shared/Rigging/RagdollBallSocketUtils.lua +2 -2
- package/src/Shared/Rigging/RagdollCollisionUtils.lua +5 -5
- package/src/Shared/Rigging/RagdollMotorUtils.lua +52 -28
- package/src/Shared/Rigging/RxRagdollUtils.lua +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [15.23.1-canary.545.2374fb2.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/ragdoll@15.23.0...@quenty/ragdoll@15.23.1-canary.545.2374fb2.0) (2025-04-05)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* Add types to packages ([2374fb2](https://github.com/Quenty/NevermoreEngine/commit/2374fb2b043cfbe0e9b507b3316eec46a4e353a0))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
# [15.23.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/ragdoll@15.22.3...@quenty/ragdoll@15.23.0) (2025-04-02)
|
|
7
18
|
|
|
8
19
|
**Note:** Version bump only for package @quenty/ragdoll
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quenty/ragdoll",
|
|
3
|
-
"version": "15.23.0",
|
|
3
|
+
"version": "15.23.1-canary.545.2374fb2.0",
|
|
4
4
|
"description": "Quenty's Ragdoll system for Roblox - Floppy fun ragdolls",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Roblox",
|
|
@@ -25,39 +25,39 @@
|
|
|
25
25
|
"Quenty"
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@quenty/adorneedata": "
|
|
29
|
-
"@quenty/attributeutils": "
|
|
30
|
-
"@quenty/baseobject": "
|
|
31
|
-
"@quenty/binder": "
|
|
32
|
-
"@quenty/brio": "
|
|
33
|
-
"@quenty/camera": "
|
|
34
|
-
"@quenty/cancellabledelay": "
|
|
35
|
-
"@quenty/characterutils": "
|
|
36
|
-
"@quenty/draw": "
|
|
37
|
-
"@quenty/enumutils": "
|
|
38
|
-
"@quenty/hapticfeedbackutils": "
|
|
39
|
-
"@quenty/instanceutils": "
|
|
40
|
-
"@quenty/loader": "
|
|
41
|
-
"@quenty/maid": "
|
|
42
|
-
"@quenty/motor6d": "
|
|
43
|
-
"@quenty/physicsutils": "
|
|
44
|
-
"@quenty/playerhumanoidbinder": "
|
|
45
|
-
"@quenty/promise": "
|
|
46
|
-
"@quenty/qframe": "
|
|
47
|
-
"@quenty/r15utils": "
|
|
48
|
-
"@quenty/remoting": "
|
|
49
|
-
"@quenty/rx": "
|
|
50
|
-
"@quenty/rxbinderutils": "
|
|
51
|
-
"@quenty/rxsignal": "
|
|
52
|
-
"@quenty/spring": "
|
|
53
|
-
"@quenty/steputils": "
|
|
54
|
-
"@quenty/table": "
|
|
55
|
-
"@quenty/tie": "
|
|
56
|
-
"@quenty/valuebaseutils": "
|
|
57
|
-
"@quenty/valueobject": "
|
|
28
|
+
"@quenty/adorneedata": "7.18.1-canary.545.2374fb2.0",
|
|
29
|
+
"@quenty/attributeutils": "14.17.1-canary.545.2374fb2.0",
|
|
30
|
+
"@quenty/baseobject": "10.8.1-canary.545.2374fb2.0",
|
|
31
|
+
"@quenty/binder": "14.19.1-canary.545.2374fb2.0",
|
|
32
|
+
"@quenty/brio": "14.17.1-canary.545.2374fb2.0",
|
|
33
|
+
"@quenty/camera": "14.20.1-canary.545.2374fb2.0",
|
|
34
|
+
"@quenty/cancellabledelay": "3.5.1-canary.545.2374fb2.0",
|
|
35
|
+
"@quenty/characterutils": "12.18.1-canary.545.2374fb2.0",
|
|
36
|
+
"@quenty/draw": "7.8.2-canary.545.2374fb2.0",
|
|
37
|
+
"@quenty/enumutils": "3.4.1-canary.545.2374fb2.0",
|
|
38
|
+
"@quenty/hapticfeedbackutils": "3.2.1-canary.545.2374fb2.0",
|
|
39
|
+
"@quenty/instanceutils": "13.17.1-canary.545.2374fb2.0",
|
|
40
|
+
"@quenty/loader": "10.8.1-canary.545.2374fb2.0",
|
|
41
|
+
"@quenty/maid": "3.4.1-canary.545.2374fb2.0",
|
|
42
|
+
"@quenty/motor6d": "7.20.1-canary.545.2374fb2.0",
|
|
43
|
+
"@quenty/physicsutils": "8.17.1-canary.545.2374fb2.0",
|
|
44
|
+
"@quenty/playerhumanoidbinder": "14.19.1-canary.545.2374fb2.0",
|
|
45
|
+
"@quenty/promise": "10.10.2-canary.545.2374fb2.0",
|
|
46
|
+
"@quenty/qframe": "10.10.2-canary.545.2374fb2.0",
|
|
47
|
+
"@quenty/r15utils": "13.17.1-canary.545.2374fb2.0",
|
|
48
|
+
"@quenty/remoting": "12.18.1-canary.545.2374fb2.0",
|
|
49
|
+
"@quenty/rx": "13.17.1-canary.545.2374fb2.0",
|
|
50
|
+
"@quenty/rxbinderutils": "14.19.1-canary.545.2374fb2.0",
|
|
51
|
+
"@quenty/rxsignal": "7.17.1-canary.545.2374fb2.0",
|
|
52
|
+
"@quenty/spring": "10.8.2-canary.545.2374fb2.0",
|
|
53
|
+
"@quenty/steputils": "3.5.4-canary.545.2374fb2.0",
|
|
54
|
+
"@quenty/table": "3.7.2-canary.545.2374fb2.0",
|
|
55
|
+
"@quenty/tie": "10.20.1-canary.545.2374fb2.0",
|
|
56
|
+
"@quenty/valuebaseutils": "13.17.1-canary.545.2374fb2.0",
|
|
57
|
+
"@quenty/valueobject": "13.17.1-canary.545.2374fb2.0"
|
|
58
58
|
},
|
|
59
59
|
"publishConfig": {
|
|
60
60
|
"access": "public"
|
|
61
61
|
},
|
|
62
|
-
"gitHead": "
|
|
62
|
+
"gitHead": "2374fb2b043cfbe0e9b507b3316eec46a4e353a0"
|
|
63
63
|
}
|
|
@@ -25,7 +25,7 @@ local RagdollCameraShakeClient = setmetatable({}, BaseObject)
|
|
|
25
25
|
RagdollCameraShakeClient.ClassName = "RagdollCameraShakeClient"
|
|
26
26
|
RagdollCameraShakeClient.__index = RagdollCameraShakeClient
|
|
27
27
|
|
|
28
|
-
function RagdollCameraShakeClient.new(humanoid, serviceBag)
|
|
28
|
+
function RagdollCameraShakeClient.new(humanoid: Humanoid, serviceBag)
|
|
29
29
|
local self = setmetatable(BaseObject.new(humanoid), RagdollCameraShakeClient)
|
|
30
30
|
|
|
31
31
|
self._serviceBag = assert(serviceBag, "No serviceBag")
|
|
@@ -76,7 +76,7 @@ end
|
|
|
76
76
|
function RagdollHumanoidOnDeathClient.disableParticleEmittersAndFadeOutYielding(character, duration)
|
|
77
77
|
local descendants = character:GetDescendants()
|
|
78
78
|
local transparencies = {}
|
|
79
|
-
for _, instance in
|
|
79
|
+
for _, instance in descendants do
|
|
80
80
|
if instance:IsA("BasePart") or instance:IsA("Decal") then
|
|
81
81
|
transparencies[instance] = instance.Transparency
|
|
82
82
|
elseif instance:IsA("ParticleEmitter") then
|
|
@@ -90,7 +90,7 @@ function RagdollHumanoidOnDeathClient.disableParticleEmittersAndFadeOutYielding(
|
|
|
90
90
|
local dt = RunService.Heartbeat:Wait()
|
|
91
91
|
t = t + dt
|
|
92
92
|
local alpha = math.min(t / duration, 1)
|
|
93
|
-
for part, initialTransparency in
|
|
93
|
+
for part, initialTransparency in transparencies do
|
|
94
94
|
part.Transparency = (1 - alpha) * initialTransparency + alpha
|
|
95
95
|
end
|
|
96
96
|
end
|
|
@@ -10,6 +10,7 @@ local require = require(script.Parent.loader).load(script)
|
|
|
10
10
|
local AttributeValue = require("AttributeValue")
|
|
11
11
|
|
|
12
12
|
local Players = game:GetService("Players")
|
|
13
|
+
local _ServiceBag = require("ServiceBag")
|
|
13
14
|
|
|
14
15
|
local RagdollServiceClient = {}
|
|
15
16
|
RagdollServiceClient.ServiceName = "RagdollServiceClient"
|
|
@@ -18,7 +19,7 @@ RagdollServiceClient.ServiceName = "RagdollServiceClient"
|
|
|
18
19
|
Initializes the ragdoll service on the client. Should be done via [ServiceBag].
|
|
19
20
|
@param serviceBag ServiceBag
|
|
20
21
|
]=]
|
|
21
|
-
function RagdollServiceClient:Init(serviceBag)
|
|
22
|
+
function RagdollServiceClient:Init(serviceBag: _ServiceBag.ServiceBag)
|
|
22
23
|
assert(not self._serviceBag, "Already initialized")
|
|
23
24
|
self._serviceBag = assert(serviceBag, "No serviceBag")
|
|
24
25
|
|
|
@@ -27,12 +28,12 @@ function RagdollServiceClient:Init(serviceBag)
|
|
|
27
28
|
self._serviceBag:GetService(require("CameraStackService"))
|
|
28
29
|
|
|
29
30
|
-- Internal
|
|
30
|
-
self._serviceBag:GetService(require("RagdollClient"))
|
|
31
|
-
self._serviceBag:GetService(require("RagdollableClient"))
|
|
32
|
-
self._serviceBag:GetService(require("RagdollHumanoidOnDeathClient"))
|
|
33
|
-
self._serviceBag:GetService(require("RagdollHumanoidOnFallClient"))
|
|
34
|
-
self._serviceBag:GetService(require("RagdollCameraShakeClient"))
|
|
35
|
-
self._serviceBag:GetService(require("RagdollBindersClient"))
|
|
31
|
+
self._serviceBag:GetService((require :: any)("RagdollClient"))
|
|
32
|
+
self._serviceBag:GetService((require :: any)("RagdollableClient"))
|
|
33
|
+
self._serviceBag:GetService((require :: any)("RagdollHumanoidOnDeathClient"))
|
|
34
|
+
self._serviceBag:GetService((require :: any)("RagdollHumanoidOnFallClient"))
|
|
35
|
+
self._serviceBag:GetService((require :: any)("RagdollCameraShakeClient"))
|
|
36
|
+
self._serviceBag:GetService((require :: any)("RagdollBindersClient"))
|
|
36
37
|
|
|
37
38
|
self._screenShakeEnabled = AttributeValue.new(Players.LocalPlayer, "RagdollScreenShakeEnabled", true)
|
|
38
39
|
end
|
|
@@ -41,7 +42,7 @@ end
|
|
|
41
42
|
Sets screen shake enabled for the local player
|
|
42
43
|
@param value boolelan
|
|
43
44
|
]=]
|
|
44
|
-
function RagdollServiceClient:SetScreenShakeEnabled(value)
|
|
45
|
+
function RagdollServiceClient:SetScreenShakeEnabled(value: boolean)
|
|
45
46
|
assert(type(value) == "boolean", "Bad value")
|
|
46
47
|
|
|
47
48
|
self._screenShakeEnabled.Value = value
|
|
@@ -20,7 +20,7 @@ RagdollCameraShake.__index = RagdollCameraShake
|
|
|
20
20
|
@param serviceBag ServiceBag
|
|
21
21
|
@return RagdollCameraShake
|
|
22
22
|
]=]
|
|
23
|
-
function RagdollCameraShake.new(humanoid, serviceBag)
|
|
23
|
+
function RagdollCameraShake.new(humanoid: Humanoid, serviceBag)
|
|
24
24
|
local self = setmetatable(BaseObject.new(humanoid), RagdollCameraShake)
|
|
25
25
|
|
|
26
26
|
self._serviceBag = assert(serviceBag, "Bad serviceBag")
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
Initializes ragdoll related binders
|
|
3
4
|
|
|
@@ -7,6 +8,8 @@
|
|
|
7
8
|
|
|
8
9
|
local require = require(script.Parent.loader).load(script)
|
|
9
10
|
|
|
11
|
+
local _ServiceBag = require("ServiceBag")
|
|
12
|
+
|
|
10
13
|
local RagdollService = {}
|
|
11
14
|
RagdollService.ServiceName = "RagdollService"
|
|
12
15
|
|
|
@@ -14,7 +17,7 @@ RagdollService.ServiceName = "RagdollService"
|
|
|
14
17
|
Initializes the ragdoll service on the server. Should be done via [ServiceBag].
|
|
15
18
|
@param serviceBag ServiceBag
|
|
16
19
|
]=]
|
|
17
|
-
function RagdollService:Init(serviceBag)
|
|
20
|
+
function RagdollService:Init(serviceBag: _ServiceBag.ServiceBag)
|
|
18
21
|
assert(not self._serviceBag, "Already initialized")
|
|
19
22
|
self._serviceBag = assert(serviceBag, "No serviceBag")
|
|
20
23
|
|
|
@@ -25,17 +28,17 @@ function RagdollService:Init(serviceBag)
|
|
|
25
28
|
self._serviceBag:GetService(require("RagdollBindersServer"))
|
|
26
29
|
|
|
27
30
|
-- Binders
|
|
28
|
-
self._serviceBag:GetService(require("Ragdoll"))
|
|
29
|
-
self._serviceBag:GetService(require("Ragdollable"))
|
|
30
|
-
self._serviceBag:GetService(require("RagdollHumanoidOnDeath"))
|
|
31
|
-
self._serviceBag:GetService(require("RagdollHumanoidOnFall"))
|
|
32
|
-
self._serviceBag:GetService(require("UnragdollAutomatically"))
|
|
33
|
-
self._serviceBag:GetService(require("RagdollCameraShake"))
|
|
31
|
+
self._serviceBag:GetService((require :: any)("Ragdoll"))
|
|
32
|
+
self._serviceBag:GetService((require :: any)("Ragdollable"))
|
|
33
|
+
self._serviceBag:GetService((require :: any)("RagdollHumanoidOnDeath"))
|
|
34
|
+
self._serviceBag:GetService((require :: any)("RagdollHumanoidOnFall"))
|
|
35
|
+
self._serviceBag:GetService((require :: any)("UnragdollAutomatically"))
|
|
36
|
+
self._serviceBag:GetService((require :: any)("RagdollCameraShake"))
|
|
34
37
|
|
|
35
38
|
-- Configure
|
|
36
|
-
self._serviceBag:GetService(require("RagdollHumanoidOnDeath")):SetAutomaticTagging(false)
|
|
37
|
-
self._serviceBag:GetService(require("RagdollHumanoidOnFall")):SetAutomaticTagging(false)
|
|
38
|
-
self._serviceBag:GetService(require("UnragdollAutomatically")):SetAutomaticTagging(false)
|
|
39
|
+
self._serviceBag:GetService((require :: any)("RagdollHumanoidOnDeath")):SetAutomaticTagging(false)
|
|
40
|
+
self._serviceBag:GetService((require :: any)("RagdollHumanoidOnFall")):SetAutomaticTagging(false)
|
|
41
|
+
self._serviceBag:GetService((require :: any)("UnragdollAutomatically")):SetAutomaticTagging(false)
|
|
39
42
|
end
|
|
40
43
|
|
|
41
44
|
--[=[
|
|
@@ -73,7 +73,7 @@ end
|
|
|
73
73
|
function BindableRagdollHumanoidOnFall:_getLargestSpeedInRecords()
|
|
74
74
|
local largestSpeed = -math.huge
|
|
75
75
|
|
|
76
|
-
for _, velocityRecord in
|
|
76
|
+
for _, velocityRecord in self._lastVelocityRecords do
|
|
77
77
|
local speed = velocityRecord.magnitude
|
|
78
78
|
if speed > largestSpeed then
|
|
79
79
|
largestSpeed = speed
|
|
@@ -87,9 +87,7 @@ function BindableRagdollHumanoidOnFall:_ragdollFromFall()
|
|
|
87
87
|
self.ShouldRagdoll.Value = true
|
|
88
88
|
|
|
89
89
|
task.spawn(function()
|
|
90
|
-
while self.Destroy
|
|
91
|
-
and self:_getLargestSpeedInRecords() >= 3
|
|
92
|
-
and self.ShouldRagdoll.Value do
|
|
90
|
+
while self.Destroy and self:_getLargestSpeedInRecords() >= 3 and self.ShouldRagdoll.Value do
|
|
93
91
|
task.wait(0.05)
|
|
94
92
|
end
|
|
95
93
|
|
|
@@ -117,7 +115,7 @@ function BindableRagdollHumanoidOnFall:_updateVelocity()
|
|
|
117
115
|
|
|
118
116
|
local fellForAllFrames = true
|
|
119
117
|
local mostNegativeVelocityY = math.huge
|
|
120
|
-
for _, velocityRecord in
|
|
118
|
+
for _, velocityRecord in self._lastVelocityRecords do
|
|
121
119
|
if velocityRecord.y >= -2 then
|
|
122
120
|
fellForAllFrames = false
|
|
123
121
|
break
|
|
@@ -62,7 +62,7 @@ function RagdollAdditionalAttachmentUtils.ensureAdditionalAttachments(character,
|
|
|
62
62
|
|
|
63
63
|
local topMaid = Maid.new()
|
|
64
64
|
|
|
65
|
-
for _, data in
|
|
65
|
+
for _, data in RagdollAdditionalAttachmentUtils.getAdditionalAttachmentData(rigType) do
|
|
66
66
|
local partName, attachmentName, cframe, baseAttachmentName = unpack(data)
|
|
67
67
|
|
|
68
68
|
if baseAttachmentName then
|
|
@@ -196,7 +196,7 @@ function RagdollBallSocketUtils.ensureBallSockets(character, rigType)
|
|
|
196
196
|
|
|
197
197
|
local topMaid = Maid.new()
|
|
198
198
|
|
|
199
|
-
for _, data in
|
|
199
|
+
for _, data in RagdollBallSocketUtils.getRigData(rigType) do
|
|
200
200
|
local part0Name = assert(data.part0Name, "No part0Name")
|
|
201
201
|
local part1Name = assert(data.part1Name, "No part1Name")
|
|
202
202
|
local motorName = assert(data.motorName, "No motorName")
|
|
@@ -262,7 +262,7 @@ function RagdollBallSocketUtils.ensureBallSockets(character, rigType)
|
|
|
262
262
|
mass = RxPhysicsUtils.observePartMass(motorState.part1);
|
|
263
263
|
}):Subscribe(function(state)
|
|
264
264
|
local gravityScale = state.gravity / state.referenceGravity
|
|
265
|
-
local referenceMass = state.referenceMass
|
|
265
|
+
local referenceMass = state.referenceMass
|
|
266
266
|
local massScale = referenceMass and (state.mass / referenceMass) or 1
|
|
267
267
|
ballSocket.MaxFrictionTorque = state.frictionTorque * massScale * gravityScale
|
|
268
268
|
end))
|
|
@@ -86,7 +86,7 @@ local R6_NO_COLLIDES = {
|
|
|
86
86
|
{"HumanoidRootPart", "Left Arm"},
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
function RagdollCollisionUtils.getCollisionData(rigType)
|
|
89
|
+
function RagdollCollisionUtils.getCollisionData(rigType: Enum.HumanoidRigType)
|
|
90
90
|
if rigType == Enum.HumanoidRigType.R15 then
|
|
91
91
|
return R15_NO_COLLIDES
|
|
92
92
|
elseif rigType == Enum.HumanoidRigType.R6 then
|
|
@@ -96,10 +96,10 @@ function RagdollCollisionUtils.getCollisionData(rigType)
|
|
|
96
96
|
end
|
|
97
97
|
end
|
|
98
98
|
|
|
99
|
-
function RagdollCollisionUtils.preventCollisionAmongOthers(character, part)
|
|
99
|
+
function RagdollCollisionUtils.preventCollisionAmongOthers(character: Model, part: BasePart)
|
|
100
100
|
local topMaid = Maid.new()
|
|
101
101
|
|
|
102
|
-
for _, partName in
|
|
102
|
+
for _, partName in R15_PARTS do
|
|
103
103
|
topMaid:GiveTask(RxR15Utils.observeCharacterPartBrio(character, partName):Subscribe(function(brio)
|
|
104
104
|
if brio:IsDead() then
|
|
105
105
|
return
|
|
@@ -120,13 +120,13 @@ function RagdollCollisionUtils.preventCollisionAmongOthers(character, part)
|
|
|
120
120
|
return topMaid
|
|
121
121
|
end
|
|
122
122
|
|
|
123
|
-
function RagdollCollisionUtils.ensureNoCollides(character, rigType)
|
|
123
|
+
function RagdollCollisionUtils.ensureNoCollides(character: Model, rigType: Enum.HumanoidRigType)
|
|
124
124
|
assert(typeof(character) == "Instance" and character:IsA("Model"), "Bad character")
|
|
125
125
|
assert(EnumUtils.isOfType(Enum.HumanoidRigType, rigType), "Bad rigType")
|
|
126
126
|
|
|
127
127
|
local topMaid = Maid.new()
|
|
128
128
|
|
|
129
|
-
for _, data in
|
|
129
|
+
for _, data in RagdollCollisionUtils.getCollisionData(rigType) do
|
|
130
130
|
local part0Name, part1Name = unpack(data)
|
|
131
131
|
|
|
132
132
|
local observable = RxBrioUtils.flatCombineLatest({
|
|
@@ -24,7 +24,15 @@ local Spring = require("Spring")
|
|
|
24
24
|
|
|
25
25
|
local RagdollMotorUtils = {}
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
type MotorData = {
|
|
28
|
+
partName: string,
|
|
29
|
+
motorName: string,
|
|
30
|
+
isRootJoint: boolean?,
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
type MotorDataList = { MotorData }
|
|
34
|
+
|
|
35
|
+
local R6_MOTORS: MotorDataList = {
|
|
28
36
|
{
|
|
29
37
|
partName = "Torso",
|
|
30
38
|
motorName = "Root",
|
|
@@ -52,7 +60,7 @@ local R6_MOTORS = {
|
|
|
52
60
|
},
|
|
53
61
|
}
|
|
54
62
|
|
|
55
|
-
local R15_MOTORS = {
|
|
63
|
+
local R15_MOTORS: MotorDataList = {
|
|
56
64
|
{
|
|
57
65
|
partName = "LowerTorso",
|
|
58
66
|
motorName = "Root",
|
|
@@ -118,12 +126,12 @@ local R15_MOTORS = {
|
|
|
118
126
|
|
|
119
127
|
local ROOT_JOINT_CACHE = {}
|
|
120
128
|
|
|
121
|
-
function RagdollMotorUtils.getFirstRootJointData(rigType)
|
|
129
|
+
function RagdollMotorUtils.getFirstRootJointData(rigType: Enum.HumanoidRigType): MotorData
|
|
122
130
|
if ROOT_JOINT_CACHE[rigType] then
|
|
123
131
|
return ROOT_JOINT_CACHE[rigType]
|
|
124
132
|
end
|
|
125
133
|
|
|
126
|
-
for _, item in
|
|
134
|
+
for _, item in RagdollMotorUtils.getMotorData(rigType) do
|
|
127
135
|
if item.isRootJoint then
|
|
128
136
|
ROOT_JOINT_CACHE[rigType] = item
|
|
129
137
|
return item
|
|
@@ -133,7 +141,7 @@ function RagdollMotorUtils.getFirstRootJointData(rigType)
|
|
|
133
141
|
error("Could not find root joint data")
|
|
134
142
|
end
|
|
135
143
|
|
|
136
|
-
function RagdollMotorUtils.getMotorData(rigType)
|
|
144
|
+
function RagdollMotorUtils.getMotorData(rigType: Enum.HumanoidRigType): MotorDataList
|
|
137
145
|
if rigType == Enum.HumanoidRigType.R15 then
|
|
138
146
|
return R15_MOTORS
|
|
139
147
|
elseif rigType == Enum.HumanoidRigType.R6 then
|
|
@@ -143,11 +151,11 @@ function RagdollMotorUtils.getMotorData(rigType)
|
|
|
143
151
|
end
|
|
144
152
|
end
|
|
145
153
|
|
|
146
|
-
function RagdollMotorUtils.initMotorAttributes(character, rigType)
|
|
154
|
+
function RagdollMotorUtils.initMotorAttributes(character, rigType: Enum.HumanoidRigType)
|
|
147
155
|
assert(typeof(character) == "Instance" and character:IsA("Model"), "Bad character")
|
|
148
156
|
assert(EnumUtils.isOfType(Enum.HumanoidRigType, rigType), "Bad rigType")
|
|
149
157
|
|
|
150
|
-
for _, data in
|
|
158
|
+
for _, data in RagdollMotorUtils.getMotorData(rigType) do
|
|
151
159
|
local motor = R15Utils.getRigMotor(character, data.partName, data.motorName)
|
|
152
160
|
if motor then
|
|
153
161
|
RagdollMotorData:InitAttributes(motor)
|
|
@@ -155,7 +163,7 @@ function RagdollMotorUtils.initMotorAttributes(character, rigType)
|
|
|
155
163
|
end
|
|
156
164
|
end
|
|
157
165
|
|
|
158
|
-
function RagdollMotorUtils.setupAnimatedMotor(character, part)
|
|
166
|
+
function RagdollMotorUtils.setupAnimatedMotor(character: Model, part: BasePart)
|
|
159
167
|
local maid = Maid.new()
|
|
160
168
|
|
|
161
169
|
-- make this stuff not physics collide with our own rig
|
|
@@ -165,7 +173,7 @@ function RagdollMotorUtils.setupAnimatedMotor(character, part)
|
|
|
165
173
|
return maid
|
|
166
174
|
end
|
|
167
175
|
|
|
168
|
-
function RagdollMotorUtils.setupRagdollRootPartMotor(motor, part0, part1)
|
|
176
|
+
function RagdollMotorUtils.setupRagdollRootPartMotor(motor: Motor6D, part0, part1)
|
|
169
177
|
local maid = Maid.new()
|
|
170
178
|
|
|
171
179
|
local ragdollMotorData = RagdollMotorData:Create(motor)
|
|
@@ -199,6 +207,13 @@ function RagdollMotorUtils.setupRagdollRootPartMotor(motor, part0, part1)
|
|
|
199
207
|
weld.C0 = innerState.C0 * innerState.Transform
|
|
200
208
|
end))
|
|
201
209
|
|
|
210
|
+
-- if weld:IsA("Motor6D") then
|
|
211
|
+
-- -- Suppress animations on any weld connection
|
|
212
|
+
-- weldMaid:GiveTask(RunService.Stepped:Connect(function()
|
|
213
|
+
-- weld.Transform = CFrame.new()
|
|
214
|
+
-- end))
|
|
215
|
+
-- end
|
|
216
|
+
|
|
202
217
|
weldMaid:GiveTask(RxInstanceUtils.observeProperty(motor, "C1"):Subscribe(function(c1)
|
|
203
218
|
weld.C1 = c1
|
|
204
219
|
end))
|
|
@@ -222,6 +237,15 @@ function RagdollMotorUtils.setupRagdollRootPartMotor(motor, part0, part1)
|
|
|
222
237
|
lastTransformSpring.s = speed
|
|
223
238
|
end))
|
|
224
239
|
|
|
240
|
+
-- Lerp smoothly to 0 to avoid jarring camera.
|
|
241
|
+
-- maid:GiveTask(RunService.Stepped:Connect(function()
|
|
242
|
+
-- local target = QFrame.toCFrame(lastTransformSpring.p)
|
|
243
|
+
-- if target then
|
|
244
|
+
-- transformValue.Value = target
|
|
245
|
+
-- motor.Transform = target
|
|
246
|
+
-- end
|
|
247
|
+
-- end))
|
|
248
|
+
|
|
225
249
|
motor.Enabled = false
|
|
226
250
|
|
|
227
251
|
maid:GiveTask(function()
|
|
@@ -231,7 +255,7 @@ function RagdollMotorUtils.setupRagdollRootPartMotor(motor, part0, part1)
|
|
|
231
255
|
return maid
|
|
232
256
|
end
|
|
233
257
|
|
|
234
|
-
function RagdollMotorUtils.setupRagdollMotor(motor, part0, part1)
|
|
258
|
+
function RagdollMotorUtils.setupRagdollMotor(motor: Motor6D, part0: BasePart, part1: BasePart)
|
|
235
259
|
local maid = Maid.new()
|
|
236
260
|
|
|
237
261
|
motor.Enabled = false
|
|
@@ -239,7 +263,7 @@ function RagdollMotorUtils.setupRagdollMotor(motor, part0, part1)
|
|
|
239
263
|
local implemention = Motor6DStackInterface:FindFirstImplementation(motor)
|
|
240
264
|
if implemention then
|
|
241
265
|
local ragdollMotorData = RagdollMotorData:Create(motor)
|
|
242
|
-
local initialTransform = (part0.CFrame * motor.C0):
|
|
266
|
+
local initialTransform = (part0.CFrame * motor.C0):ToObjectSpace(part1.CFrame * motor.C1)
|
|
243
267
|
local speed = ragdollMotorData.RagdollSpringReturnSpeed.Value
|
|
244
268
|
|
|
245
269
|
implemention:TransformFromCFrame(initialTransform, speed)
|
|
@@ -255,7 +279,7 @@ function RagdollMotorUtils.setupRagdollMotor(motor, part0, part1)
|
|
|
255
279
|
return maid
|
|
256
280
|
end
|
|
257
281
|
|
|
258
|
-
function RagdollMotorUtils.suppressJustRootPart(character, rigType)
|
|
282
|
+
function RagdollMotorUtils.suppressJustRootPart(character: Model, rigType: Enum.HumanoidRigType)
|
|
259
283
|
local data = RagdollMotorUtils.getFirstRootJointData(rigType)
|
|
260
284
|
|
|
261
285
|
local observable = RxR15Utils.observeRigMotorBrio(character, data.partName, data.motorName):Pipe({
|
|
@@ -295,13 +319,13 @@ function RagdollMotorUtils.suppressJustRootPart(character, rigType)
|
|
|
295
319
|
return topMaid
|
|
296
320
|
end
|
|
297
321
|
|
|
298
|
-
function RagdollMotorUtils.suppressMotors(character, rigType, velocityReadings)
|
|
322
|
+
function RagdollMotorUtils.suppressMotors(character: Model, rigType: Enum.HumanoidRigType, velocityReadings)
|
|
299
323
|
assert(typeof(character) == "Instance" and character:IsA("Model"), "Bad character")
|
|
300
324
|
assert(EnumUtils.isOfType(Enum.HumanoidRigType, rigType), "Bad rigType")
|
|
301
325
|
|
|
302
326
|
local topMaid = Maid.new()
|
|
303
327
|
|
|
304
|
-
for _, data in
|
|
328
|
+
for _, data in RagdollMotorUtils.getMotorData(rigType) do
|
|
305
329
|
local observable = RxR15Utils.observeRigMotorBrio(character, data.partName, data.motorName):Pipe({
|
|
306
330
|
RxBrioUtils.switchMapBrio(function(motor)
|
|
307
331
|
local ragdollMotorData = RagdollMotorData:Create(motor)
|
|
@@ -346,12 +370,12 @@ function RagdollMotorUtils.suppressMotors(character, rigType, velocityReadings)
|
|
|
346
370
|
if passed <= 0.1 then
|
|
347
371
|
local rotVelocity = velocityReadings.rotation[data]
|
|
348
372
|
if rotVelocity then
|
|
349
|
-
state.part1.
|
|
373
|
+
state.part1.AssemblyAngularVelocity += rotVelocity
|
|
350
374
|
end
|
|
351
375
|
|
|
352
376
|
local velocity = velocityReadings.linear[data]
|
|
353
377
|
if velocity then
|
|
354
|
-
state.part1.
|
|
378
|
+
state.part1.AssemblyLinearVelocity += velocity
|
|
355
379
|
end
|
|
356
380
|
end
|
|
357
381
|
end)
|
|
@@ -363,7 +387,7 @@ function RagdollMotorUtils.suppressMotors(character, rigType, velocityReadings)
|
|
|
363
387
|
return topMaid
|
|
364
388
|
end
|
|
365
389
|
|
|
366
|
-
function RagdollMotorUtils.guessIfNetworkOwner(part)
|
|
390
|
+
function RagdollMotorUtils.guessIfNetworkOwner(part: BasePart): boolean
|
|
367
391
|
local currentNetworkOwner
|
|
368
392
|
local expectedNetworkOwner = Players.LocalPlayer
|
|
369
393
|
|
|
@@ -382,19 +406,19 @@ function RagdollMotorUtils.guessIfNetworkOwner(part)
|
|
|
382
406
|
return CharacterUtils.getPlayerFromCharacter(part) == expectedNetworkOwner
|
|
383
407
|
end
|
|
384
408
|
|
|
385
|
-
function RagdollMotorUtils.promiseVelocityRecordings(character, rigType)
|
|
409
|
+
function RagdollMotorUtils.promiseVelocityRecordings(character: Model, rigType: Enum.HumanoidRigType)
|
|
386
410
|
assert(typeof(character) == "Instance" and character:IsA("Model"), "Bad character")
|
|
387
411
|
assert(EnumUtils.isOfType(Enum.HumanoidRigType, rigType), "Bad rigType")
|
|
388
412
|
|
|
389
413
|
local parts = {}
|
|
390
414
|
|
|
391
415
|
local rootPart = character:FindFirstChild("HumanoidRootPart")
|
|
392
|
-
if not rootPart then
|
|
416
|
+
if rootPart == nil or not rootPart:IsA("BasePart") then
|
|
393
417
|
return Promise.rejected("No humanoid root part")
|
|
394
418
|
end
|
|
395
419
|
|
|
396
420
|
local initialRootPartCFrame = rootPart.CFrame
|
|
397
|
-
for _, data in
|
|
421
|
+
for _, data in RagdollMotorUtils.getMotorData(rigType) do
|
|
398
422
|
local motor = R15Utils.getRigMotor(character, data.partName, data.motorName)
|
|
399
423
|
if motor then
|
|
400
424
|
local part0 = motor.Part0
|
|
@@ -404,7 +428,7 @@ function RagdollMotorUtils.promiseVelocityRecordings(character, rigType)
|
|
|
404
428
|
motor = motor,
|
|
405
429
|
part0 = part0,
|
|
406
430
|
part1 = part1,
|
|
407
|
-
relCFrame = initialRootPartCFrame:
|
|
431
|
+
relCFrame = initialRootPartCFrame:ToObjectSpace(part1.CFrame),
|
|
408
432
|
}
|
|
409
433
|
end
|
|
410
434
|
end
|
|
@@ -423,21 +447,21 @@ function RagdollMotorUtils.promiseVelocityRecordings(character, rigType)
|
|
|
423
447
|
rotation = {},
|
|
424
448
|
}
|
|
425
449
|
|
|
426
|
-
for data, info in
|
|
450
|
+
for data, info in parts do
|
|
427
451
|
local motor = R15Utils.getRigMotor(character, data.partName, data.motorName)
|
|
428
452
|
|
|
429
453
|
-- Validate all the same
|
|
430
|
-
if info.motor == motor and info.part0 == motor.Part0 and info.part1 == motor.Part1 then
|
|
431
|
-
local linear = newRootPartCFrame:
|
|
432
|
-
result.linear[data] = newRootPartCFrame:
|
|
454
|
+
if motor ~= nil and info.motor == motor and info.part0 == motor.Part0 and info.part1 == motor.Part1 then
|
|
455
|
+
local linear = newRootPartCFrame:PointToObjectSpace(info.part1.Position) - info.relCFrame.Position
|
|
456
|
+
result.linear[data] = newRootPartCFrame:VectorToWorldSpace(linear / dt)
|
|
433
457
|
|
|
434
|
-
local change = info.relCFrame:
|
|
458
|
+
local change = info.relCFrame:ToObjectSpace(newRootPartCFrame:ToObjectSpace(info.part1.CFrame))
|
|
435
459
|
|
|
436
460
|
-- assume that we're XYZ ordered
|
|
437
461
|
local x, y, z = change:ToEulerAnglesXYZ()
|
|
438
462
|
|
|
439
|
-
local vector = newRootPartCFrame:
|
|
440
|
-
result.rotation[data] = vector
|
|
463
|
+
local vector = newRootPartCFrame:VectorToWorldSpace(Vector3.new(x, y, z))
|
|
464
|
+
result.rotation[data] = vector/dt
|
|
441
465
|
end
|
|
442
466
|
end
|
|
443
467
|
|
|
@@ -181,7 +181,7 @@ function RxRagdollUtils.runLocal(humanoid: Humanoid)
|
|
|
181
181
|
:Then(function(velocityReadings)
|
|
182
182
|
debug.profilebegin("initragdoll")
|
|
183
183
|
|
|
184
|
-
|
|
184
|
+
maid:GiveTask(RxRagdollUtils.suppressRootPartCollision(character))
|
|
185
185
|
maid:GiveTask(RxRagdollUtils.enforceHeadCollision(character))
|
|
186
186
|
maid:GiveTask(RxRagdollUtils.enforceHumanoidStateMachineOff(character, humanoid))
|
|
187
187
|
|