I’m animating a bunch of weapons in Blender and I realize that to animate bigger weapons/tools such as rifles, big swords, and big shields, it’s very convenient to have the motor6D
that connects the tool to the character to have its part0
as the character’s UpperTorso
, however, the way I’m scripting those weapons and the features I’m implementing makes very convenient to have this motor’s part0 as the character’s RightHand
.
Blender’s bone constraints could easily solve this dilemma of mine, but the plugin I’m using to convert motor6D animations to bone animations and vice versa doesn’t seem to handle well these constraints:
So I’m wondering: how could I convert a motor6D
’s part0
in an animation by script? This way I could animate with the tool on the UpperTorso
and convert the animations so they have the tool connected to the RightHand
.
I’m pretty sure there’s a way since I messed around a bit with the keyframe sequences’ documentation, and made this local plugin:
local serverStorage = game:GetService("ServerStorage")
local selection = game:GetService("Selection")
local toolbar = plugin:CreateToolbar("viewmodelVisualizer")
local changeMotorPart0 = toolbar:CreateButton(
"changeMotorPart0",
"Change the part0 of a motor6D while keeping the correct offset",
"rbxassetid://17395316136"
)
local pluginFolder = script.Parent
changeMotorPart0.Click:Connect(function()
local selectionTable = selection:Get()
local rig = selectionTable[4]
local desiredPart0 = selectionTable[3]
local motorToConvert = selectionTable[2]
local keyframeSequence = selectionTable[1]
print("Rig:" .. rig)
print("Motor to convert:" .. motorToConvert)
print("Desired part0:" .. desiredPart0)
if not keyframeSequence:IsA("KeyframeSequence") then
warn("The first selection must be a KeyframeSequence.")
return
end
if not motorToConvert:IsA("Motor6D") then
warn("The second selection must be a Motor6D.")
return
end
if not desiredPart0:IsA("BasePart") then
warn("The third selection must be a BasePart.")
return
end
if not rig:IsA("Model") then
warn("The fourth selection must be a Model (the rig).")
return
end
local keyframes = {}
for _, c in keyframeSequence:GetChildren() do
if not c:IsA("Keyframe") then continue end
table.insert(keyframes, c)
end
table.sort(keyframes, function(l, r)
return l.Time > r.Time
end)
local originalC0s = {}
for _, keyframe in keyframes do
for _, pose in keyframe:GetDescendants() do
local posePart = rig:FindFirstChild(pose.Name, true)
local partMotor6d = posePart:FindFirstChildOfClass("Motor6D")
if not partMotor6d then continue end
originalC0s[partMotor6d] = partMotor6d.C0
end
end
for i, keyframe in keyframes do
local keyframePoses = {}
for _, pose in keyframe:GetDescendants() do
local posePart = rig:FindFirstChild(pose.Name, true)
local partMotor6d = posePart:FindFirstChildOfClass("Motor6D")
if not partMotor6d then continue end
partMotor6d.C0 = originalC0s[partMotor6d] * pose.CFrame
end
local part1Pose = keyframe:FindFirstChild(motorToConvert.Part1.Name, true)
part1Pose.CFrame = desiredPart0.CFrame:Inverse() * part1Pose.CFrame
local parent = keyframe:FindFirstChild(desiredPart0.Name, true)
part1Pose.Parent = parent
end
end)
but it’s very crappy and not working.
Any help is appreciated, and let me know if you need additional information or don’t understand something about the problem.
Btw if there’s already a plugin for that let me know, please.