WorldModel and character animation in viewport frame?

I’m trying to play an animation in a viewport frame on a copy of the players character.
The code goes as following:

  1. Create worldmodel and camera for viewport
  2. Clone MeshParts, Parts, Motor6Ds, Welds and the Humanoid from the real character
  3. Load Idle animation into Animator
  4. Play Animation

However, no animations play. When I print .IsPlaying for the animation track it says true.
I know there are many threads discussing character animation in viewports. I am not asking how to do it, instead does the WorldModel actually do what it should?

Viewport hirearchy:
RobloxStudioBeta_h1x7SJfY2L

Function which handles the viewport:

local function updateCharacterViewport()
    local viewport = gui.Menu.CharacterViewport

    --check for camera and instance new if needed
    local vpCamera = viewport:FindFirstChild("vpCamera")
    if not vpCamera then
        vpCamera = Instance.new("Camera")
        vpCamera.Parent = viewport
        viewport.CurrentCamera = vpCamera
    end

    --check for world model and instance new if needed
    local worldModel = viewport:FindFirstChild("WorldModel")
    if not worldModel then
        worldModel = Instance.new("WorldModel")
        worldModel.Parent = viewport
    end

    --look for old character model and remove if there
    local oldChar = viewport.WorldModel:FindFirstChild("CharModel")
    if oldChar then
        oldChar:Destroy()
    end

    --clone and set up new character model
    local newChar = Instance.new("Model")
    newChar.Name = "CharModel"
    for _, child in ipairs(player.Character:GetChildren()) do
        if child:IsA("Part") or child:IsA("MeshPart") or child:IsA("Motor6D") or child:IsA("Weld") or child:IsA("Humanoid") then
            local childClone = child:Clone()
            childClone.Parent = newChar
        end
    end
    newChar.PrimaryPart = newChar.HumanoidRootPart
    newChar:SetPrimaryPartCFrame(CFrame.new(0,0,0))
    newChar.Name = "CharModel"
    newChar.Parent = worldModel
    --play idle animation on character
    local anim = newChar.Humanoid.Animator:LoadAnimation(replicatedStorage.Effect:WaitForChild("ViewportIdleAnim"))
    anim:Play()
    print(anim.IsPlaying) --prints true

    --make camera face model
    vpCamera.CFrame = CFrame.new(Vector3.new(2, 2, -4), newChar.PrimaryPart.Position)
end
2 Likes

I managed to fix it myself!

Turns out my method of cloning the character wasn’t working. I believe I wasn’t cloning the animator inside of the humanoid before.
The method that worked for me was to clone the character and then remove anything extra from it. (Especially scripts since you don’t want double character scripts!)

Part of code that was edited:

    --enable archivable and clone then disable
    player.Character.Archivable = true
    local viewportCharacter = player.Character:Clone()
    player.Character.Archivable = false

    --destroy uneeded stuff
    for _, child in ipairs(viewportCharacter:GetDescendants()) do
        if not child:IsA("MeshPart") and not child:IsA("BasePart") and not child:IsA("Motor6D") and not child:IsA("Weld") and not child:IsA("Humanoid") and not child:IsA("Animator") then
            child:Destroy()
        end
    end

    viewportCharacter.Name = "CharModel"
    viewportCharacter:SetPrimaryPartCFrame(CFrame.new(0,0,0))
    viewportCharacter.Parent = worldModel

    --play idle animation on character
    local anim = viewportCharacter.Humanoid.Animator:LoadAnimation(replicatedStorage.Effect:WaitForChild("ViewportIdleAnim"))
    anim:Play()
7 Likes