How to render a character within a ViewportFrame

Hello, this is a basic method to load characters within a ViewportFrame.

MEDIA
https://gyazo.com/e12e81fc877bc9c4f624f77e583be60a

First place a ScreenGui into StarterGui
then you can place a ViewportFrame and LocalScript into the ScreenGui.

TbzidiwfTHyqugeK1kJv9g

Here is the local script, it has a mini tutorial within it.

--1). Setup some variables and grab the ViewportFrame
local viewport = script.Parent:WaitForChild("ViewportFrame")
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local zoom = -5



--2). Create a camera and place it inside of the viewport frame
local camera = Instance.new("Camera")
camera.Parent=viewport
viewport.CurrentCamera = camera


--3). Create an invisible part that will 'control' the cameras orbit easily.
local invisiblePart = Instance.new("Part")
invisiblePart.Size = Vector3.new(1,1,1)
invisiblePart.Transparency = 1
invisiblePart.Parent=viewport
invisiblePart.Orientation = Vector3.new(0,180,0)


--4). Make the character archivable so you can clone certain instances.
--store all cloned parts into a new model, and add the model into viewportframe

local clonedModel
function addCharacter()
    character.Archivable=true
    local bodyParts = character:GetChildren()
    clonedModel = Instance.new("Model")

    for i = 1, #bodyParts do
    	local b = bodyParts[i]
    	if(b:IsA("Humanoid") 
        or b:IsA("Accessory")
    	or b:IsA("MeshPart") or b:IsA("BasePart") 
    	or b:IsA("Pants") or b:IsA("Shirt") or b:IsA("ShirtGraphic")
    	or b:IsA("BodyColors"))then
    				
    	    newTable[b.Name]=b.Name

           if(b.Archivable == false)then
    	        b.Archivable = true
    		    local clone = b:Clone()
    		    clone.Parent = clonedModel
    		    b.Archivable = false
    	   else
    	       local clone = b:Clone()
    	       clone.Parent = clonedModel
    	   end
    			
           if(b:IsA("Humanoid"))then
    	       b.DisplayDistanceType = Enum.HumanoidDisplayDistanceType.None
    	       b.HealthDisplayType = Enum.HumanoidHealthDisplayType.AlwaysOff
    	   end
       end
   end
    	
   clonedModel.Parent = viewport
   local ore = invisiblePart.Orientation
   invisiblePart.CFrame = clonedModel.HumanoidRootPart.CFrame

   --just incase you decide to apply character updates
   invisiblePart.Orientation=ore
end
    
function removeCharacter()
    if(clonedModel) then
        clonedModel:Destroy()
    end
end

--5).add the character to viewport frame and Use RenderStepped for camera & part updates
addCharacter()
game:GetService("RunService").RenderStepped:Connect(function()
    --makes the camera orbit around the character model.
    invisiblePart.CFrame = invisiblePart.CFrame * CFrame.Angles(0,math.rad(0.5),0)
    camera.CFrame = invisiblePart.CFrame + invisiblePart.CFrame.lookVector * zoom
end)

hopefully this helps some people, if you find any bugs or have any improvements then please notify me here, enjoy!

31 Likes

This looks nice, now only if I could find a way to let the mouse drag around the character to view it as if you were previewing a 3D avatar on the website.

Rotate camera using mouse

you can use UserInputService.InputChanged event along with MouseMovement InputType to 
get MouseDeltaX and MouseDeltaY

use the delta values to simply rotate the "invisible part" 
(this will orbit the camera using your mouse)
3 Likes

nice, so awhile ago they decided to let Viewport Frames use WorldModel.

I DEFINITELY do not recommend refreshing the viewport children for animations now (which wasn’t recommended in the first place), just use a WorldModel instead, it should support humanoids, joints and animations etc.

8 Likes