Hats on ViewportFrame Character Broken?

So, I have my system which clones the player’s model into a viewport frame. However, the hats on the character that is in the ViewportFrame(ViewportFrameCharacter), are being glitchy. I put the ViewportFrame Character model in workspace to see if the hats would still glitch out; however, the hats were normally placed. Does anyone have any clue on why this occurs?

I appreciate any and all help I receive.

https://gyazo.com/6dbec4d45cd3ba1eaafcb213f5be55f2

local RunService = game:GetService('RunService')
local Players = game:GetService("Players")

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

local viewportFrame = script.Parent
local viewportFrameCamera = Instance.new("Camera")

local viewportFrameCharacter = Instance.new("Model") -- frame character
local viewportProxyCharacter = Instance.new("Model") -- proxy

local anims = script.animations

local part = workspace.Part
local sword = script.Parent.sword

local idleAnim

viewportFrame.CurrentCamera = viewportFrameCamera
viewportFrameCamera.Parent = viewportFrame
viewportFrameCharacter.Name = player.Name
viewportProxyCharacter.Parent = workspace
viewportProxyCharacter.Name = player.Name

wait(2)

for _,v in pairs(character:GetChildren()) do
    v:Clone().Parent = viewportFrameCharacter
    v:Clone().Parent = viewportProxyCharacter
end

viewportFrameCharacter.PrimaryPart = viewportFrameCharacter.HumanoidRootPart
viewportProxyCharacter.PrimaryPart = viewportProxyCharacter.HumanoidRootPart

local proxyHumanoid = viewportProxyCharacter:FindFirstChild("Humanoid")
idleAnim = proxyHumanoid:LoadAnimation(anims.idle)
idleAnim:Play()

sword:Clone().Parent = viewportFrameCharacter
sword:Clone().Parent = viewportProxyCharacter
viewportProxyCharacter:MoveTo(part.Position)
viewportFrameCharacter.Parent = viewportFrame

RunService:BindToRenderStep("UpdateVPCharacter", Enum.RenderPriority.Last.Value, function()
	viewportFrameCamera.CFrame = viewportFrameCharacter.HumanoidRootPart.CFrame*CFrame.new(0,0,-5.5,0,1,0,0)
    local realCharacter = viewportProxyCharacter
    if realCharacter then
    for _, descendant in pairs(viewportFrameCharacter:GetDescendants()) do
        if descendant:IsA("BasePart") then
            local realMotor = realCharacter:FindFirstChild(descendant.Name, true)
            if realMotor then
	--print(typeof(descendant) ,typeof( realMotor))
	-- print(typeof(descendant.CFrame) ,typeof( realMotor.CFrame))
                descendant.CFrame = realMotor.CFrame
            end
         end
     end
    end
end)
6 Likes

Yea ive tried it (without the sword and playing the anim) and it dosent show the hats or my arms. dont know whats wrong…

Have you tried manually setting the accessory’s attachment offset values through the script?

1 Like

also the hats (for me) fall off and the whole character is not anchored

I will try that and get back to you.

What values exactly? All of the offsets on the Proxy Model and the Viewport model are both the same.

It’s possible that there are some instances in your character with the same name, which could mean you’re setting the wrong CFrame. Instead of finding the parts in the other character using its name, you could create a table where each key is the viewportProxyCharacter’s part, and the value is the viewportFrameCharacter’s part. Then, instead of looping through the model, you would loop through the table and set the value’s CFrame to the key’s CFrame.

1 Like

It’s what @slo_w mentioned, as part names of hats are usually named Handles, and having more than one hat will set all the other hats to the same CFrame. The above methods works too but if you prefer to stick with what you wrote you can include this:

local RunService = game:GetService('RunService')
local Players = game:GetService("Players")

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

local viewportFrame = script.Parent
local viewportFrameCamera = Instance.new("Camera")

local viewportProxyCharacter = Instance.new("Model")

local anims = script.animations

local part = workspace.Part
local sword = script.Parent.sword

local idleAnim

viewportFrame.CurrentCamera = viewportFrameCamera
viewportFrameCamera.Parent = viewportFrame
viewportProxyCharacter.Parent = workspace
viewportProxyCharacter.Name = player.Name

wait(2)

for _,v in pairs(character:GetChildren()) do
    v:Clone().Parent = viewportProxyCharacter
end

viewportProxyCharacter.PrimaryPart = viewportProxyCharacter.HumanoidRootPart

local proxyHumanoid = viewportProxyCharacter:FindFirstChild("Humanoid")
idleAnim = proxyHumanoid:LoadAnimation(anims.idle)
idleAnim:Play()

sword:Clone().Parent = viewportProxyCharacter
viewportProxyCharacter:MoveTo(part.Position)

for _, descendant in pairs(viewportProxyCharacter:GetDescendants()) do -- added to rename handle hat parts
	if descendant:IsA("BasePart") and descendant.Parent:IsA("Accoutrement") then 
		descendant.Name = descendant.Name..descendant.Parent.Name
		wait()
	end
end

local viewportFrameCharacter = viewportProxyCharacter:Clone()
viewportFrameCharacter.Parent = viewportFrame

RunService:BindToRenderStep("UpdateVPCharacter", Enum.RenderPriority.Last.Value, function()
	viewportFrameCamera.CFrame = viewportFrameCharacter.HumanoidRootPart.CFrame*CFrame.new(0,0,-5.5,0,1,0,0)
    local realCharacter = viewportProxyCharacter
    if realCharacter then
    for _, descendant in pairs(viewportFrameCharacter:GetDescendants()) do
        if descendant:IsA("BasePart") then
            local realMotor = realCharacter:FindFirstChild(descendant.Name, true)
            if realMotor then
                descendant.CFrame = realMotor.CFrame
            end
         end
     end
    end
end)

That should fix the hats.

Edit: What now happens is just before the viewportFrameCharacter is created and sent to the Viewport, I included in a loop to check for accessories and to include their accessory name along with the original handle part to prevent duplicate handles being found when you search and update any baseparts.

2 Likes

Thank you and @slo_w so much. I was so clueless with this for a long time. I thank you greatly.

Do you mind explaining the parts you edited? It still doesn’t add up much to me still.