For some background, I have a guitar customizer in the PlayerGUI. The player can customize all the guitar’s parts and preview the guitar in a ViewportFrame. The player clicks a submit button which is supposed to bring the ViewportFrame’s model “to life.”
I am trying to clone the model from the ViewportFrame to the Workspace, using RemoteEvents located in ReplicatedStorage.
The reason why I am trying to do it this way is it is much easier.
Client-sided script, cropped:
button.Activated:Connect(function()
game.ReplicatedStorage.changeInstrument:FireServer(game.Players.LocalPlayer.PlayerGui.Instruments.Customizer.Viewer.ViewportFrame:FindFirstChildOfClass("Model"))
-- This passes through the model inside the ViewportFrame as a parameter of FireServer()
end)
Server-sided function, cropped:
game.ReplicatedStorage.changeInstrument.OnServerEvent:Connect(function(player, model)
if seat.Occupant and seat.Occupant.Name ~= "LeadBot" then
if player == game.Players:GetPlayerFromCharacter(seat.Occupant.Parent) then
play:Destroy()
play = model:Clone()
play.Parent = instruments
makeWelds()
end
end
end)
With the various combinations of parenting or cloning, nothing seems to work. Either the model doesn’t update in-game, or it does but only client-side.
Any help is appreciated.
First, serialize the model’s parts and properties into a table on the client side.
local function serializeModel(model)
local partsData = {}
for _, part in ipairs(model:GetDescendants()) do
if part:IsA("BasePart") then
table.insert(partsData, {
ClassName = part.ClassName,
Name = part.Name,
Position = part.Position,
Orientation = part.Orientation,
Color = part.Color,
Material = part.Material,
Size = part.Size,
-- Add any other properties you need here
})
end
end
return partsData
end
button.Activated:Connect(function()
local model = game.Players.LocalPlayer.PlayerGui.Instruments.Customizer.Viewer.ViewportFrame:FindFirstChildOfClass("Model")
if model then
local modelData = serializeModel(model)
game.ReplicatedStorage.changeInstrument:FireServer(modelData)
end
end)
2. Reconstruct the Model on the Server
On the server side, reconstruct the model from the serialized data.
local function reconstructModel(modelData)
local model = Instance.new("Model")
for _, partData in ipairs(modelData) do
local part = Instance.new(partData.ClassName)
part.Name = partData.Name
part.Position = partData.Position
part.Orientation = partData.Orientation
part.Color = partData.Color
part.Material = partData.Material
part.Size = partData.Size
-- Set any other properties you serialized
part.Parent = model
end
return model
end
game.ReplicatedStorage.changeInstrument.OnServerEvent:Connect(function(player, modelData)
if seat.Occupant and seat.Occupant.Name ~= "LeadBot" then
if player == game.Players:GetPlayerFromCharacter(seat.Occupant.Parent) then
if play then
play:Destroy()
end
play = reconstructModel(modelData)
play.Parent = instruments
makeWelds()
end
end
end)
In the server side script, you can simply do this to set the properties of the part.
local part = Instance.new(partData.ClassName)
partData.ClassName = nil -- removes `ClassName` from the dictionary `partData`
for property, value in partData do
part[property] = value
end
part.Parent = model