@quenty/ik 15.24.3 → 15.24.4-canary.11a5dcf.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 +27 -27
- package/src/Client/GripPointer.lua +3 -3
- package/src/Client/IKServiceClient.lua +3 -3
- package/src/Client/Rig/IKRigAimerLocalPlayer.lua +3 -3
- package/src/Client/Rig/IKRigClient.lua +3 -2
- package/src/Server/IKService.lua +2 -2
- package/src/Server/Rig/IKRig.lua +4 -3
- package/src/Shared/Arm/ArmIKBase.lua +150 -105
- package/src/Shared/Arm/ArmIKBase.story.lua +5 -5
- package/src/Shared/Arm/ArmIKUtils.lua +11 -5
- package/src/Shared/Arm/IKAimPositionPriorites.lua +5 -5
- package/src/Shared/Grip/IKGripBase.lua +11 -11
- package/src/Shared/Grip/IKGripUtils.lua +1 -1
- package/src/Shared/Grip/IKLeftGrip.lua +4 -3
- package/src/Shared/Grip/IKRightGrip.lua +4 -3
- package/src/Shared/IKDataService.lua +2 -2
- package/src/Shared/IKUtils.lua +8 -4
- package/src/Shared/Interfaces/IKRigInterface.lua +8 -8
- package/src/Shared/Resources/IKResource.lua +2 -2
- package/src/Shared/Resources/IKResourceUtils.lua +1 -1
- package/src/Shared/Rig/IKRigBase.lua +4 -4
- package/src/Shared/Rig/IKRigUtils.lua +3 -3
- package/src/Shared/Torso/TorsoIKBase.lua +2 -2
- package/src/Shared/Torso/TorsoIKUtils.lua +11 -20
- package/test/scripts/Server/ServerMain.server.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.24.4-canary.11a5dcf.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/ik@15.24.3...@quenty/ik@15.24.4-canary.11a5dcf.0) (2025-05-10)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* Additional type checking updates ([05ba29a](https://github.com/Quenty/NevermoreEngine/commit/05ba29a03efc9f3feed74b34f1d9dfb237496214))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
## [15.24.3](https://github.com/Quenty/NevermoreEngine/compare/@quenty/ik@15.24.2...@quenty/ik@15.24.3) (2025-04-10)
|
|
7
18
|
|
|
8
19
|
**Note:** Version bump only for package @quenty/ik
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quenty/ik",
|
|
3
|
-
"version": "15.24.
|
|
3
|
+
"version": "15.24.4-canary.11a5dcf.0",
|
|
4
4
|
"description": "Inverse Kinematics for characters on Roblox",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Roblox",
|
|
@@ -26,36 +26,36 @@
|
|
|
26
26
|
"Quenty"
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@quenty/acceltween": "
|
|
30
|
-
"@quenty/baseobject": "
|
|
31
|
-
"@quenty/binder": "
|
|
32
|
-
"@quenty/brio": "
|
|
33
|
-
"@quenty/camera": "
|
|
34
|
-
"@quenty/characterutils": "
|
|
35
|
-
"@quenty/humanoidtracker": "
|
|
36
|
-
"@quenty/instanceutils": "
|
|
37
|
-
"@quenty/loader": "
|
|
38
|
-
"@quenty/maid": "
|
|
39
|
-
"@quenty/math": "
|
|
40
|
-
"@quenty/motor6d": "
|
|
41
|
-
"@quenty/optional": "
|
|
42
|
-
"@quenty/promise": "
|
|
43
|
-
"@quenty/qframe": "
|
|
44
|
-
"@quenty/r15utils": "
|
|
45
|
-
"@quenty/ragdoll": "
|
|
46
|
-
"@quenty/remoting": "
|
|
47
|
-
"@quenty/rx": "
|
|
48
|
-
"@quenty/servicebag": "
|
|
49
|
-
"@quenty/signal": "
|
|
50
|
-
"@quenty/table": "
|
|
51
|
-
"@quenty/tie": "
|
|
52
|
-
"@quenty/valueobject": "
|
|
29
|
+
"@quenty/acceltween": "2.5.3",
|
|
30
|
+
"@quenty/baseobject": "10.8.4-canary.11a5dcf.0",
|
|
31
|
+
"@quenty/binder": "14.19.4-canary.11a5dcf.0",
|
|
32
|
+
"@quenty/brio": "14.17.4-canary.11a5dcf.0",
|
|
33
|
+
"@quenty/camera": "14.20.4-canary.11a5dcf.0",
|
|
34
|
+
"@quenty/characterutils": "12.18.4-canary.11a5dcf.0",
|
|
35
|
+
"@quenty/humanoidtracker": "13.17.4-canary.11a5dcf.0",
|
|
36
|
+
"@quenty/instanceutils": "13.17.4-canary.11a5dcf.0",
|
|
37
|
+
"@quenty/loader": "10.8.4-canary.11a5dcf.0",
|
|
38
|
+
"@quenty/maid": "3.4.4-canary.11a5dcf.0",
|
|
39
|
+
"@quenty/math": "2.7.3",
|
|
40
|
+
"@quenty/motor6d": "7.20.4-canary.11a5dcf.0",
|
|
41
|
+
"@quenty/optional": "11.8.4-canary.11a5dcf.0",
|
|
42
|
+
"@quenty/promise": "10.10.5-canary.11a5dcf.0",
|
|
43
|
+
"@quenty/qframe": "10.10.5-canary.11a5dcf.0",
|
|
44
|
+
"@quenty/r15utils": "13.17.4-canary.11a5dcf.0",
|
|
45
|
+
"@quenty/ragdoll": "15.23.4-canary.11a5dcf.0",
|
|
46
|
+
"@quenty/remoting": "12.18.4-canary.11a5dcf.0",
|
|
47
|
+
"@quenty/rx": "13.17.4-canary.11a5dcf.0",
|
|
48
|
+
"@quenty/servicebag": "11.11.5-canary.11a5dcf.0",
|
|
49
|
+
"@quenty/signal": "7.10.4-canary.11a5dcf.0",
|
|
50
|
+
"@quenty/table": "3.7.5-canary.11a5dcf.0",
|
|
51
|
+
"@quenty/tie": "10.20.4-canary.11a5dcf.0",
|
|
52
|
+
"@quenty/valueobject": "13.17.4-canary.11a5dcf.0"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
|
-
"@quenty/rigbuilderutils": "
|
|
55
|
+
"@quenty/rigbuilderutils": "10.19.4-canary.11a5dcf.0"
|
|
56
56
|
},
|
|
57
57
|
"publishConfig": {
|
|
58
58
|
"access": "public"
|
|
59
59
|
},
|
|
60
|
-
"gitHead": "
|
|
60
|
+
"gitHead": "11a5dcf7d4c7a0bfbf3337e97d30e8346ea09d3f"
|
|
61
61
|
}
|
|
@@ -22,7 +22,7 @@ function GripPointer.new(ikRig)
|
|
|
22
22
|
return self
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
function GripPointer:SetLeftGrip(leftGrip)
|
|
25
|
+
function GripPointer:SetLeftGrip(leftGrip: Attachment)
|
|
26
26
|
self._leftGripAttachment = leftGrip
|
|
27
27
|
|
|
28
28
|
if not self._leftGripAttachment then
|
|
@@ -37,7 +37,7 @@ function GripPointer:SetLeftGrip(leftGrip)
|
|
|
37
37
|
self._maid._leftGripMaid = maid
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
-
function GripPointer:SetRightGrip(rightGrip)
|
|
40
|
+
function GripPointer:SetRightGrip(rightGrip: Attachment)
|
|
41
41
|
self._rightGripAttachment = rightGrip
|
|
42
42
|
|
|
43
43
|
if not self._rightGripAttachment then
|
|
@@ -52,4 +52,4 @@ function GripPointer:SetRightGrip(rightGrip)
|
|
|
52
52
|
self._maid._rightArmMaid = maid
|
|
53
53
|
end
|
|
54
54
|
|
|
55
|
-
return GripPointer
|
|
55
|
+
return GripPointer
|
|
@@ -12,13 +12,13 @@
|
|
|
12
12
|
|
|
13
13
|
local require = require(script.Parent.loader).load(script)
|
|
14
14
|
|
|
15
|
+
local Players = game:GetService("Players")
|
|
15
16
|
local RunService = game:GetService("RunService")
|
|
16
17
|
local Workspace = game:GetService("Workspace")
|
|
17
|
-
local Players = game:GetService("Players")
|
|
18
18
|
|
|
19
19
|
local IKRigUtils = require("IKRigUtils")
|
|
20
20
|
local Maid = require("Maid")
|
|
21
|
-
local
|
|
21
|
+
local ServiceBag = require("ServiceBag")
|
|
22
22
|
|
|
23
23
|
local IKServiceClient = {}
|
|
24
24
|
IKServiceClient.ServiceName = "IKServiceClient"
|
|
@@ -39,7 +39,7 @@ IKServiceClient.ServiceName = "IKServiceClient"
|
|
|
39
39
|
|
|
40
40
|
@param serviceBag ServiceBag
|
|
41
41
|
]=]
|
|
42
|
-
function IKServiceClient:Init(serviceBag:
|
|
42
|
+
function IKServiceClient:Init(serviceBag: ServiceBag.ServiceBag)
|
|
43
43
|
assert(not self._serviceBag, "Already initialized")
|
|
44
44
|
|
|
45
45
|
self._serviceBag = assert(serviceBag, "No serviceBag")
|
|
@@ -81,7 +81,7 @@ function IKRigAimerLocalPlayer:PushReplicationRate(replicateRate: number)
|
|
|
81
81
|
assert(type(replicateRate) == "number", "Bad replicateRate")
|
|
82
82
|
|
|
83
83
|
local data = {
|
|
84
|
-
replicateRate = replicateRate
|
|
84
|
+
replicateRate = replicateRate,
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
table.insert(self._replicationRates, data)
|
|
@@ -118,7 +118,7 @@ end
|
|
|
118
118
|
]=]
|
|
119
119
|
function IKRigAimerLocalPlayer:GetAimPosition()
|
|
120
120
|
if self._aimData and (os.clock() - self._aimData.timeStamp) < MAX_AGE_FOR_AIM_DATA then
|
|
121
|
-
|
|
121
|
+
-- If we have aim data within the last 0.2 seconds start pointing at that
|
|
122
122
|
return self._aimData.position -- May be nil
|
|
123
123
|
end
|
|
124
124
|
|
|
@@ -173,4 +173,4 @@ function IKRigAimerLocalPlayer:UpdateStepped()
|
|
|
173
173
|
end
|
|
174
174
|
end
|
|
175
175
|
|
|
176
|
-
return IKRigAimerLocalPlayer
|
|
176
|
+
return IKRigAimerLocalPlayer
|
|
@@ -12,12 +12,13 @@ local IKRigAimerLocalPlayer = require("IKRigAimerLocalPlayer")
|
|
|
12
12
|
local IKRigBase = require("IKRigBase")
|
|
13
13
|
local IKRigInterface = require("IKRigInterface")
|
|
14
14
|
local Remoting = require("Remoting")
|
|
15
|
+
local ServiceBag = require("ServiceBag")
|
|
15
16
|
|
|
16
17
|
local IKRigClient = setmetatable({}, IKRigBase)
|
|
17
18
|
IKRigClient.ClassName = "IKRigClient"
|
|
18
19
|
IKRigClient.__index = IKRigClient
|
|
19
20
|
|
|
20
|
-
function IKRigClient.new(humanoid: Humanoid, serviceBag)
|
|
21
|
+
function IKRigClient.new(humanoid: Humanoid, serviceBag: ServiceBag.ServiceBag)
|
|
21
22
|
local self = setmetatable(IKRigBase.new(humanoid, serviceBag), IKRigClient)
|
|
22
23
|
|
|
23
24
|
self._serviceBag = assert(serviceBag, "No serviceBag")
|
|
@@ -99,4 +100,4 @@ function IKRigClient:FireSetAimPosition(newTarget: Vector3?)
|
|
|
99
100
|
self._remoting.SetAimPosition:FireServer(newTarget)
|
|
100
101
|
end
|
|
101
102
|
|
|
102
|
-
return Binder.new("IKRig", IKRigClient)
|
|
103
|
+
return Binder.new("IKRig", IKRigClient)
|
package/src/Server/IKService.lua
CHANGED
|
@@ -23,7 +23,7 @@ local Players = game:GetService("Players")
|
|
|
23
23
|
local RunService = game:GetService("RunService")
|
|
24
24
|
|
|
25
25
|
local Maid = require("Maid")
|
|
26
|
-
local
|
|
26
|
+
local ServiceBag = require("ServiceBag")
|
|
27
27
|
|
|
28
28
|
local SERVER_UPDATE_RATE = 1 / 10
|
|
29
29
|
|
|
@@ -43,7 +43,7 @@ IKService.ServiceName = "IKService"
|
|
|
43
43
|
|
|
44
44
|
@param serviceBag ServiceBag
|
|
45
45
|
]=]
|
|
46
|
-
function IKService:Init(serviceBag:
|
|
46
|
+
function IKService:Init(serviceBag: ServiceBag.ServiceBag)
|
|
47
47
|
assert(not self._maid, "Already initialized")
|
|
48
48
|
self._serviceBag = assert(serviceBag, "No serviceBag")
|
|
49
49
|
self._maid = Maid.new()
|
package/src/Server/Rig/IKRig.lua
CHANGED
|
@@ -11,12 +11,13 @@ local IKRigBase = require("IKRigBase")
|
|
|
11
11
|
local IKRigInterface = require("IKRigInterface")
|
|
12
12
|
local Motor6DStackHumanoid = require("Motor6DStackHumanoid")
|
|
13
13
|
local Remoting = require("Remoting")
|
|
14
|
+
local ServiceBag = require("ServiceBag")
|
|
14
15
|
|
|
15
16
|
local IKRig = setmetatable({}, IKRigBase)
|
|
16
17
|
IKRig.ClassName = "IKRig"
|
|
17
18
|
IKRig.__index = IKRig
|
|
18
19
|
|
|
19
|
-
function IKRig.new(humanoid: Humanoid, serviceBag)
|
|
20
|
+
function IKRig.new(humanoid: Humanoid, serviceBag: ServiceBag.ServiceBag)
|
|
20
21
|
local self = setmetatable(IKRigBase.new(humanoid, serviceBag), IKRig)
|
|
21
22
|
|
|
22
23
|
self._serviceBag = assert(serviceBag, "No serviceBag")
|
|
@@ -35,7 +36,7 @@ end
|
|
|
35
36
|
|
|
36
37
|
@return Vector3?
|
|
37
38
|
]=]
|
|
38
|
-
function IKRig:GetAimPosition()
|
|
39
|
+
function IKRig:GetAimPosition(): Vector3?
|
|
39
40
|
return self._aimPosition
|
|
40
41
|
end
|
|
41
42
|
|
|
@@ -78,4 +79,4 @@ function IKRig:_applyAimPosition(target: Vector3?)
|
|
|
78
79
|
end
|
|
79
80
|
end
|
|
80
81
|
|
|
81
|
-
return Binder.new("IKRig", IKRig)
|
|
82
|
+
return Binder.new("IKRig", IKRig)
|
|
@@ -20,10 +20,11 @@ local Rx = require("Rx")
|
|
|
20
20
|
local RxBrioUtils = require("RxBrioUtils")
|
|
21
21
|
local RxInstanceUtils = require("RxInstanceUtils")
|
|
22
22
|
local RxR15Utils = require("RxR15Utils")
|
|
23
|
-
local
|
|
23
|
+
local ServiceBag = require("ServiceBag")
|
|
24
24
|
local TieRealmService = require("TieRealmService")
|
|
25
|
+
local ValueObject = require("ValueObject")
|
|
25
26
|
|
|
26
|
-
local CFA_90X = CFrame.Angles(math.pi/2, 0, 0)
|
|
27
|
+
local CFA_90X = CFrame.Angles(math.pi / 2, 0, 0)
|
|
27
28
|
local USE_OLD_IK_SYSTEM = (not LimbIKUtils) or false
|
|
28
29
|
local USE_MOTOR_6D_RAW = false
|
|
29
30
|
|
|
@@ -31,7 +32,7 @@ local ArmIKBase = setmetatable({}, BaseObject)
|
|
|
31
32
|
ArmIKBase.ClassName = "ArmIKBase"
|
|
32
33
|
ArmIKBase.__index = ArmIKBase
|
|
33
34
|
|
|
34
|
-
function ArmIKBase.new(humanoid, armName, serviceBag)
|
|
35
|
+
function ArmIKBase.new(humanoid: Humanoid, armName, serviceBag: ServiceBag.ServiceBag)
|
|
35
36
|
local self = setmetatable(BaseObject.new(), ArmIKBase)
|
|
36
37
|
|
|
37
38
|
self._humanoid = humanoid or error("No humanoid")
|
|
@@ -100,7 +101,7 @@ function ArmIKBase:_startUpdateLoop(character)
|
|
|
100
101
|
maid:GiveTask(self:_ensureAnimator(character, self._armName .. "LowerArm", self._armName .. "Elbow", function()
|
|
101
102
|
return self._elbowTransform
|
|
102
103
|
end))
|
|
103
|
-
maid:GiveTask(self:_ensureAnimator(character, self._armName .. "Hand", self._armName .."Wrist", function()
|
|
104
|
+
maid:GiveTask(self:_ensureAnimator(character, self._armName .. "Hand", self._armName .. "Wrist", function()
|
|
104
105
|
return self._wristTransform
|
|
105
106
|
end))
|
|
106
107
|
|
|
@@ -110,31 +111,33 @@ end
|
|
|
110
111
|
function ArmIKBase:_ensureAnimator(character, partName, motorName, getTranform)
|
|
111
112
|
local topMaid = Maid.new()
|
|
112
113
|
|
|
113
|
-
topMaid:GiveTask(RxR15Utils.observeRigMotorBrio(character, partName, motorName)
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
114
|
+
topMaid:GiveTask(RxR15Utils.observeRigMotorBrio(character, partName, motorName)
|
|
115
|
+
:Pipe({
|
|
116
|
+
RxBrioUtils.switchMapBrio(function(motor)
|
|
117
|
+
return Motor6DStackInterface:ObserveLastImplementationBrio(motor, self._tieRealmService:GetTieRealm())
|
|
118
|
+
end),
|
|
119
|
+
})
|
|
120
|
+
:Subscribe(function(brio)
|
|
121
|
+
if brio:IsDead() then
|
|
122
|
+
return
|
|
123
|
+
end
|
|
121
124
|
|
|
122
|
-
|
|
125
|
+
local maid, motor6DStack = brio:ToMaidAndValue()
|
|
123
126
|
|
|
124
|
-
|
|
125
|
-
|
|
127
|
+
local transformer = Motor6DSmoothTransformer.new(getTranform)
|
|
128
|
+
transformer:SetTarget(1)
|
|
126
129
|
|
|
127
|
-
|
|
130
|
+
local cleanup = motor6DStack:Push(transformer)
|
|
128
131
|
|
|
129
|
-
|
|
130
|
-
|
|
132
|
+
maid:GiveTask(function()
|
|
133
|
+
transformer:SetTarget(0)
|
|
131
134
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
+
task.delay(2, function()
|
|
136
|
+
transformer:Destroy()
|
|
137
|
+
cleanup()
|
|
138
|
+
end)
|
|
135
139
|
end)
|
|
136
|
-
end)
|
|
137
|
-
end))
|
|
140
|
+
end))
|
|
138
141
|
|
|
139
142
|
return topMaid
|
|
140
143
|
end
|
|
@@ -147,116 +150,155 @@ function ArmIKBase:_observeCharacterBrio()
|
|
|
147
150
|
self._characterObservable = RxInstanceUtils.observePropertyBrio(self._humanoid, "Parent", function(parent)
|
|
148
151
|
return parent ~= nil
|
|
149
152
|
end):Pipe({
|
|
150
|
-
Rx.shareReplay(1)
|
|
153
|
+
Rx.shareReplay(1),
|
|
151
154
|
})
|
|
152
155
|
|
|
153
156
|
return self._characterObservable
|
|
154
157
|
end
|
|
155
158
|
|
|
156
|
-
|
|
157
159
|
function ArmIKBase:_observeStateBrio()
|
|
158
160
|
return self:_observeCharacterBrio():Pipe({
|
|
159
161
|
RxBrioUtils.switchMapBrio(function(character)
|
|
160
|
-
local observeUpperTorsoBrio = RxInstanceUtils.observeLastNamedChildBrio(character, "BasePart", "UpperTorso")
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
162
|
+
local observeUpperTorsoBrio = RxInstanceUtils.observeLastNamedChildBrio(character, "BasePart", "UpperTorso")
|
|
163
|
+
:Pipe({
|
|
164
|
+
Rx.shareReplay(1),
|
|
165
|
+
})
|
|
166
|
+
local observeUpperArmBrio =
|
|
167
|
+
RxInstanceUtils.observeLastNamedChildBrio(character, "BasePart", self._armName .. "UpperArm"):Pipe({
|
|
168
|
+
Rx.shareReplay(1),
|
|
169
|
+
})
|
|
170
|
+
local observeLowerArmBrio =
|
|
171
|
+
RxInstanceUtils.observeLastNamedChildBrio(character, "BasePart", self._armName .. "LowerArm"):Pipe({
|
|
172
|
+
Rx.shareReplay(1),
|
|
173
|
+
})
|
|
174
|
+
local observeHandBrio =
|
|
175
|
+
RxInstanceUtils.observeLastNamedChildBrio(character, "BasePart", self._armName .. "Hand"):Pipe({
|
|
176
|
+
Rx.shareReplay(1),
|
|
177
|
+
})
|
|
172
178
|
|
|
173
179
|
local observeShoulderBrio = observeUpperArmBrio:Pipe({
|
|
174
180
|
RxBrioUtils.switchMapBrio(function(upperArm)
|
|
175
181
|
return RxInstanceUtils.observeLastNamedChildBrio(upperArm, "Motor6D", self._armName .. "Shoulder")
|
|
176
|
-
end)
|
|
177
|
-
Rx.shareReplay(1)
|
|
182
|
+
end),
|
|
183
|
+
Rx.shareReplay(1),
|
|
178
184
|
})
|
|
179
185
|
local observeElbowBrio = observeLowerArmBrio:Pipe({
|
|
180
186
|
RxBrioUtils.switchMapBrio(function(lowerArm)
|
|
181
187
|
return RxInstanceUtils.observeLastNamedChildBrio(lowerArm, "Motor6D", self._armName .. "Elbow")
|
|
182
|
-
end)
|
|
183
|
-
Rx.shareReplay(1)
|
|
188
|
+
end),
|
|
189
|
+
Rx.shareReplay(1),
|
|
184
190
|
})
|
|
185
191
|
local observeWristBrio = observeHandBrio:Pipe({
|
|
186
192
|
RxBrioUtils.switchMapBrio(function(hand)
|
|
187
193
|
return RxInstanceUtils.observeLastNamedChildBrio(hand, "Motor6D", self._armName .. "Wrist")
|
|
188
|
-
end)
|
|
189
|
-
Rx.shareReplay(1)
|
|
194
|
+
end),
|
|
195
|
+
Rx.shareReplay(1),
|
|
190
196
|
})
|
|
191
197
|
|
|
192
198
|
return RxBrioUtils.flatCombineLatest({
|
|
193
|
-
UpperTorso = observeUpperTorsoBrio
|
|
194
|
-
UpperArm = observeUpperArmBrio
|
|
195
|
-
LowerArm = observeLowerArmBrio
|
|
196
|
-
Hand = observeHandBrio
|
|
199
|
+
UpperTorso = observeUpperTorsoBrio,
|
|
200
|
+
UpperArm = observeUpperArmBrio,
|
|
201
|
+
LowerArm = observeLowerArmBrio,
|
|
202
|
+
Hand = observeHandBrio,
|
|
197
203
|
|
|
198
|
-
Shoulder = observeShoulderBrio
|
|
199
|
-
Elbow = observeElbowBrio
|
|
200
|
-
Wrist = observeWristBrio
|
|
204
|
+
Shoulder = observeShoulderBrio,
|
|
205
|
+
Elbow = observeElbowBrio,
|
|
206
|
+
Wrist = observeWristBrio,
|
|
201
207
|
|
|
202
208
|
ShoulderMotor6DStack = observeShoulderBrio:Pipe({
|
|
203
209
|
RxBrioUtils.switchMapBrio(function(motor)
|
|
204
|
-
return Motor6DStackInterface:ObserveLastImplementationBrio(
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
210
|
+
return Motor6DStackInterface:ObserveLastImplementationBrio(
|
|
211
|
+
motor,
|
|
212
|
+
self._tieRealmService:GetTieRealm()
|
|
213
|
+
)
|
|
214
|
+
end),
|
|
215
|
+
Rx.defaultsToNil,
|
|
216
|
+
}),
|
|
208
217
|
ElbowMotor6DStack = observeElbowBrio:Pipe({
|
|
209
218
|
RxBrioUtils.switchMapBrio(function(motor)
|
|
210
|
-
return Motor6DStackInterface:ObserveLastImplementationBrio(
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
219
|
+
return Motor6DStackInterface:ObserveLastImplementationBrio(
|
|
220
|
+
motor,
|
|
221
|
+
self._tieRealmService:GetTieRealm()
|
|
222
|
+
)
|
|
223
|
+
end),
|
|
224
|
+
Rx.defaultsToNil,
|
|
225
|
+
}),
|
|
214
226
|
WristMotor6DStack = observeWristBrio:Pipe({
|
|
215
227
|
RxBrioUtils.switchMapBrio(function(motor)
|
|
216
|
-
return Motor6DStackInterface:ObserveLastImplementationBrio(
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
228
|
+
return Motor6DStackInterface:ObserveLastImplementationBrio(
|
|
229
|
+
motor,
|
|
230
|
+
self._tieRealmService:GetTieRealm()
|
|
231
|
+
)
|
|
232
|
+
end),
|
|
233
|
+
Rx.defaultsToNil,
|
|
234
|
+
}),
|
|
220
235
|
|
|
221
236
|
UpperTorsoShoulderRigAttachment = observeUpperTorsoBrio:Pipe({
|
|
222
237
|
RxBrioUtils.switchMapBrio(function(upperTorso)
|
|
223
|
-
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
224
|
-
|
|
225
|
-
|
|
238
|
+
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
239
|
+
upperTorso,
|
|
240
|
+
"Attachment",
|
|
241
|
+
self._armName .. "ShoulderRigAttachment"
|
|
242
|
+
)
|
|
243
|
+
end),
|
|
244
|
+
}),
|
|
226
245
|
UpperArmShoulderRigAttachment = observeUpperArmBrio:Pipe({
|
|
227
246
|
RxBrioUtils.switchMapBrio(function(upperArm)
|
|
228
|
-
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
229
|
-
|
|
230
|
-
|
|
247
|
+
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
248
|
+
upperArm,
|
|
249
|
+
"Attachment",
|
|
250
|
+
self._armName .. "ShoulderRigAttachment"
|
|
251
|
+
)
|
|
252
|
+
end),
|
|
253
|
+
}),
|
|
231
254
|
UpperArmElbowRigAttachment = observeUpperArmBrio:Pipe({
|
|
232
255
|
RxBrioUtils.switchMapBrio(function(upperArm)
|
|
233
|
-
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
234
|
-
|
|
235
|
-
|
|
256
|
+
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
257
|
+
upperArm,
|
|
258
|
+
"Attachment",
|
|
259
|
+
self._armName .. "ElbowRigAttachment"
|
|
260
|
+
)
|
|
261
|
+
end),
|
|
262
|
+
}),
|
|
236
263
|
LowerArmElbowRigAttachment = observeLowerArmBrio:Pipe({
|
|
237
264
|
RxBrioUtils.switchMapBrio(function(lowerArm)
|
|
238
|
-
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
239
|
-
|
|
240
|
-
|
|
265
|
+
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
266
|
+
lowerArm,
|
|
267
|
+
"Attachment",
|
|
268
|
+
self._armName .. "ElbowRigAttachment"
|
|
269
|
+
)
|
|
270
|
+
end),
|
|
271
|
+
}),
|
|
241
272
|
LowerArmWristRigAttachment = observeLowerArmBrio:Pipe({
|
|
242
273
|
RxBrioUtils.switchMapBrio(function(lowerArm)
|
|
243
|
-
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
244
|
-
|
|
245
|
-
|
|
274
|
+
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
275
|
+
lowerArm,
|
|
276
|
+
"Attachment",
|
|
277
|
+
self._armName .. "WristRigAttachment"
|
|
278
|
+
)
|
|
279
|
+
end),
|
|
280
|
+
}),
|
|
246
281
|
HandWristRigAttachment = observeHandBrio:Pipe({
|
|
247
282
|
RxBrioUtils.switchMapBrio(function(hand)
|
|
248
|
-
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
249
|
-
|
|
250
|
-
|
|
283
|
+
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
284
|
+
hand,
|
|
285
|
+
"Attachment",
|
|
286
|
+
self._armName .. "WristRigAttachment"
|
|
287
|
+
)
|
|
288
|
+
end),
|
|
289
|
+
}),
|
|
251
290
|
HandGripAttachment = observeHandBrio:Pipe({
|
|
252
291
|
RxBrioUtils.switchMapBrio(function(hand)
|
|
253
|
-
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
254
|
-
|
|
255
|
-
|
|
292
|
+
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
293
|
+
hand,
|
|
294
|
+
"Attachment",
|
|
295
|
+
self._armName .. "GripAttachment"
|
|
296
|
+
)
|
|
297
|
+
end),
|
|
298
|
+
}),
|
|
256
299
|
})
|
|
257
|
-
end)
|
|
258
|
-
Rx.throttleDefer()
|
|
259
|
-
|
|
300
|
+
end),
|
|
301
|
+
Rx.throttleDefer(),
|
|
260
302
|
})
|
|
261
303
|
end
|
|
262
304
|
|
|
@@ -267,8 +309,8 @@ function ArmIKBase:Grip(attachment, priority)
|
|
|
267
309
|
priority = priority or IKAimPositionPriorites.DEFAULT
|
|
268
310
|
|
|
269
311
|
local gripData = {
|
|
270
|
-
attachment = attachment
|
|
271
|
-
priority = priority
|
|
312
|
+
attachment = attachment,
|
|
313
|
+
priority = priority,
|
|
272
314
|
}
|
|
273
315
|
|
|
274
316
|
local i = 1
|
|
@@ -347,7 +389,6 @@ else
|
|
|
347
389
|
end
|
|
348
390
|
end
|
|
349
391
|
|
|
350
|
-
|
|
351
392
|
if USE_OLD_IK_SYSTEM then
|
|
352
393
|
function ArmIKBase:Update()
|
|
353
394
|
if self:_oldUpdatePoint() then
|
|
@@ -412,13 +453,17 @@ function ArmIKBase:_newUpdate()
|
|
|
412
453
|
local handWristRigAttachment = self._lastState["HandWristRigAttachment"]
|
|
413
454
|
local handGripAttachment = self._lastState["HandGripAttachment"]
|
|
414
455
|
|
|
415
|
-
if
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
456
|
+
if
|
|
457
|
+
not (
|
|
458
|
+
upperTorsoShoulderRigAttachment
|
|
459
|
+
and upperArmShoulderRigAttachment
|
|
460
|
+
and upperArmElbowRigAttachment
|
|
461
|
+
and lowerArmElbowRigAttachment
|
|
462
|
+
and lowerArmWristRigAttachment
|
|
463
|
+
and handWristRigAttachment
|
|
464
|
+
and handGripAttachment
|
|
465
|
+
)
|
|
466
|
+
then
|
|
422
467
|
return false
|
|
423
468
|
end
|
|
424
469
|
|
|
@@ -432,7 +477,11 @@ function ArmIKBase:_newUpdate()
|
|
|
432
477
|
|
|
433
478
|
-- TODO: Allow configuration
|
|
434
479
|
local ELBOW_ANGLE = math.rad(20)
|
|
435
|
-
local shoulderQFrame, elbowQFrame, wristQFrame = LimbIKUtils.solveLimb(
|
|
480
|
+
local shoulderQFrame, elbowQFrame, wristQFrame = LimbIKUtils.solveLimb(
|
|
481
|
+
config,
|
|
482
|
+
QFrame.fromCFrameClosestTo(relTargetCFrame, QFrame.new()),
|
|
483
|
+
self._direction * ELBOW_ANGLE
|
|
484
|
+
)
|
|
436
485
|
|
|
437
486
|
self._shoulderTransform = QFrame.toCFrame(shoulderQFrame)
|
|
438
487
|
self._elbowTransform = QFrame.toCFrame(elbowQFrame)
|
|
@@ -450,10 +499,7 @@ function ArmIKBase:_oldCalculatePoint(targetPositionWorld)
|
|
|
450
499
|
local elbow = self._lastState["Elbow"]
|
|
451
500
|
local wrist = self._lastState["Wrist"]
|
|
452
501
|
local gripAttachment = self._lastState["HandGripAttachment"]
|
|
453
|
-
if not (shoulder
|
|
454
|
-
and elbow
|
|
455
|
-
and wrist
|
|
456
|
-
and gripAttachment) then
|
|
502
|
+
if not (shoulder and elbow and wrist and gripAttachment) then
|
|
457
503
|
return false
|
|
458
504
|
end
|
|
459
505
|
|
|
@@ -489,8 +535,8 @@ function ArmIKBase:_oldCalculatePoint(targetPositionWorld)
|
|
|
489
535
|
end
|
|
490
536
|
|
|
491
537
|
elbowAngle = (elbowAngle - math.pi)
|
|
492
|
-
if elbowAngle > -math.pi/32 then -- Force a bit of bent elbow
|
|
493
|
-
elbowAngle = -math.pi/32
|
|
538
|
+
if elbowAngle > -math.pi / 32 then -- Force a bit of bent elbow
|
|
539
|
+
elbowAngle = -math.pi / 32
|
|
494
540
|
end
|
|
495
541
|
|
|
496
542
|
self._shoulderXAngle = -baseAngle
|
|
@@ -500,5 +546,4 @@ function ArmIKBase:_oldCalculatePoint(targetPositionWorld)
|
|
|
500
546
|
return true
|
|
501
547
|
end
|
|
502
548
|
|
|
503
|
-
|
|
504
|
-
return ArmIKBase
|
|
549
|
+
return ArmIKBase
|
|
@@ -2,14 +2,15 @@
|
|
|
2
2
|
@class ArmIKBase.story
|
|
3
3
|
]]
|
|
4
4
|
|
|
5
|
-
local require =
|
|
5
|
+
local require =
|
|
6
|
+
require(game:GetService("ServerScriptService"):FindFirstChild("LoaderUtils", true).Parent).bootstrapStory(script)
|
|
6
7
|
|
|
7
|
-
local Workspace = game:GetService("Workspace")
|
|
8
8
|
local RunService = game:GetService("RunService")
|
|
9
|
+
local Workspace = game:GetService("Workspace")
|
|
9
10
|
|
|
11
|
+
local ArmIKBase = require("ArmIKBase")
|
|
10
12
|
local Maid = require("Maid")
|
|
11
13
|
local RigBuilderUtils = require("RigBuilderUtils")
|
|
12
|
-
local ArmIKBase = require("ArmIKBase")
|
|
13
14
|
local ServiceBag = require("ServiceBag")
|
|
14
15
|
|
|
15
16
|
return function(_target)
|
|
@@ -42,8 +43,7 @@ return function(_target)
|
|
|
42
43
|
end))
|
|
43
44
|
end)
|
|
44
45
|
|
|
45
|
-
|
|
46
46
|
return function()
|
|
47
47
|
maid:DoCleaning()
|
|
48
48
|
end
|
|
49
|
-
end
|
|
49
|
+
end
|
|
@@ -10,7 +10,7 @@ local RxR15Utils = require("RxR15Utils")
|
|
|
10
10
|
|
|
11
11
|
local ArmIKUtils = {}
|
|
12
12
|
|
|
13
|
-
function ArmIKUtils.ensureMotorAnimated(character, armName)
|
|
13
|
+
function ArmIKUtils.ensureMotorAnimated(character: Model, armName)
|
|
14
14
|
local topMaid = Maid.new()
|
|
15
15
|
|
|
16
16
|
local function disable(brio)
|
|
@@ -27,11 +27,17 @@ function ArmIKUtils.ensureMotorAnimated(character, armName)
|
|
|
27
27
|
end)
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
topMaid:GiveTask(
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
topMaid:GiveTask(
|
|
31
|
+
RxR15Utils.observeRigMotorBrio(character, armName .. "UpperArm", armName .. "Shoulder"):Subscribe(disable)
|
|
32
|
+
)
|
|
33
|
+
topMaid:GiveTask(
|
|
34
|
+
RxR15Utils.observeRigMotorBrio(character, armName .. "LowerArm", armName .. "Elbow"):Subscribe(disable)
|
|
35
|
+
)
|
|
36
|
+
topMaid:GiveTask(
|
|
37
|
+
RxR15Utils.observeRigMotorBrio(character, armName .. "Hand", armName .. "Wrist"):Subscribe(disable)
|
|
38
|
+
)
|
|
33
39
|
|
|
34
40
|
return topMaid
|
|
35
41
|
end
|
|
36
42
|
|
|
37
|
-
return ArmIKUtils
|
|
43
|
+
return ArmIKUtils
|
|
@@ -7,8 +7,8 @@ local require = require(script.Parent.loader).load(script)
|
|
|
7
7
|
local Table = require("Table")
|
|
8
8
|
|
|
9
9
|
return Table.readonly({
|
|
10
|
-
DEFAULT = 0
|
|
11
|
-
LOW = 1000
|
|
12
|
-
MEDIUM = 3000
|
|
13
|
-
HIGH = 4000
|
|
14
|
-
})
|
|
10
|
+
DEFAULT = 0,
|
|
11
|
+
LOW = 1000,
|
|
12
|
+
MEDIUM = 3000,
|
|
13
|
+
HIGH = 4000,
|
|
14
|
+
})
|
|
@@ -8,14 +8,15 @@ local require = require(script.Parent.loader).load(script)
|
|
|
8
8
|
local RunService = game:GetService("RunService")
|
|
9
9
|
|
|
10
10
|
local BaseObject = require("BaseObject")
|
|
11
|
-
local promisePropertyValue = require("promisePropertyValue")
|
|
12
11
|
local Promise = require("Promise")
|
|
12
|
+
local ServiceBag = require("ServiceBag")
|
|
13
|
+
local promisePropertyValue = require("promisePropertyValue")
|
|
13
14
|
|
|
14
15
|
local IKGripBase = setmetatable({}, BaseObject)
|
|
15
16
|
IKGripBase.ClassName = "IKGripBase"
|
|
16
17
|
IKGripBase.__index = IKGripBase
|
|
17
18
|
|
|
18
|
-
function IKGripBase.new(objectValue: ObjectValue, serviceBag)
|
|
19
|
+
function IKGripBase.new(objectValue: ObjectValue, serviceBag: ServiceBag.ServiceBag)
|
|
19
20
|
local self = setmetatable(BaseObject.new(objectValue), IKGripBase)
|
|
20
21
|
|
|
21
22
|
self._serviceBag = assert(serviceBag, "No serviceBag")
|
|
@@ -50,17 +51,16 @@ function IKGripBase:PromiseIKRig()
|
|
|
50
51
|
local promise = promisePropertyValue(self._obj, "Value")
|
|
51
52
|
self._maid:GiveTask(promise)
|
|
52
53
|
|
|
53
|
-
self._ikRigPromise = promise
|
|
54
|
-
:
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
end
|
|
54
|
+
self._ikRigPromise = promise:Then(function(humanoid)
|
|
55
|
+
if not humanoid:IsA("Humanoid") then
|
|
56
|
+
warn("[IKGripBase.PromiseIKRig] - Humanoid in link is not a humanoid")
|
|
57
|
+
return Promise.rejected()
|
|
58
|
+
end
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
return self._maid:GivePromise(ikService:PromiseRig(humanoid))
|
|
61
|
+
end)
|
|
62
62
|
|
|
63
63
|
return self._ikRigPromise
|
|
64
64
|
end
|
|
65
65
|
|
|
66
|
-
return IKGripBase
|
|
66
|
+
return IKGripBase
|
|
@@ -5,14 +5,15 @@
|
|
|
5
5
|
|
|
6
6
|
local require = require(script.Parent.loader).load(script)
|
|
7
7
|
|
|
8
|
-
local IKGripBase = require("IKGripBase")
|
|
9
8
|
local Binder = require("Binder")
|
|
9
|
+
local IKGripBase = require("IKGripBase")
|
|
10
|
+
local ServiceBag = require("ServiceBag")
|
|
10
11
|
|
|
11
12
|
local IKLeftGrip = setmetatable({}, IKGripBase)
|
|
12
13
|
IKLeftGrip.ClassName = "IKLeftGrip"
|
|
13
14
|
IKLeftGrip.__index = IKLeftGrip
|
|
14
15
|
|
|
15
|
-
function IKLeftGrip.new(objectValue, serviceBag)
|
|
16
|
+
function IKLeftGrip.new(objectValue, serviceBag: ServiceBag.ServiceBag)
|
|
16
17
|
local self = setmetatable(IKGripBase.new(objectValue, serviceBag), IKLeftGrip)
|
|
17
18
|
|
|
18
19
|
self:PromiseIKRig()
|
|
@@ -26,4 +27,4 @@ function IKLeftGrip.new(objectValue, serviceBag)
|
|
|
26
27
|
return self
|
|
27
28
|
end
|
|
28
29
|
|
|
29
|
-
return Binder.new("IKLeftGrip", IKLeftGrip)
|
|
30
|
+
return Binder.new("IKLeftGrip", IKLeftGrip)
|
|
@@ -5,14 +5,15 @@
|
|
|
5
5
|
|
|
6
6
|
local require = require(script.Parent.loader).load(script)
|
|
7
7
|
|
|
8
|
-
local IKGripBase = require("IKGripBase")
|
|
9
8
|
local Binder = require("Binder")
|
|
9
|
+
local IKGripBase = require("IKGripBase")
|
|
10
|
+
local ServiceBag = require("ServiceBag")
|
|
10
11
|
|
|
11
12
|
local IKRightGrip = setmetatable({}, IKGripBase)
|
|
12
13
|
IKRightGrip.ClassName = "IKRightGrip"
|
|
13
14
|
IKRightGrip.__index = IKRightGrip
|
|
14
15
|
|
|
15
|
-
function IKRightGrip.new(objectValue: ObjectValue, serviceBag)
|
|
16
|
+
function IKRightGrip.new(objectValue: ObjectValue, serviceBag: ServiceBag.ServiceBag)
|
|
16
17
|
local self = setmetatable(IKGripBase.new(objectValue, serviceBag), IKRightGrip)
|
|
17
18
|
|
|
18
19
|
self:PromiseIKRig()
|
|
@@ -26,4 +27,4 @@ function IKRightGrip.new(objectValue: ObjectValue, serviceBag)
|
|
|
26
27
|
return self
|
|
27
28
|
end
|
|
28
29
|
|
|
29
|
-
return Binder.new("IKRightGrip", IKRightGrip)
|
|
30
|
+
return Binder.new("IKRightGrip", IKRightGrip)
|
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
local require = require(script.Parent.loader).load(script)
|
|
6
6
|
|
|
7
7
|
local IKRigInterface = require("IKRigInterface")
|
|
8
|
+
local ServiceBag = require("ServiceBag")
|
|
8
9
|
local TieRealmService = require("TieRealmService")
|
|
9
|
-
local _ServiceBag = require("ServiceBag")
|
|
10
10
|
|
|
11
11
|
local IKDataService = {}
|
|
12
12
|
IKDataService.ServiceName = "IKDataService"
|
|
13
13
|
|
|
14
|
-
function IKDataService:Init(serviceBag:
|
|
14
|
+
function IKDataService:Init(serviceBag: ServiceBag.ServiceBag)
|
|
15
15
|
assert(not self._serviceBag, "Already initialized")
|
|
16
16
|
self._serviceBag = assert(serviceBag, "No serviceBag")
|
|
17
17
|
|
package/src/Shared/IKUtils.lua
CHANGED
|
@@ -6,7 +6,11 @@
|
|
|
6
6
|
|
|
7
7
|
local IKUtils = {}
|
|
8
8
|
|
|
9
|
-
function IKUtils.getDampenedAngleClamp(
|
|
9
|
+
function IKUtils.getDampenedAngleClamp(
|
|
10
|
+
maxAngle: number,
|
|
11
|
+
dampenAreaAngle: number,
|
|
12
|
+
dampenAreaFactor: number?
|
|
13
|
+
): (number) -> number
|
|
10
14
|
local areaFactor = dampenAreaFactor or dampenAreaAngle
|
|
11
15
|
|
|
12
16
|
return function(angle)
|
|
@@ -17,11 +21,11 @@ function IKUtils.getDampenedAngleClamp(maxAngle: number, dampenAreaAngle: number
|
|
|
17
21
|
-- dampenAreaFactor is the area that the bouncing happens
|
|
18
22
|
-- dampenAreaAngle is the amount of bounce that occurs
|
|
19
23
|
local timesOver = (math.abs(angle) - min) / areaFactor
|
|
20
|
-
local scale = (1 - 0.5^timesOver)
|
|
24
|
+
local scale = (1 - 0.5 ^ timesOver)
|
|
21
25
|
|
|
22
|
-
return math.sign(angle) * (min + (scale*dampenAreaAngle))
|
|
26
|
+
return math.sign(angle) * (min + (scale * dampenAreaAngle))
|
|
23
27
|
end
|
|
24
28
|
end
|
|
25
29
|
end
|
|
26
30
|
|
|
27
|
-
return IKUtils
|
|
31
|
+
return IKUtils
|
|
@@ -7,13 +7,13 @@ local require = require(script.Parent.loader).load(script)
|
|
|
7
7
|
local TieDefinition = require("TieDefinition")
|
|
8
8
|
|
|
9
9
|
return TieDefinition.new("IKRig", {
|
|
10
|
-
GetPlayer = TieDefinition.Types.METHOD
|
|
11
|
-
GetHumanoid = TieDefinition.Types.METHOD
|
|
10
|
+
GetPlayer = TieDefinition.Types.METHOD,
|
|
11
|
+
GetHumanoid = TieDefinition.Types.METHOD,
|
|
12
12
|
|
|
13
|
-
PromiseLeftArm = TieDefinition.Types.METHOD
|
|
14
|
-
PromiseRightArm = TieDefinition.Types.METHOD
|
|
15
|
-
GetLeftArm = TieDefinition.Types.METHOD
|
|
16
|
-
GetRightArm = TieDefinition.Types.METHOD
|
|
13
|
+
PromiseLeftArm = TieDefinition.Types.METHOD,
|
|
14
|
+
PromiseRightArm = TieDefinition.Types.METHOD,
|
|
15
|
+
GetLeftArm = TieDefinition.Types.METHOD,
|
|
16
|
+
GetRightArm = TieDefinition.Types.METHOD,
|
|
17
17
|
|
|
18
|
-
GetAimPosition = TieDefinition.Types.METHOD
|
|
19
|
-
})
|
|
18
|
+
GetAimPosition = TieDefinition.Types.METHOD,
|
|
19
|
+
})
|
|
@@ -22,7 +22,7 @@ function IKResource.new(data)
|
|
|
22
22
|
self._instance = nil
|
|
23
23
|
self._childResourceMap = {} -- [robloxName] = { data = data; ikResource = ikResource }
|
|
24
24
|
self._descendantLookupMap = {
|
|
25
|
-
[data.name] = self
|
|
25
|
+
[data.name] = self,
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
self._ready = self._maid:Add(ValueObject.new(false, "boolean"))
|
|
@@ -194,4 +194,4 @@ function IKResource:_calculateIsReady()
|
|
|
194
194
|
return true
|
|
195
195
|
end
|
|
196
196
|
|
|
197
|
-
return IKResource
|
|
197
|
+
return IKResource
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
local require = require(script.Parent.loader).load(script)
|
|
6
6
|
|
|
7
|
+
local ArmIKBase = require("ArmIKBase")
|
|
7
8
|
local BaseObject = require("BaseObject")
|
|
8
|
-
local TorsoIKBase = require("TorsoIKBase")
|
|
9
|
-
local Promise = require("Promise")
|
|
10
9
|
local CharacterUtils = require("CharacterUtils")
|
|
10
|
+
local Promise = require("Promise")
|
|
11
11
|
local Signal = require("Signal")
|
|
12
|
-
local
|
|
12
|
+
local TorsoIKBase = require("TorsoIKBase")
|
|
13
13
|
|
|
14
14
|
local IKRigBase = setmetatable({}, BaseObject)
|
|
15
15
|
IKRigBase.ClassName = "IKRigBase"
|
|
@@ -128,4 +128,4 @@ function IKRigBase:_getNewTorso()
|
|
|
128
128
|
return newIk
|
|
129
129
|
end
|
|
130
130
|
|
|
131
|
-
return IKRigBase
|
|
131
|
+
return IKRigBase
|
|
@@ -9,7 +9,7 @@ local Math = require("Math")
|
|
|
9
9
|
|
|
10
10
|
local IKRigUtils = {}
|
|
11
11
|
|
|
12
|
-
function IKRigUtils.getTimeBeforeNextUpdate(distance)
|
|
12
|
+
function IKRigUtils.getTimeBeforeNextUpdate(distance: number): number
|
|
13
13
|
local updateRate
|
|
14
14
|
if distance < 128 then
|
|
15
15
|
updateRate = 0
|
|
@@ -21,7 +21,7 @@ function IKRigUtils.getTimeBeforeNextUpdate(distance)
|
|
|
21
21
|
return updateRate
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
function IKRigUtils.getPlayerIKRig(binder, player)
|
|
24
|
+
function IKRigUtils.getPlayerIKRig(binder, player: Player)
|
|
25
25
|
assert(binder, "Bad binder")
|
|
26
26
|
|
|
27
27
|
local humanoid = CharacterUtils.getPlayerHumanoid(player)
|
|
@@ -32,4 +32,4 @@ function IKRigUtils.getPlayerIKRig(binder, player)
|
|
|
32
32
|
return binder:Get(humanoid)
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
return IKRigUtils
|
|
35
|
+
return IKRigUtils
|
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
local require = require(script.Parent.loader).load(script)
|
|
7
7
|
|
|
8
8
|
local AccelTween = require("AccelTween")
|
|
9
|
-
local TorsoIKUtils = require("TorsoIKUtils")
|
|
10
|
-
local Signal = require("Signal")
|
|
11
9
|
local BaseObject = require("BaseObject")
|
|
12
10
|
local IKResource = require("IKResource")
|
|
13
11
|
local IKResourceUtils = require("IKResourceUtils")
|
|
12
|
+
local Signal = require("Signal")
|
|
13
|
+
local TorsoIKUtils = require("TorsoIKUtils")
|
|
14
14
|
|
|
15
15
|
local TorsoIKBase = setmetatable({}, BaseObject)
|
|
16
16
|
TorsoIKBase.__index = TorsoIKBase
|
|
@@ -10,40 +10,31 @@ local OFFSET_Y = 0.5
|
|
|
10
10
|
|
|
11
11
|
local TorsoIKUtils = {}
|
|
12
12
|
|
|
13
|
-
local waistYawClamper = IKUtils.getDampenedAngleClamp(
|
|
14
|
-
math.rad(20),
|
|
15
|
-
math.rad(10))
|
|
13
|
+
local waistYawClamper = IKUtils.getDampenedAngleClamp(math.rad(20), math.rad(10))
|
|
16
14
|
local waistPitchClamper = IKUtils.getDampenedAngleClamp(
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
local headPitchClamper = IKUtils.getDampenedAngleClamp(
|
|
23
|
-
math.rad(45),
|
|
24
|
-
math.rad(15))
|
|
15
|
+
math.rad(20), -- TODO: Allow forward bend by 40 degrees
|
|
16
|
+
math.rad(10)
|
|
17
|
+
)
|
|
18
|
+
local headYawClamper = IKUtils.getDampenedAngleClamp(math.rad(45), math.rad(15))
|
|
19
|
+
local headPitchClamper = IKUtils.getDampenedAngleClamp(math.rad(45), math.rad(15))
|
|
25
20
|
|
|
26
21
|
function TorsoIKUtils.getTargetAngles(rootPart, target)
|
|
27
|
-
local baseCFrame = rootPart.CFrame
|
|
28
|
-
* CFrame.new(0, OFFSET_Y, 0)
|
|
22
|
+
local baseCFrame = rootPart.CFrame * CFrame.new(0, OFFSET_Y, 0)
|
|
29
23
|
|
|
30
24
|
local offsetWaistY = baseCFrame:pointToObjectSpace(target)
|
|
31
25
|
local waistY = waistYawClamper(math.atan2(-offsetWaistY.X, -offsetWaistY.Z))
|
|
32
26
|
|
|
33
|
-
local relativeToWaistY = baseCFrame
|
|
34
|
-
* CFrame.Angles(0, waistY, 0)
|
|
27
|
+
local relativeToWaistY = baseCFrame * CFrame.Angles(0, waistY, 0)
|
|
35
28
|
|
|
36
29
|
local headOffsetY = relativeToWaistY:pointToObjectSpace(target)
|
|
37
30
|
local headY = headYawClamper(math.atan2(-headOffsetY.X, -headOffsetY.Z))
|
|
38
31
|
|
|
39
|
-
local relativeToHeadY = relativeToWaistY
|
|
40
|
-
* CFrame.Angles(0, headY, 0)
|
|
32
|
+
local relativeToHeadY = relativeToWaistY * CFrame.Angles(0, headY, 0)
|
|
41
33
|
|
|
42
34
|
local offsetWaistZ = relativeToHeadY:pointToObjectSpace(target)
|
|
43
35
|
local waistZ = waistPitchClamper(math.atan2(offsetWaistZ.Y, -offsetWaistZ.Z))
|
|
44
36
|
|
|
45
|
-
local relativeToEverything = relativeToHeadY
|
|
46
|
-
* CFrame.Angles(0, 0, waistZ)
|
|
37
|
+
local relativeToEverything = relativeToHeadY * CFrame.Angles(0, 0, waistZ)
|
|
47
38
|
|
|
48
39
|
local headOffsetZ = relativeToEverything:pointToObjectSpace(target)
|
|
49
40
|
local headZ = headPitchClamper(math.atan2(headOffsetZ.Y, -headOffsetZ.Z))
|
|
@@ -51,4 +42,4 @@ function TorsoIKUtils.getTargetAngles(rootPart, target)
|
|
|
51
42
|
return waistY, headY, waistZ, headZ
|
|
52
43
|
end
|
|
53
44
|
|
|
54
|
-
return TorsoIKUtils
|
|
45
|
+
return TorsoIKUtils
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
@class ServerMain
|
|
3
3
|
]]
|
|
4
4
|
|
|
5
|
-
local ServerScriptService = game:GetService("ServerScriptService")
|
|
6
5
|
local RunService = game:GetService("RunService")
|
|
6
|
+
local ServerScriptService = game:GetService("ServerScriptService")
|
|
7
7
|
|
|
8
8
|
local loader = ServerScriptService:FindFirstChild("LoaderUtils", true).Parent
|
|
9
9
|
local require = require(loader).bootstrapGame(ServerScriptService.ik)
|