@quenty/ik 15.25.0-canary.ae8d76d.0 → 15.25.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 +1 -1
- package/package.json +27 -27
- package/src/Client/GripPointer.lua +1 -1
- package/src/Client/IKServiceClient.lua +1 -1
- package/src/Client/Rig/IKRigAimerLocalPlayer.lua +3 -3
- package/src/Client/Rig/IKRigClient.lua +1 -1
- package/src/Server/Rig/IKRig.lua +1 -1
- package/src/Shared/Arm/ArmIKBase.lua +148 -104
- package/src/Shared/Arm/ArmIKBase.story.lua +5 -5
- package/src/Shared/Arm/ArmIKUtils.lua +10 -4
- package/src/Shared/Arm/IKAimPositionPriorites.lua +5 -5
- package/src/Shared/Grip/IKGripBase.lua +9 -10
- package/src/Shared/Grip/IKGripUtils.lua +1 -1
- package/src/Shared/Grip/IKLeftGrip.lua +2 -2
- package/src/Shared/Grip/IKRightGrip.lua +2 -2
- package/src/Shared/IKDataService.lua +1 -1
- 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 +1 -1
- 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,7 +3,7 @@
|
|
|
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.25.0
|
|
6
|
+
# [15.25.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/ik@15.24.3...@quenty/ik@15.25.0) (2025-05-10)
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
### Bug Fixes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quenty/ik",
|
|
3
|
-
"version": "15.25.0
|
|
3
|
+
"version": "15.25.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": "2.5.3",
|
|
30
|
-
"@quenty/baseobject": "10.
|
|
31
|
-
"@quenty/binder": "14.20.0
|
|
32
|
-
"@quenty/brio": "14.18.0
|
|
33
|
-
"@quenty/camera": "14.21.0
|
|
34
|
-
"@quenty/characterutils": "12.19.0
|
|
35
|
-
"@quenty/humanoidtracker": "13.18.0
|
|
36
|
-
"@quenty/instanceutils": "13.18.0
|
|
37
|
-
"@quenty/loader": "10.
|
|
38
|
-
"@quenty/maid": "3.
|
|
39
|
-
"@quenty/math": "2.7.3",
|
|
40
|
-
"@quenty/motor6d": "7.21.0
|
|
41
|
-
"@quenty/optional": "11.9.0
|
|
42
|
-
"@quenty/promise": "10.11.0
|
|
43
|
-
"@quenty/qframe": "10.11.0
|
|
44
|
-
"@quenty/r15utils": "13.18.0
|
|
45
|
-
"@quenty/ragdoll": "15.24.0
|
|
46
|
-
"@quenty/remoting": "12.19.0
|
|
47
|
-
"@quenty/rx": "13.18.0
|
|
48
|
-
"@quenty/servicebag": "11.12.0
|
|
49
|
-
"@quenty/signal": "7.
|
|
50
|
-
"@quenty/table": "3.
|
|
51
|
-
"@quenty/tie": "10.21.0
|
|
52
|
-
"@quenty/valueobject": "13.18.0
|
|
29
|
+
"@quenty/acceltween": "^2.5.3",
|
|
30
|
+
"@quenty/baseobject": "^10.9.0",
|
|
31
|
+
"@quenty/binder": "^14.20.0",
|
|
32
|
+
"@quenty/brio": "^14.18.0",
|
|
33
|
+
"@quenty/camera": "^14.21.0",
|
|
34
|
+
"@quenty/characterutils": "^12.19.0",
|
|
35
|
+
"@quenty/humanoidtracker": "^13.18.0",
|
|
36
|
+
"@quenty/instanceutils": "^13.18.0",
|
|
37
|
+
"@quenty/loader": "^10.9.0",
|
|
38
|
+
"@quenty/maid": "^3.5.0",
|
|
39
|
+
"@quenty/math": "^2.7.3",
|
|
40
|
+
"@quenty/motor6d": "^7.21.0",
|
|
41
|
+
"@quenty/optional": "^11.9.0",
|
|
42
|
+
"@quenty/promise": "^10.11.0",
|
|
43
|
+
"@quenty/qframe": "^10.11.0",
|
|
44
|
+
"@quenty/r15utils": "^13.18.0",
|
|
45
|
+
"@quenty/ragdoll": "^15.24.0",
|
|
46
|
+
"@quenty/remoting": "^12.19.0",
|
|
47
|
+
"@quenty/rx": "^13.18.0",
|
|
48
|
+
"@quenty/servicebag": "^11.12.0",
|
|
49
|
+
"@quenty/signal": "^7.11.0",
|
|
50
|
+
"@quenty/table": "^3.8.0",
|
|
51
|
+
"@quenty/tie": "^10.21.0",
|
|
52
|
+
"@quenty/valueobject": "^13.18.0"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
|
-
"@quenty/rigbuilderutils": "10.20.0
|
|
55
|
+
"@quenty/rigbuilderutils": "^10.20.0"
|
|
56
56
|
},
|
|
57
57
|
"publishConfig": {
|
|
58
58
|
"access": "public"
|
|
59
59
|
},
|
|
60
|
-
"gitHead": "
|
|
60
|
+
"gitHead": "20cff952c2cf06b959f2f11d2293bdef38acc604"
|
|
61
61
|
}
|
|
@@ -12,9 +12,9 @@
|
|
|
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")
|
|
@@ -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
|
package/src/Server/Rig/IKRig.lua
CHANGED
|
@@ -20,9 +20,9 @@ local Rx = require("Rx")
|
|
|
20
20
|
local RxBrioUtils = require("RxBrioUtils")
|
|
21
21
|
local RxInstanceUtils = require("RxInstanceUtils")
|
|
22
22
|
local RxR15Utils = require("RxR15Utils")
|
|
23
|
-
local ValueObject = require("ValueObject")
|
|
24
|
-
local TieRealmService = require("TieRealmService")
|
|
25
23
|
local ServiceBag = require("ServiceBag")
|
|
24
|
+
local TieRealmService = require("TieRealmService")
|
|
25
|
+
local ValueObject = require("ValueObject")
|
|
26
26
|
|
|
27
27
|
local CFA_90X = CFrame.Angles(math.pi / 2, 0, 0)
|
|
28
28
|
local USE_OLD_IK_SYSTEM = (not LimbIKUtils) or false
|
|
@@ -101,7 +101,7 @@ function ArmIKBase:_startUpdateLoop(character)
|
|
|
101
101
|
maid:GiveTask(self:_ensureAnimator(character, self._armName .. "LowerArm", self._armName .. "Elbow", function()
|
|
102
102
|
return self._elbowTransform
|
|
103
103
|
end))
|
|
104
|
-
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()
|
|
105
105
|
return self._wristTransform
|
|
106
106
|
end))
|
|
107
107
|
|
|
@@ -111,31 +111,33 @@ end
|
|
|
111
111
|
function ArmIKBase:_ensureAnimator(character, partName, motorName, getTranform)
|
|
112
112
|
local topMaid = Maid.new()
|
|
113
113
|
|
|
114
|
-
topMaid:GiveTask(RxR15Utils.observeRigMotorBrio(character, partName, motorName)
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
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
|
|
122
124
|
|
|
123
|
-
|
|
125
|
+
local maid, motor6DStack = brio:ToMaidAndValue()
|
|
124
126
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
+
local transformer = Motor6DSmoothTransformer.new(getTranform)
|
|
128
|
+
transformer:SetTarget(1)
|
|
127
129
|
|
|
128
|
-
|
|
130
|
+
local cleanup = motor6DStack:Push(transformer)
|
|
129
131
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
+
maid:GiveTask(function()
|
|
133
|
+
transformer:SetTarget(0)
|
|
132
134
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
135
|
+
task.delay(2, function()
|
|
136
|
+
transformer:Destroy()
|
|
137
|
+
cleanup()
|
|
138
|
+
end)
|
|
136
139
|
end)
|
|
137
|
-
end)
|
|
138
|
-
end))
|
|
140
|
+
end))
|
|
139
141
|
|
|
140
142
|
return topMaid
|
|
141
143
|
end
|
|
@@ -148,116 +150,155 @@ function ArmIKBase:_observeCharacterBrio()
|
|
|
148
150
|
self._characterObservable = RxInstanceUtils.observePropertyBrio(self._humanoid, "Parent", function(parent)
|
|
149
151
|
return parent ~= nil
|
|
150
152
|
end):Pipe({
|
|
151
|
-
Rx.shareReplay(1)
|
|
153
|
+
Rx.shareReplay(1),
|
|
152
154
|
})
|
|
153
155
|
|
|
154
156
|
return self._characterObservable
|
|
155
157
|
end
|
|
156
158
|
|
|
157
|
-
|
|
158
159
|
function ArmIKBase:_observeStateBrio()
|
|
159
160
|
return self:_observeCharacterBrio():Pipe({
|
|
160
161
|
RxBrioUtils.switchMapBrio(function(character)
|
|
161
|
-
local observeUpperTorsoBrio = RxInstanceUtils.observeLastNamedChildBrio(character, "BasePart", "UpperTorso")
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
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
|
+
})
|
|
173
178
|
|
|
174
179
|
local observeShoulderBrio = observeUpperArmBrio:Pipe({
|
|
175
180
|
RxBrioUtils.switchMapBrio(function(upperArm)
|
|
176
181
|
return RxInstanceUtils.observeLastNamedChildBrio(upperArm, "Motor6D", self._armName .. "Shoulder")
|
|
177
|
-
end)
|
|
178
|
-
Rx.shareReplay(1)
|
|
182
|
+
end),
|
|
183
|
+
Rx.shareReplay(1),
|
|
179
184
|
})
|
|
180
185
|
local observeElbowBrio = observeLowerArmBrio:Pipe({
|
|
181
186
|
RxBrioUtils.switchMapBrio(function(lowerArm)
|
|
182
187
|
return RxInstanceUtils.observeLastNamedChildBrio(lowerArm, "Motor6D", self._armName .. "Elbow")
|
|
183
|
-
end)
|
|
184
|
-
Rx.shareReplay(1)
|
|
188
|
+
end),
|
|
189
|
+
Rx.shareReplay(1),
|
|
185
190
|
})
|
|
186
191
|
local observeWristBrio = observeHandBrio:Pipe({
|
|
187
192
|
RxBrioUtils.switchMapBrio(function(hand)
|
|
188
193
|
return RxInstanceUtils.observeLastNamedChildBrio(hand, "Motor6D", self._armName .. "Wrist")
|
|
189
|
-
end)
|
|
190
|
-
Rx.shareReplay(1)
|
|
194
|
+
end),
|
|
195
|
+
Rx.shareReplay(1),
|
|
191
196
|
})
|
|
192
197
|
|
|
193
198
|
return RxBrioUtils.flatCombineLatest({
|
|
194
|
-
UpperTorso = observeUpperTorsoBrio
|
|
195
|
-
UpperArm = observeUpperArmBrio
|
|
196
|
-
LowerArm = observeLowerArmBrio
|
|
197
|
-
Hand = observeHandBrio
|
|
199
|
+
UpperTorso = observeUpperTorsoBrio,
|
|
200
|
+
UpperArm = observeUpperArmBrio,
|
|
201
|
+
LowerArm = observeLowerArmBrio,
|
|
202
|
+
Hand = observeHandBrio,
|
|
198
203
|
|
|
199
|
-
Shoulder = observeShoulderBrio
|
|
200
|
-
Elbow = observeElbowBrio
|
|
201
|
-
Wrist = observeWristBrio
|
|
204
|
+
Shoulder = observeShoulderBrio,
|
|
205
|
+
Elbow = observeElbowBrio,
|
|
206
|
+
Wrist = observeWristBrio,
|
|
202
207
|
|
|
203
208
|
ShoulderMotor6DStack = observeShoulderBrio:Pipe({
|
|
204
209
|
RxBrioUtils.switchMapBrio(function(motor)
|
|
205
|
-
return Motor6DStackInterface:ObserveLastImplementationBrio(
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
210
|
+
return Motor6DStackInterface:ObserveLastImplementationBrio(
|
|
211
|
+
motor,
|
|
212
|
+
self._tieRealmService:GetTieRealm()
|
|
213
|
+
)
|
|
214
|
+
end),
|
|
215
|
+
Rx.defaultsToNil,
|
|
216
|
+
}),
|
|
209
217
|
ElbowMotor6DStack = observeElbowBrio:Pipe({
|
|
210
218
|
RxBrioUtils.switchMapBrio(function(motor)
|
|
211
|
-
return Motor6DStackInterface:ObserveLastImplementationBrio(
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
219
|
+
return Motor6DStackInterface:ObserveLastImplementationBrio(
|
|
220
|
+
motor,
|
|
221
|
+
self._tieRealmService:GetTieRealm()
|
|
222
|
+
)
|
|
223
|
+
end),
|
|
224
|
+
Rx.defaultsToNil,
|
|
225
|
+
}),
|
|
215
226
|
WristMotor6DStack = observeWristBrio:Pipe({
|
|
216
227
|
RxBrioUtils.switchMapBrio(function(motor)
|
|
217
|
-
return Motor6DStackInterface:ObserveLastImplementationBrio(
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
228
|
+
return Motor6DStackInterface:ObserveLastImplementationBrio(
|
|
229
|
+
motor,
|
|
230
|
+
self._tieRealmService:GetTieRealm()
|
|
231
|
+
)
|
|
232
|
+
end),
|
|
233
|
+
Rx.defaultsToNil,
|
|
234
|
+
}),
|
|
221
235
|
|
|
222
236
|
UpperTorsoShoulderRigAttachment = observeUpperTorsoBrio:Pipe({
|
|
223
237
|
RxBrioUtils.switchMapBrio(function(upperTorso)
|
|
224
|
-
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
225
|
-
|
|
226
|
-
|
|
238
|
+
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
239
|
+
upperTorso,
|
|
240
|
+
"Attachment",
|
|
241
|
+
self._armName .. "ShoulderRigAttachment"
|
|
242
|
+
)
|
|
243
|
+
end),
|
|
244
|
+
}),
|
|
227
245
|
UpperArmShoulderRigAttachment = observeUpperArmBrio:Pipe({
|
|
228
246
|
RxBrioUtils.switchMapBrio(function(upperArm)
|
|
229
|
-
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
230
|
-
|
|
231
|
-
|
|
247
|
+
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
248
|
+
upperArm,
|
|
249
|
+
"Attachment",
|
|
250
|
+
self._armName .. "ShoulderRigAttachment"
|
|
251
|
+
)
|
|
252
|
+
end),
|
|
253
|
+
}),
|
|
232
254
|
UpperArmElbowRigAttachment = observeUpperArmBrio:Pipe({
|
|
233
255
|
RxBrioUtils.switchMapBrio(function(upperArm)
|
|
234
|
-
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
235
|
-
|
|
236
|
-
|
|
256
|
+
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
257
|
+
upperArm,
|
|
258
|
+
"Attachment",
|
|
259
|
+
self._armName .. "ElbowRigAttachment"
|
|
260
|
+
)
|
|
261
|
+
end),
|
|
262
|
+
}),
|
|
237
263
|
LowerArmElbowRigAttachment = observeLowerArmBrio:Pipe({
|
|
238
264
|
RxBrioUtils.switchMapBrio(function(lowerArm)
|
|
239
|
-
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
240
|
-
|
|
241
|
-
|
|
265
|
+
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
266
|
+
lowerArm,
|
|
267
|
+
"Attachment",
|
|
268
|
+
self._armName .. "ElbowRigAttachment"
|
|
269
|
+
)
|
|
270
|
+
end),
|
|
271
|
+
}),
|
|
242
272
|
LowerArmWristRigAttachment = observeLowerArmBrio:Pipe({
|
|
243
273
|
RxBrioUtils.switchMapBrio(function(lowerArm)
|
|
244
|
-
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
245
|
-
|
|
246
|
-
|
|
274
|
+
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
275
|
+
lowerArm,
|
|
276
|
+
"Attachment",
|
|
277
|
+
self._armName .. "WristRigAttachment"
|
|
278
|
+
)
|
|
279
|
+
end),
|
|
280
|
+
}),
|
|
247
281
|
HandWristRigAttachment = observeHandBrio:Pipe({
|
|
248
282
|
RxBrioUtils.switchMapBrio(function(hand)
|
|
249
|
-
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
250
|
-
|
|
251
|
-
|
|
283
|
+
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
284
|
+
hand,
|
|
285
|
+
"Attachment",
|
|
286
|
+
self._armName .. "WristRigAttachment"
|
|
287
|
+
)
|
|
288
|
+
end),
|
|
289
|
+
}),
|
|
252
290
|
HandGripAttachment = observeHandBrio:Pipe({
|
|
253
291
|
RxBrioUtils.switchMapBrio(function(hand)
|
|
254
|
-
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
255
|
-
|
|
256
|
-
|
|
292
|
+
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
293
|
+
hand,
|
|
294
|
+
"Attachment",
|
|
295
|
+
self._armName .. "GripAttachment"
|
|
296
|
+
)
|
|
297
|
+
end),
|
|
298
|
+
}),
|
|
257
299
|
})
|
|
258
|
-
end)
|
|
259
|
-
Rx.throttleDefer()
|
|
260
|
-
|
|
300
|
+
end),
|
|
301
|
+
Rx.throttleDefer(),
|
|
261
302
|
})
|
|
262
303
|
end
|
|
263
304
|
|
|
@@ -268,8 +309,8 @@ function ArmIKBase:Grip(attachment, priority)
|
|
|
268
309
|
priority = priority or IKAimPositionPriorites.DEFAULT
|
|
269
310
|
|
|
270
311
|
local gripData = {
|
|
271
|
-
attachment = attachment
|
|
272
|
-
priority = priority
|
|
312
|
+
attachment = attachment,
|
|
313
|
+
priority = priority,
|
|
273
314
|
}
|
|
274
315
|
|
|
275
316
|
local i = 1
|
|
@@ -348,7 +389,6 @@ else
|
|
|
348
389
|
end
|
|
349
390
|
end
|
|
350
391
|
|
|
351
|
-
|
|
352
392
|
if USE_OLD_IK_SYSTEM then
|
|
353
393
|
function ArmIKBase:Update()
|
|
354
394
|
if self:_oldUpdatePoint() then
|
|
@@ -413,13 +453,17 @@ function ArmIKBase:_newUpdate()
|
|
|
413
453
|
local handWristRigAttachment = self._lastState["HandWristRigAttachment"]
|
|
414
454
|
local handGripAttachment = self._lastState["HandGripAttachment"]
|
|
415
455
|
|
|
416
|
-
if
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
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
|
|
423
467
|
return false
|
|
424
468
|
end
|
|
425
469
|
|
|
@@ -433,7 +477,11 @@ function ArmIKBase:_newUpdate()
|
|
|
433
477
|
|
|
434
478
|
-- TODO: Allow configuration
|
|
435
479
|
local ELBOW_ANGLE = math.rad(20)
|
|
436
|
-
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
|
+
)
|
|
437
485
|
|
|
438
486
|
self._shoulderTransform = QFrame.toCFrame(shoulderQFrame)
|
|
439
487
|
self._elbowTransform = QFrame.toCFrame(elbowQFrame)
|
|
@@ -451,10 +499,7 @@ function ArmIKBase:_oldCalculatePoint(targetPositionWorld)
|
|
|
451
499
|
local elbow = self._lastState["Elbow"]
|
|
452
500
|
local wrist = self._lastState["Wrist"]
|
|
453
501
|
local gripAttachment = self._lastState["HandGripAttachment"]
|
|
454
|
-
if not (shoulder
|
|
455
|
-
and elbow
|
|
456
|
-
and wrist
|
|
457
|
-
and gripAttachment) then
|
|
502
|
+
if not (shoulder and elbow and wrist and gripAttachment) then
|
|
458
503
|
return false
|
|
459
504
|
end
|
|
460
505
|
|
|
@@ -490,8 +535,8 @@ function ArmIKBase:_oldCalculatePoint(targetPositionWorld)
|
|
|
490
535
|
end
|
|
491
536
|
|
|
492
537
|
elbowAngle = (elbowAngle - math.pi)
|
|
493
|
-
if elbowAngle > -math.pi/32 then -- Force a bit of bent elbow
|
|
494
|
-
elbowAngle = -math.pi/32
|
|
538
|
+
if elbowAngle > -math.pi / 32 then -- Force a bit of bent elbow
|
|
539
|
+
elbowAngle = -math.pi / 32
|
|
495
540
|
end
|
|
496
541
|
|
|
497
542
|
self._shoulderXAngle = -baseAngle
|
|
@@ -501,5 +546,4 @@ function ArmIKBase:_oldCalculatePoint(targetPositionWorld)
|
|
|
501
546
|
return true
|
|
502
547
|
end
|
|
503
548
|
|
|
504
|
-
|
|
505
|
-
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
|
|
@@ -27,11 +27,17 @@ function ArmIKUtils.ensureMotorAnimated(character: Model, 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,9 +8,9 @@ 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")
|
|
13
12
|
local ServiceBag = require("ServiceBag")
|
|
13
|
+
local promisePropertyValue = require("promisePropertyValue")
|
|
14
14
|
|
|
15
15
|
local IKGripBase = setmetatable({}, BaseObject)
|
|
16
16
|
IKGripBase.ClassName = "IKGripBase"
|
|
@@ -51,17 +51,16 @@ function IKGripBase:PromiseIKRig()
|
|
|
51
51
|
local promise = promisePropertyValue(self._obj, "Value")
|
|
52
52
|
self._maid:GiveTask(promise)
|
|
53
53
|
|
|
54
|
-
self._ikRigPromise = promise
|
|
55
|
-
:
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
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
|
|
60
59
|
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
return self._maid:GivePromise(ikService:PromiseRig(humanoid))
|
|
61
|
+
end)
|
|
63
62
|
|
|
64
63
|
return self._ikRigPromise
|
|
65
64
|
end
|
|
66
65
|
|
|
67
|
-
return IKGripBase
|
|
66
|
+
return IKGripBase
|
|
@@ -5,8 +5,8 @@
|
|
|
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
10
|
local ServiceBag = require("ServiceBag")
|
|
11
11
|
|
|
12
12
|
local IKLeftGrip = setmetatable({}, IKGripBase)
|
|
@@ -27,4 +27,4 @@ function IKLeftGrip.new(objectValue, serviceBag: ServiceBag.ServiceBag)
|
|
|
27
27
|
return self
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
return Binder.new("IKLeftGrip", IKLeftGrip)
|
|
30
|
+
return Binder.new("IKLeftGrip", IKLeftGrip)
|
|
@@ -5,8 +5,8 @@
|
|
|
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
10
|
local ServiceBag = require("ServiceBag")
|
|
11
11
|
|
|
12
12
|
local IKRightGrip = setmetatable({}, IKGripBase)
|
|
@@ -27,4 +27,4 @@ function IKRightGrip.new(objectValue: ObjectValue, serviceBag: ServiceBag.Servic
|
|
|
27
27
|
return self
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
return Binder.new("IKRightGrip", IKRightGrip)
|
|
30
|
+
return Binder.new("IKRightGrip", IKRightGrip)
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
local require = require(script.Parent.loader).load(script)
|
|
6
6
|
|
|
7
7
|
local IKRigInterface = require("IKRigInterface")
|
|
8
|
-
local TieRealmService = require("TieRealmService")
|
|
9
8
|
local ServiceBag = require("ServiceBag")
|
|
9
|
+
local TieRealmService = require("TieRealmService")
|
|
10
10
|
|
|
11
11
|
local IKDataService = {}
|
|
12
12
|
IKDataService.ServiceName = "IKDataService"
|
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
|
|
@@ -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)
|