im essentially making a custom animator for a combat security system. this is what i believe one of the last 3 things i need to do in this system. its optimized for 200 player servers.
i have a dictionary of cframes which are the cframes in the poses of a keyframe.
this is pretty much what it looks like, generalized for keyframes which only have all the r6 bodyparts for poses+subposes
{Torso = keyframe.HumanoidRootPart.Torso.CFrame,
Head = keyframe.HumanoidRootPart.Torso.Head.CFrame,
['Left Arm'] = keyframe.HumanoidRootPart.Torso['Left Arm'].CFrame,
['Right Arm'] = keyframe.HumanoidRootPart.Torso['Right Arm'].CFrame,
['Left Leg'] = keyframe.HumanoidRootPart.Torso['Left Leg'].CFrame,
['Right Leg'] = keyframe.HumanoidRootPart.Torso['Right Leg'].CFrame}
these are changing constantly as the ‘animation’ plays programmatically (or not constantly, but rather they are updated depending on when pretender:Get() is called. pretender:Get() returns this dictionary)
i start the ‘animation’ with pretender:Play(animationName, ...)
and i get the limb pose cframes at the current time with pretender:Get()
while (1) do
pretender:Play('test', .3, .1, 1, 1)
for i = 1, 55 do
local d = pretender:Get()
for _, v in ipairs(workspace.Rig:GetChildren()) do
if (d[v.Name]) then
if (v.Name == 'Torso') then
-- ignore these 2 lines below.
print('torsoed')
v.CFrame = initialLimbCFrames['Torso'] * d[v.Name]
else
v.CFrame = initialLimbCFrames[v.Name] * d[v.Name]
end
end
end
RunService.Heartbeat:Wait()
end
wait(1)
end
initialLimbCFrames is the initial cframes of each r6 body part. not the cframes of the poses, but the cframes in world position
as the ‘animation’ plays, it shows this
it should show this
ignore the fact that the latter has a gun. also ignore the fact that it is slower- i made a mistake when programming the system and its not that big of a deal, i can fix it.
my question is, how do i set a parts cframe based on the corresponding poses cframe, as clearly it does not work as intedned. im struggling to find the cframe manipulation that does this
this is a piece of the pretender:Get() function thats involved with creating that dictionary i showed at the start of the post.
local cfScalarArray = {}
for k, v in next, locomotives do -- let k be the name of the limb and v a dictionary with an array called 'data' filled with arrays that have the pose cframe for the corresponding limb
if (not cfScalarArray[k]) then
cfScalarArray[k] = CFrame.identity
end
for _, datum in ipairs(v.data) do
local x, y, z, r00, r01, r02, r10, r11, r12, r20, r21, r22 = datum.CFrame:GetComponents()
-- ive tried flipping the lookvector, no luck
-- by the way these 3 lines of code below does an inverted mesh thingy which could be used for cell shading. its really cool and not easy to explain without an image which would make this post offtopic
--[[r02 *= -1
r12 *= -1
r22 *= -1]]
local newCF = CFrame.new(x, y, z, r00, r01, r02, r10, r11, r12, r20, r21, r22)
--local aY, aX, aZ = newCF:ToEulerAnglesYXZ()
--newCF *= CFrame.Angles(aZ, aY, aX) -- ive swapped each argument all 6 times, no luck
cfScalarArray[k] *= newCF
end
end
--...
return cfScalarArray