Viewport Character Cloning Issues

Im trying to make a viewport frame with the character cloned inside which constantly updates so you get a consistent 3d view of yourself.
First, I tried using a .RenderStepped Function and updating every limb’s CFrame but it heavily impact performance.
Now I am using Animator.AnimationPlayed to track whenever an animation is played and replicate it to the character clone. However, as you can see in the image, the animation only plays when the gui first loads and then does not update (it just freezes)
Heres is my code:

local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local Camera = Instance.new("Camera")

Camera.Parent = script.Parent
script.Parent.ViewportFrame.CurrentCamera = Camera
character.Archivable = true
local charClone = character:Clone()
charClone.Parent = script.Parent.ViewportFrame.WorldModel
for _, child in charClone:GetDescendants() do
	if child:IsA("MeshPart") or child:IsA("BasePart") or child:IsA("Shirt") or child:IsA("Pants") or child:IsA("Accessory") or child:IsA("Humanoid") or child:IsA('Decal') then
		--child:Destroy()
	else
		child:Destroy()
	end
end


local con = nil

Camera.CFrame = charClone.UpperTorso.CFrame * CFrame.new(0,1.25,-4) * CFrame.Angles(0,math.rad(180),0)

local Animator = Instance.new("Animator", charClone.Humanoid)

con = humanoid.Animator.AnimationPlayed:Connect(function(track)
	print("playing track")
	for i,v in pairs(charClone.Humanoid.Animator:GetPlayingAnimationTracks()) do
		v:Stop()
	end
	local anim = charClone.Humanoid.Animator:LoadAnimation(track.Animation)
	anim:Play()
	local con2 = nil
	con2 = track.Stopped:Connect(function()
		print("stopping track")
		anim:Stop()
	end)
end)

humanoid.Died:Connect(function()
	con:Disconnect()
	script.Parent:Destroy()
end)

Its printing “playing track” and “stopping track” but the animations dont seem to be being played

Picture of whats happening:

Is there some other way to achieve this viewportframe that I can’t think of? One that doesn’t impact performance too much?

someone please help me, I still cant get this figured out.

I have almost a exact replica of your script and I have the same issue lol, i’ll experiment a bit and i’ll let you know if anything I find works.

Are you sure this is the case? I made one like this a while ago and it ran without any issues.

Here is what I did, and I don’t seem to face any lag troubles.

r.RenderStepped:Connect(function()
	Camera.CFrame = charClone.HumanoidRootPart.CFrame * CFrame.new(0,0.5,-4) * CFrame.Angles(0,math.rad(180),0)
	for i,v in pairs(charClone:GetDescendants()) do
		if v:IsA("Part") or v:IsA("MeshPart") or v:IsA("BasePart") then
			for i,limb in pairs(player.Character:GetDescendants()) do
				if limb:IsA("Part") or limb:IsA("MeshPart") or limb:IsA("BasePart") then
					if limb.Name == v.Name then
						v.CFrame = limb.CFrame
					end
				end
			end
		end
	end
end)

Heyo! I had the same issue and got it working with AnimationPlayed.
The issue I believe was because it was running on ViewportFrame instead in WorldModel which allows animating.
Also for this version, I had it so players have to already had the Animator object so it’s seemless since it sometimes stop the animation for whatever reason when Animator is added to a character.
[I was adding in the Animator later since I had a different use case.]

Fyi, my code sucks a bit since I’m still new to Ui scripting and it was for a ViewportFrame on a SurfaceGui instead, so it’s a bit different. But it’s still clientsided so it should still work if you implement it the same way.

--!strict
local Screen1GuiVPF = script.Parent.Screen1Gui:WaitForChild("CharacterVPF")
local Screen1GuiWorldModel = Screen1GuiVPF:WaitForChild("WorldModel")

local Camera = Instance.new("Camera")

local currentCharacter
local clonedCharacter

local Module = {}
Module._scriptConnector = nil :: RBXScriptConnection?

function Module.Start(p :Player)
	Screen1GuiVPF.CurrentCamera = Camera
	Camera.Parent = Screen1GuiWorldModel
	
	currentCharacter = p.Character :: Model
	currentCharacter.Archivable = true
	
	local humanoid = currentCharacter:FindFirstChildOfClass("Humanoid") ::Humanoid
	local animator = humanoid:FindFirstChildOfClass("Animator") ::Animator
	assert(animator, "Host animator doesn't exist.")

	clonedCharacter = currentCharacter:Clone()
	clonedCharacter.Parent = Screen1GuiWorldModel
	local cHumanoid = clonedCharacter:FindFirstChildOfClass("Humanoid") ::Humanoid
	local cAnimator = cHumanoid:FindFirstChildOfClass("Animator") ::Animator
	assert(cAnimator, "cAnimator doesn't exist.") --Should exist if the player already has an Animator.
	
	local hrp = clonedCharacter:WaitForChild("HumanoidRootPart") ::Part
	Screen1GuiWorldModel.PrimaryPart = hrp
	Camera.CFrame = CFrame.new(hrp.Position + (hrp.CFrame.LookVector * 10), hrp.Position)
	
	Module._scriptConnector = animator.AnimationPlayed:Connect(function(t :AnimationTrack)
		for i,v in pairs(cAnimator:GetPlayingAnimationTracks()) do
			v:Stop()
		end
		 
		local animation = t.Animation ::Animation
		
		local cAnimation = cAnimator:LoadAnimation(animation)
		cAnimation:Play()
		
		local con2 = nil
		con2 = t.Stopped:Connect(function()
			cAnimation:Stop()
		end)
	end)
end


return Module 

Please let me know if this doesn’t work since I suck at this a bit still. :sweat_smile: