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
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.