I am making a scrollable frame with all the friends of a specific user. I am using viewportframes with a humanoid model inside. The problem i’m having is that all the players look distorted / weird.
local players = game:GetService("Players")
players.PlayerAdded:Connect(function(plr)
local success, errormessage = pcall(function()
friends = {}
local friendsList = players:GetFriendsAsync(plr.UserId)
repeat
local page = friendsList:GetCurrentPage()
for _, friend in ipairs(page) do
table.insert(friends, {Username = friend.Username, UserId = friend.Id})
end
until friendsList.IsFinished or not pcall(function() friendsList:AdvanceToNextPageAsync() end)
print(friends)
end)
if not success then
warn("Error fetching friends list:", errormessage)
end
local startergui = game.Players:FindFirstChild(tostring(plr)).PlayerGui
print(startergui)
for i in pairs(friends) do
local userid = friends[i].UserId
local username = friends[i].Username
local viewport = Instance.new("ViewportFrame")
viewport.Name = tostring(i)
local model = players:CreateHumanoidModelFromUserId(userid)
model.Parent = game.Workspace.Models
viewport.Size = UDim2.new(0, 250, 0, 250)
viewport.BackgroundTransparency = 1
viewport.Parent = startergui.FriendList.ScrollingFrame
local camera = Instance.new("Camera")
camera.Parent = viewport
viewport.CurrentCamera = camera
model.Parent = viewport
model:SetPrimaryPartCFrame(CFrame.new(Vector3.new(0, 0, 0)))
camera.CFrame = CFrame.new(Vector3.new(0, 2, 5), Vector3.new(0, 2, 0))
end
end)
I have tried changing the camera position, aiming it at the primaryrootpart but nothing made it work for all characters.
for anyone with the same future problem here is the ai’s code:
local players = game:GetService("Players")
players.PlayerAdded:Connect(function(plr)
local success, errormessage = pcall(function()
friends = {}
local friendsList = players:GetFriendsAsync(plr.UserId)
repeat
local page = friendsList:GetCurrentPage()
for _, friend in ipairs(page) do
table.insert(friends, {Username = friend.Username, UserId = friend.Id})
end
until friendsList.IsFinished or not pcall(function() friendsList:AdvanceToNextPageAsync() end)
print(friends)
end)
if not success then
warn("Error fetching friends list:", errormessage)
end
local startergui = plr:FindFirstChild("PlayerGui")
if not startergui then
startergui = plr:WaitForChild("PlayerGui")
end
print(startergui)
for i in pairs(friends) do
local userid = friends[i].UserId
local username = friends[i].Username
local viewport = Instance.new("ViewportFrame")
viewport.Name = tostring(i)
local model = players:CreateHumanoidModelFromUserId(userid)
-- Prepare WorldModel for consistent setup (like stolen script)
local worldModel = Instance.new("WorldModel")
worldModel.Parent = viewport
model.Parent = worldModel
-- Character Display setup (stolen code part)
local VPFcam = Instance.new("Camera")
VPFcam.Parent = viewport
VPFcam.CFrame = CFrame.new(0,0,0)
viewport.CurrentCamera = VPFcam
model:SetPrimaryPartCFrame(CFrame.new(Vector3.new(0,0,-9.5),Vector3.new(0,0,0))) -- Position inside WorldModel
viewport.Size = UDim2.new(0, 250, 0, 250)
viewport.BackgroundTransparency = 1
viewport.Parent = startergui.FriendList.ScrollingFrame -- Assuming FriendList and ScrollingFrame exist
VPFcam.CFrame = CFrame.new(Vector3.new(0, 2, 5), Vector3.new(0, 2, 0)) -- Camera setup adjusted for WorldModel
-- Turning Feature (stolen code integration - local variables for each viewport)
local MouseInDisplay = false
local HoldInDisplay = false
local currentX = nil
local ClonedChar = model -- No need to clone again, we are already using CreateHumanoidModelFromUserId which creates a new model
viewport.MouseEnter:Connect(function() MouseInDisplay = true end)
viewport.MouseLeave:Connect(function() MouseInDisplay = false end)
viewport.MouseMoved:Connect(function(X,Y)
if HoldInDisplay == false then return end
if currentX then ClonedChar.PrimaryPart.CFrame *= CFrame.fromEulerAnglesXYZ(0,((X-currentX)*.025),0) end
currentX = X
end)
local uis = game:GetService("UserInputService") -- Get UIS inside PlayerAdded scope to be safe, though should work outside as well.
uis.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
if MouseInDisplay == true then
HoldInDisplay = true
currentX = nil
end
end
end)
uis.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
HoldInDisplay = false
end
end)
end
end)