Converting Roblox Gameplay into an Animation (unsolved)

Hello there! This is my first devforum post. So, I’m trying to figure out on how I could convert the Player’s gameplay into an animation. Basically it converts the player’s cframes into a keyframesequence. I asked AI to do it but there are some problems that I’m facing, and the AI can’t solve it. So here is the script that the AI provided for me. (The script is located in serverscriptservice.)

local ReplicatedStorage = game:GetService("ReplicatedStorage")

-- Function to record player's gameplay and convert it into KeyframeSequence poses
local function recordAndSaveAnimation(player)
	print("Recording animation for player:", player.Name)

	-- Wait for the player's character to spawn
	local character = player.Character or player.CharacterAdded:Wait()
	character:WaitForChild("HumanoidRootPart")

	print("Character found for player:", player.Name)

	-- Create a KeyframeSequence
	local keyframeSequence = Instance.new("KeyframeSequence")
	keyframeSequence.Name = "RecordedAnimation_" .. player.UserId

	-- Record player's gameplay for the specified duration
	local duration = 3 -- Recording duration in seconds
	local frameRate = 60 -- Frame rate
	local timeStep = 1 / frameRate
	local elapsedTime = 0 -- Elapsed time counter

	-- Get the initial character position
	local initialPosition = character:WaitForChild("HumanoidRootPart").Position

	while elapsedTime < duration do
		wait(timeStep)

		-- Create a Keyframe for the current frame
		local keyframe = Instance.new("Keyframe")
		keyframe.Time = elapsedTime

		-- Iterate over all parts in the character
		for _, part in ipairs(character:GetDescendants()) do
			if part:IsA("BasePart") then
				-- Calculate relative CFrame
				local relativeCFrame = CFrame.new(part.Position - initialPosition, part.Position)

				-- Create a pose for the part with the adjusted CFrame
				local pose = Instance.new("Pose")
				pose.Name = part.Name
				pose.CFrame = relativeCFrame
				keyframe:AddPose(pose)
			end
		end

		-- Add the keyframe to the KeyframeSequence
		keyframeSequence:AddKeyframe(keyframe)

		print("Added keyframe at time:", elapsedTime)

		-- Increment elapsed time
		elapsedTime = elapsedTime + timeStep
	end

	-- Save KeyframeSequence to ReplicatedStorage
	keyframeSequence.Parent = ReplicatedStorage

	print("Saved KeyframeSequence for player:", player.Name)
end

-- Connect the function to player added event
game.Players.PlayerAdded:Connect(recordAndSaveAnimation)

The only problem that I’m facing is that it the animation isn’t display correctly. This is what it look like.

Screenshot 2024-05-07 at 1.51.02 PM

So yea. If you have any ideas or suggestions or something that might be able to solve this, you can drop it here.

I’m not seeing a lot of help here and I’m no expert but I’ll share a few ideas:

In that documentation there is an example code snippet that looks like what you might be trying to do.
Some untested ideas:

  • It uses Pose:AddSubPose
  • Instead of looping through parts it goes through joints, which I believe is what a Pose is (a Motor6D.Transform?)
local function generateKeyframe(model)
	if not model.PrimaryPart then
		warn("No primary part set")
		return
	end

	local rootPart = model.PrimaryPart:GetRootPart()

	if not rootPart then
		warn("Root part not found")
		return
	end

	local partsAdded = {}
	partsAdded[rootPart] = true

	local function addPoses(part, parentPose)
		-- get all of the joints attached to the part
--[[ First notable change in the target of the loop ]]--
		for _, joint in pairs(part:GetJoints()) do
			-- we're only interested in Motor6Ds
			if joint:IsA("Motor6D") then
				-- find the connected part
				local connectedPart = nil
				if joint.Part0 == part then
					connectedPart = joint.Part1
				elseif joint.Part1 == part then
					connectedPart = joint.Part0
				end
				if connectedPart then
					-- make sure we haven't already added this part
					if not partsAdded[connectedPart] then
						partsAdded[connectedPart] = true
						-- create a pose
						local pose = Instance.new("Pose")
						pose.Name = connectedPart.Name
--[[ Second notable change in adding poses ]]--
						parentPose:AddSubPose(pose)
						-- recurse
						addPoses(connectedPart, pose)
					end
				end
			end
		end
	end

	local keyframe = Instance.new("Keyframe")

	-- populate the keyframe
	local rootPose = Instance.new("Pose")
	rootPose.Name = rootPart.Name
	addPoses(rootPart, rootPose)
	keyframe:AddPose(rootPose)

	return keyframe
end

local character = script.Parent

local keyframe = generateKeyframe(character)

print(keyframe)
2 Likes

I’m not an expert at scripting, so I asked AI to make a script with that. However, the AI made the script worser whenever I keep asking to fix some bugs that I have with the script.

There is this devforum that I found while searching, and this user managed to get it properly. It’s just that it’s in R6, and I’m trying to make it R15. I think it might have something to do with Motor6ds, Transform, and SolveForTransform. But when I asked AI for that, it still keeps having errors and bugs and AI keeps reusing some lines from previous scripts as usual. This is the devforum here:

https://devforum.roblox.com/t/help-with-script-characters-workspace-cframe-to-keyframe-cframe/2152064

There is another devforum that I found and is facing some kind of an issue where all the body parts are not properly placed in the correct positions, just like the issue that I was facing.

https://devforum.roblox.com/t/bodypart-cframe-to-motor6d-conversion/616235

This video below is what I’m trying to achieve and how this person made it work. Sadly they didn’t give us the actual method to this.

https://youtu.be/HSCCOaFUQ0c?si=KCwE6Ac6jenY9nfT

Also, the AI that I was using is a website version so I’m thinking of getting a program version of it if I wanted to.

I’ll try to figure this out some other time. Feel free to put any ideas or suggestions here.