ViewPortFrame Character Animation

I just mean to clone the template from wherever you’ve stored it originally, such as ReplicatedStorage. Then, for each emote, clone that template and animate the NPC within. Make sure you’re pathing to the correct ones instead of the original (which would of course be taken care of inherently with the for loop iteration).

What you’ve got now looks a bit over-engineered to me. I think you should redo it more simply and straight to the point.

Ah, I see what you mean. So, for each emote in the emotesfolder, you’re suggesting I make a clone of the template originally and store that, so when the client needs one they can just access it from there?

Sorry for asking so many questions, I’m still pretty new with WorldModels. Also, would this prevent the bug with animations not playing?

I don’t think WorldModel has anything to do with this issue. If I had to guess, it would have to do with how you’re handling the animation and cloning.

But yes, clone the templates and use those cloned templates. Animate each cloned template directly.

This would prevent the bug with animations not playing.

1 Like

The issue is that I need to use a viewportframe. What I’ve read, the only way to have a model be animated inside this ViewportFrame is using a worldmodel. I’ve tried without using WorldModels and it just didn’t work. Are you suggesting that I use a camera and a physical object?

Okay, I’ll give this a try and let you know.

No, you need both a Viewport and a WorldModel. I’m saying to clone a template of all of that together with the NPC, and clone it for each animation. Then, for each clone, load and play the animation.

I tried this, and it didn’t work. The animation just isnt playing.
(Sorry for the confusion with the previous reply, it’s getting to be pretty late and I’ve been doing this for a few hrs)

Are you loading the animation into the cloned NPC of each individually cloned template? Make sure you’re not animating the original uncloned template.

Yeah, for each NPC i’m playing the animation on the NPC, I’ve tried both on the client and the server.
(I’m currentely creating the viewports on the server and importing / playing the anims on the client)
Everything prints right, the animation loads, the isplaying prints right, it just… doesnt.

Have you started over doing it more simply without modules or anything fancy? Just use a basic for loop, clone all of the required templates and animation, then play the correct animation for the corresponding NPC.

Everything can be done on the client, the server isn’t needed for anything here. You don’t even need it to play the animation on the real character, as that replicates automatically.

Yeah, I made it as simple as possible. Here’s my current code if you want it.

Code in serverscriptservice

local emoteFolder = game.ReplicatedStorage:WaitForChild("Emotes")
local template = script:WaitForChild("tempViewport")
local viewportFolder = game.ReplicatedStorage:WaitForChild("Viewports")

for i, emote in emoteFolder:GetChildren() do
	local newTemp = template:Clone()
	newTemp.Name = emote.Name
	newTemp.Parent = viewportFolder
end

Code in startergui

local emote = "dance1"

task.wait(3)
local viewport = game.ReplicatedStorage:WaitForChild("Viewports")[emote]
local emote = game.ReplicatedStorage:WaitForChild('Emotes')[emote]

local track = viewport.WorldModel.NPC.Humanoid.Animator:LoadAnimation(emote)
track.Looped = true
track:Play()

print(track)

viewport.Parent = script.Parent

The same issue is happening where the viewport has the char in it but it doesnt play the animation
I’ll try making it all on the client and lyk.

Update; switching it to local still doesn’t fix anything. At this point do I file a bug report?

Gonna try reuploading the animations and seeing if that does anything

Have you tried parenting before playing the animation?

My animation is still working, the same thing I did originally for this thread. Except I’m just using it to show the player’s character using their current idle animation. So I just clone their character into the WorldModel that’s inside the Viewport. The animation LocalScript that’s already in the character animates it automatically. Also the LocalScript doesn’t need to be inside the WorldModel or character, it’ll work from anywhere as long as the path is correct.

I was using the r15 anims on an r6 character. If I go missing tommorow, you will know why.

Sleep is an important part of development.

Also, while not needed in this case, you might find this interesting:

