Mirroring Curve Animations

Hello, recently I’ve needed a way to mirror animations made with the curve editor, and while I found many resources to mirror KeyframeSequences, I couldn’t find any for CurveAnimations, so I decided to write this:

--change to your character's body parts
local bodyPartPairs = {
	{"LeftUpperArm", "RightUpperArm"},
	{"LeftLowerArm", "RightLowerArm"},
	{"LeftHand", "RightHand"},
	{"LeftUpperLeg", "RightUpperLeg"},
	{"LeftLowerLeg", "RightLowerLeg"},
	{"LeftFoot", "RightFoot"}
}

local function mirrorCurveAnimation(curveAnimation)
	local mirroredCurveAnimation = curveAnimation:Clone()
	local affectedBodyParts = {}
	
	for index, instance in mirroredCurveAnimation:GetDescendants() do
		if instance:IsA("Vector3Curve") then
			table.insert(affectedBodyParts, instance.Parent)
		end
	end
	
	for index, affectedBodyPart in affectedBodyParts do
		local foundPair
		for index, pair in bodyPartPairs do
			if affectedBodyPart.Name == pair[1] then
				foundPair = pair[2]
				break
			elseif affectedBodyPart.Name == pair[2] then
				foundPair = pair[1]
				break
			end	
		end
		
		if foundPair then
			affectedBodyPart.Name = foundPair
		end
		
		for index, key in affectedBodyPart.Rotation:Z():GetKeys() do
			local mirroredKeyData = FloatCurveKey.new(key.Time, -key.Value, key.Interpolation)
			
			mirroredKeyData.RightTangent = if key.RightTangent then -key.RightTangent else nil
			mirroredKeyData.LeftTangent = if key.LeftTangent then -key.LeftTangent else nil
			
			affectedBodyPart.Rotation:Z():InsertKey(mirroredKeyData)
		end
		
		for index, key in affectedBodyPart.Rotation:Y():GetKeys() do
			local mirroredKeyData = FloatCurveKey.new(key.Time, -key.Value, key.Interpolation)
			mirroredKeyData.RightTangent = if key.RightTangent then -key.RightTangent else nil
			mirroredKeyData.LeftTangent = if key.LeftTangent then -key.LeftTangent else nil

			affectedBodyPart.Rotation:Y():InsertKey(mirroredKeyData)
		end

		for index, key in affectedBodyPart.Position:X():GetKeys() do
			local mirroredKeyData = FloatCurveKey.new(key.Time, -key.Value, key.Interpolation)
			mirroredKeyData.RightTangent = if key.RightTangent then -key.RightTangent else nil
			mirroredKeyData.LeftTangent = if key.LeftTangent then -key.LeftTangent else nil

			affectedBodyPart.Position:X():InsertKey(mirroredKeyData)
		end
	end
	
	mirroredCurveAnimation.Name = curveAnimation.Name.."_mirrored"
	return mirroredCurveAnimation
end

--set originalCurveAnimation to the curve animation location
local originalCurveAnimation = game.ServerStorage.RBX_ANIMSAVES.Rig["Animation"]
local mirror = mirrorCurveAnimation(originalCurveAnimation)
mirror.Parent = originalCurveAnimation.Parent

To use this, just set the variable “originalCurveAnimation” to wherever the CurveAnimation is located and paste it into the command line, and it should hopefully work. If you have any issues, let me know!

How to use with R6

To make it work with R6 all you have to do is change the bodyPartPairs table to the parts in an R6 character like so:

local bodyPartPairs = {
	{"Left Arm", "Right Arm"},
	{"Left Leg", "Right Leg"},
}
5 Likes