That’s a really cool article, I’ll look into it.
I’m sorry for wasting your time, gonna get some sleep so I dont try to set backgroundtransparency to a color3 :sob:

1 Like

this is amazing thank you so much

After testing and researching, I found a way to replicate the animations inside a ViewPortFrame.
Here is the complete process:

Step-by-Step Process

1. Clone the Character:
First, I created a function that clones only the visible and relevant parts of the character, excluding scripts and other unnecessary elements.

local player = game.Players.LocalPlayer

local function CloneCharacter(char)
    local newModelCharacter = Instance.new("Model")

    for i, part in pairs(char:GetChildren()) do
        if not part:IsA("BaseScript") then
            local newPart = part:Clone()
            newPart.Parent = newModelCharacter
        end
    end

    return newModelCharacter
end

2. Add the Clone to the WorldModel:
Once the character was cloned, I added it to the WorldModel inside the ViewPortFrame.

local PlayerCharacter = CloneCharacter(player.Character)
PlayerCharacter.Parent = WorldModel

3. Set up the Camera:
I created a camera for the ViewPortFrame and positioned it to properly show the character from a suitable distance.

local viewportCamera = Instance.new("Camera")
VPF.CurrentCamera = viewportCamera
viewportCamera.Parent = VPF
viewportCamera.CFrame = CFrame.new(PlayerCharacter.HumanoidRootPart.Position - Vector3.new(0, 0, 8)) 
                          * CFrame.Angles(0, math.rad(180), 0)

4. Update the Character Periodically:
I implemented a recursive function to continuously update the model inside the ViewPortFrame. This ensures that the character’s animations and changes are reflected.

local function UpdateCharacterView()
    task.spawn(function()
        local VPF: ViewportFrame = player.PlayerGui.Inventory.Content.EquipmentContent.CharacterView
        local WM: WorldModel = VPF.WorldModel
        WM:ClearAllChildren()

        local PlayerCharacter = CloneCharacter(player.Character)
        PlayerCharacter.Parent = WM

        local viewportCamera = Instance.new("Camera")
        VPF.CurrentCamera = viewportCamera
        viewportCamera.Parent = VPF
        viewportCamera.CFrame = CFrame.new(PlayerCharacter.HumanoidRootPart.Position - Vector3.new(0, 0, 5)) 
                                  * CFrame.Angles(0, math.rad(180), 0)

        task.wait()
        UpdateCharacterView() -- Call itself again after waiting
    end)
end

Complete Code

Here is the complete code I implemented:

local player = game.Players.LocalPlayer

local function CloneCharacter(char)
    local newModelCharacter = Instance.new("Model")

    for i, part in pairs(char:GetChildren()) do
        if not part:IsA("BaseScript") then
            local newPart = part:Clone()
            newPart.Parent = newModelCharacter
        end
    end

    return newModelCharacter
end

local function UpdateCharacterView()
    task.spawn(function()
        local VPF: ViewportFrame = player.PlayerGui.Inventory.Content.EquipmentContent.CharacterView
        local WM: WorldModel = VPF.WorldModel
        WM:ClearAllChildren()

        local PlayerCharacter = CloneCharacter(player.Character)
        PlayerCharacter.Parent = WM

        local viewportCamera = Instance.new("Camera")
        VPF.CurrentCamera = viewportCamera
        viewportCamera.Parent = VPF
        viewportCamera.CFrame = CFrame.new(PlayerCharacter.HumanoidRootPart.Position - Vector3.new(0, 0, 5)) 
                                  * CFrame.Angles(0, math.rad(180), 0)

        task.wait()
        UpdateCharacterView()
    end)
end

player.CharacterAdded:Connect(function()
    UpdateCharacterView()
end)

Result

With this implementation, I was able to replicate the animations of the original character inside a ViewPortFrame.

Feedback

If anyone has a more efficient way to achieve this result, I would appreciate any suggestions or improvements.
I hope this is helpful to those who are trying to solve the same issue.

1 Like