
KeylessUniversal

local Players = game:GetService("Players")
local HttpService = game:GetService("HttpService")
local StarterGui = game:GetService("StarterGui")
local player = Players.LocalPlayer
-- ===== CRÉATION DE L'UI =====
local gui = Instance.new("ScreenGui")
gui.Name = "MapExporterUI"
gui.ResetOnSpawn = false
gui.Parent = player:WaitForChild("PlayerGui")
local frame = Instance.new("Frame")
frame.Parent = gui
frame.Size = UDim2.fromScale(0.7, 0.75)
frame.Position = UDim2.fromScale(0.15, 0.125)
frame.BackgroundColor3 = Color3.fromRGB(30, 30, 30)
local corner = Instance.new("UICorner")
corner.CornerRadius = UDim.new(0, 16)
corner.Parent = frame
local title = Instance.new("TextLabel")
title.Parent = frame
title.Size = UDim2.fromScale(1, 0.07)
title.Text = "Map & GUI Exporter / Importer + Position Saver"
title.TextScaled = true
title.TextColor3 = Color3.new(1,1,1)
title.BackgroundTransparency = 1
local statusLabel = Instance.new("TextLabel")
statusLabel.Parent = frame
statusLabel.Size = UDim2.fromScale(0.95, 0.07)
statusLabel.Position = UDim2.fromScale(0.025, 0.08)
statusLabel.Text = "Prêt - Cliquez sur Exporter pour commencer"
statusLabel.TextScaled = true
statusLabel.TextColor3 = Color3.fromRGB(100, 255, 100)
statusLabel.BackgroundColor3 = Color3.fromRGB(20, 20, 20)
statusLabel.TextWrapped = true
local box = Instance.new("TextBox")
box.Parent = frame
box.Name = "DataBox"
box.Size = UDim2.fromScale(0.95, 0.5)
box.Position = UDim2.fromScale(0.025, 0.16)
box.ClearTextOnFocus = false
box.MultiLine = true
box.TextWrapped = true
box.TextYAlignment = Enum.TextYAlignment.Top
box.TextXAlignment = Enum.TextXAlignment.Left
box.TextSize = 12
box.Text = ""
box.BackgroundColor3 = Color3.fromRGB(20,20,20)
box.TextColor3 = Color3.new(1,1,1)
box.Font = Enum.Font.Code
local boxCorner = Instance.new("UICorner")
boxCorner.CornerRadius = UDim.new(0, 8)
boxCorner.Parent = box
local exportBtn = Instance.new("TextButton")
exportBtn.Parent = frame
exportBtn.Text = "📤 EXPORTER MAP"
exportBtn.Size = UDim2.fromScale(0.3, 0.065)
exportBtn.Position = UDim2.fromScale(0.025, 0.68)
exportBtn.BackgroundColor3 = Color3.fromRGB(50,150,50)
exportBtn.TextColor3 = Color3.new(1,1,1)
exportBtn.TextScaled = true
exportBtn.Font = Enum.Font.GothamBold
local selectBtn = Instance.new("TextButton")
selectBtn.Parent = frame
selectBtn.Text = "📋 TOUT SÉLECT"
selectBtn.Size = UDim2.fromScale(0.3, 0.065)
selectBtn.Position = UDim2.fromScale(0.35, 0.68)
selectBtn.BackgroundColor3 = Color3.fromRGB(50,100,200)
selectBtn.TextColor3 = Color3.new(1,1,1)
selectBtn.TextScaled = true
selectBtn.Font = Enum.Font.GothamBold
local importBtn = Instance.new("TextButton")
importBtn.Parent = frame
importBtn.Text = "📥 IMPORTER MAP"
importBtn.Size = UDim2.fromScale(0.3, 0.065)
importBtn.Position = UDim2.fromScale(0.675, 0.68)
importBtn.BackgroundColor3 = Color3.fromRGB(200,100,50)
importBtn.TextColor3 = Color3.new(1,1,1)
importBtn.TextScaled = true
importBtn.Font = Enum.Font.GothamBold
-- Nouveaux boutons pour positions
local savePoBtn = Instance.new("TextButton")
savePoBtn.Parent = frame
savePoBtn.Text = "💾 SAVE POSITIONS"
savePoBtn.Size = UDim2.fromScale(0.3, 0.065)
savePoBtn.Position = UDim2.fromScale(0.025, 0.76)
savePoBtn.BackgroundColor3 = Color3.fromRGB(100,150,200)
savePoBtn.TextColor3 = Color3.new(1,1,1)
savePoBtn.TextScaled = true
savePoBtn.Font = Enum.Font.GothamBold
local loadPoBtn = Instance.new("TextButton")
loadPoBtn.Parent = frame
loadPoBtn.Text = "📍 LOAD POSITIONS"
loadPoBtn.Size = UDim2.fromScale(0.3, 0.065)
loadPoBtn.Position = UDim2.fromScale(0.35, 0.76)
loadPoBtn.BackgroundColor3 = Color3.fromRGB(150,100,200)
loadPoBtn.TextColor3 = Color3.new(1,1,1)
loadPoBtn.TextScaled = true
loadPoBtn.Font = Enum.Font.GothamBold
local clearBtn = Instance.new("TextButton")
clearBtn.Parent = frame
clearBtn.Text = "🗑️ EFFACER"
clearBtn.Size = UDim2.fromScale(0.3, 0.065)
clearBtn.Position = UDim2.fromScale(0.675, 0.76)
clearBtn.BackgroundColor3 = Color3.fromRGB(150,50,50)
clearBtn.TextColor3 = Color3.new(1,1,1)
clearBtn.TextScaled = true
clearBtn.Font = Enum.Font.Gotham
local closeBtn = Instance.new("TextButton")
closeBtn.Parent = frame
closeBtn.Text = "❌ FERMER"
closeBtn.Size = UDim2.fromScale(0.95, 0.06)
closeBtn.Position = UDim2.fromScale(0.025, 0.84)
closeBtn.BackgroundColor3 = Color3.fromRGB(80,80,80)
closeBtn.TextColor3 = Color3.new(1,1,1)
closeBtn.TextScaled = true
closeBtn.Font = Enum.Font.Gotham
local infoLabel = Instance.new("TextLabel")
infoLabel.Parent = frame
infoLabel.Size = UDim2.fromScale(0.95, 0.04)
infoLabel.Position = UDim2.fromScale(0.025, 0.91)
infoLabel.Text = "💡 Save Positions = Sauvegarde uniquement les positions | Load = Restaure les positions"
infoLabel.TextSize = 10
infoLabel.TextColor3 = Color3.fromRGB(200, 200, 100)
infoLabel.BackgroundTransparency = 1
infoLabel.TextWrapped = true
infoLabel.Font = Enum.Font.Gotham
-- ===== PROPRIÉTÉS À SAUVEGARDER =====
local PROPERTIES_TO_SAVE = {
BasePart = {
"Size", "Position", "Orientation", "Color", "Material",
"Transparency", "Reflectance", "CanCollide", "Anchored",
"CastShadow", "TopSurface", "BottomSurface", "LeftSurface",
"RightSurface", "FrontSurface", "BackSurface"
},
GuiObject = {
"Size", "Position", "BackgroundColor3", "BackgroundTransparency",
"BorderColor3", "BorderSizePixel", "Rotation", "Visible",
"ZIndex", "AnchorPoint"
},
TextLabel = {
"Text", "TextColor3", "TextSize", "TextScaled", "TextWrapped",
"TextXAlignment", "TextYAlignment", "Font"
},
TextButton = {
"Text", "TextColor3", "TextSize", "TextScaled", "Font", "AutoButtonColor"
},
TextBox = {
"Text", "TextColor3", "TextSize", "PlaceholderText", "ClearTextOnFocus",
"MultiLine", "TextEditable"
},
ImageLabel = {
"Image", "ImageColor3", "ImageTransparency", "ScaleType"
},
ImageButton = {
"Image", "ImageColor3", "ImageTransparency"
},
Frame = {},
ScreenGui = {
"ResetOnSpawn", "DisplayOrder", "Enabled"
}
}
-- ===== SÉRIALISATION =====
local function serializeValue(value)
local t = typeof(value)
if t == "Vector3" then
return {value.X, value.Y, value.Z}
elseif t == "Vector2" then
return {value.X, value.Y}
elseif t == "Color3" then
return {value.R, value.G, value.B}
elseif t == "UDim2" then
return {value.X.Scale, value.X.Offset, value.Y.Scale, value.Y.Offset}
elseif t == "EnumItem" then
return tostring(value)
end
return value
end
local function serialize(obj, parentId, data, ignoreList)
ignoreList = ignoreList or {}
if obj:IsA("Terrain") or ignoreList[obj] then
return
end
local objData = {
ClassName = obj.ClassName,
Name = obj.Name,
Parent = parentId,
Properties = {}
}
for className, props in pairs(PROPERTIES_TO_SAVE) do
if obj:IsA(className) then
for _, propName in ipairs(props) do
local success, value = pcall(function()
return obj[propName]
end)
if success then
objData.Properties[propName] = serializeValue(value)
end
end
end
end
table.insert(data, objData)
local myId = #data
for _, child in ipairs(obj:GetChildren()) do
serialize(child, myId, data, ignoreList)
end
end
-- ===== SAUVEGARDE POSITIONS =====
local function getFullPath(obj)
local path = {}
local current = obj
while current and current ~= workspace and current ~= game do
table.insert(path, 1, current.Name)
current = current.Parent
end
return table.concat(path, ".")
end
local function savePositions(parent, positions)
for _, obj in ipairs(parent:GetChildren()) do
if obj:IsA("BasePart") then
local path = getFullPath(obj)
positions[path] = {
Position = {obj.Position.X, obj.Position.Y, obj.Position.Z},
Orientation = {obj.Orientation.X, obj.Orientation.Y, obj.Orientation.Z},
CFrame = {obj.CFrame:GetComponents()}
}
end
if obj:IsA("Model") or obj:IsA("Folder") then
savePositions(obj, positions)
end
end
end
savePoBtn.MouseButton1Click:Connect(function()
statusLabel.Text = "⏳ Sauvegarde des positions en cours..."
statusLabel.TextColor3 = Color3.fromRGB(255, 200, 100)
wait()
local positions = {}
savePositions(workspace, positions)
local jsonData = HttpService:JSONEncode(positions)
box.Text = jsonData
statusLabel.Text = "✅ Positions sauvegardées ! " .. #positions .. " parts | Cliquez TOUT SÉLECT puis Ctrl+C"
statusLabel.TextColor3 = Color3.fromRGB(100, 255, 100)
print("✅ Positions sauvegardées:", #jsonData, "caractères")
end)
-- ===== CHARGEMENT POSITIONS =====
local function findByPath(parent, path)
local parts = {}
for part in path:gmatch("[^.]+") do
table.insert(parts, part)
end
local current = parent
for _, name in ipairs(parts) do
local found = current:FindFirstChild(name)
if not found then
return nil
end
current = found
end
return current
end
loadPoBtn.MouseButton1Click:Connect(function()
if box.Text == "" then
statusLabel.Text = "❌ Collez d'abord les données de positions (Ctrl+V)"
statusLabel.TextColor3 = Color3.fromRGB(255, 100, 100)
return
end
statusLabel.Text = "⏳ Restauration des positions..."
statusLabel.TextColor3 = Color3.fromRGB(255, 200, 100)
wait()
local success, positions = pcall(function()
return HttpService:JSONDecode(box.Text)
end)
if not success then
statusLabel.Text = "❌ Données invalides"
statusLabel.TextColor3 = Color3.fromRGB(255, 100, 100)
return
end
local restored = 0
local notFound = 0
for path, data in pairs(positions) do
local obj = findByPath(workspace, path)
if obj and obj:IsA("BasePart") then
pcall(function()
if data.CFrame then
obj.CFrame = CFrame.new(unpack(data.CFrame))
else
obj.Position = Vector3.new(unpack(data.Position))
obj.Orientation = Vector3.new(unpack(data.Orientation))
end
restored = restored + 1
end)
else
notFound = notFound + 1
end
end
statusLabel.Text = "✅ Positions restaurées ! " .. restored .. " parts | " .. notFound .. " non trouvées"
statusLabel.TextColor3 = Color3.fromRGB(100, 255, 100)
print("✅ Restauration:", restored, "parts,", notFound, "non trouvées")
end)
-- ===== EXPORT MAP =====
exportBtn.MouseButton1Click:Connect(function()
statusLabel.Text = "⏳ Export en cours..."
statusLabel.TextColor3 = Color3.fromRGB(255, 200, 100)
box.Text = "Génération des données..."
wait()
local exportData = {
Workspace = {},
StarterGui = {}
}
local ignoreList = {
[workspace.Terrain] = true,
[gui] = true
}
serialize(workspace, 0, exportData.Workspace, ignoreList)
for _, child in ipairs(StarterGui:GetChildren()) do
serialize(child, 0, exportData.StarterGui, {})
end
local jsonData = HttpService:JSONEncode(exportData)
if #jsonData > 190000 then
local chunkSize = 190000
local chunks = {}
for i = 1, #jsonData, chunkSize do
table.insert(chunks, jsonData:sub(i, i + chunkSize - 1))
end
box.Text = chunks[1]
statusLabel.Text = "⚠️ Données trop grandes ! Partie 1/" .. #chunks
statusLabel.TextColor3 = Color3.fromRGB(255, 150, 50)
print("DONNÉES COMPLÈTES:")
print(jsonData)
else
box.Text = jsonData
statusLabel.Text = "✅ Export terminé ! " .. #exportData.Workspace .. " objets"
statusLabel.TextColor3 = Color3.fromRGB(100, 255, 100)
end
end)
-- ===== TOUT SÉLECTIONNER =====
selectBtn.MouseButton1Click:Connect(function()
box:CaptureFocus()
box.CursorPosition = 1
box.SelectionStart = 1
task.wait(0.1)
box.CursorPosition = #box.Text + 1
statusLabel.Text = "✅ Texte sélectionné ! Ctrl+C pour copier"
statusLabel.TextColor3 = Color3.fromRGB(100, 200, 255)
end)
-- ===== EFFACER =====
clearBtn.MouseButton1Click:Connect(function()
box.Text = ""
statusLabel.Text = "🗑️ Zone effacée"
statusLabel.TextColor3 = Color3.fromRGB(150, 150, 150)
end)
-- ===== FERMER =====
closeBtn.MouseButton1Click:Connect(function()
gui:Destroy()
end)
-- ===== DÉSÉRIALISATION =====
local function deserializeValue(value, propType)
if type(value) == "table" then
if #value == 3 and (propType == "Vector3" or propType == "Color3") then
if propType == "Color3" then
return Color3.new(value[1], value[2], value[3])
end
return Vector3.new(value[1], value[2], value[3])
elseif #value == 2 then
return Vector2.new(value[1], value[2])
elseif #value == 4 then
return UDim2.new(value[1], value[2], value[3], value[4])
end
end
return value
end
local function applyProperties(obj, props)
for propName, value in pairs(props) do
pcall(function()
local propType = typeof(obj[propName])
obj[propName] = deserializeValue(value, propType)
end)
end
end
-- ===== IMPORT MAP =====
importBtn.MouseButton1Click:Connect(function()
if box.Text == "" then
statusLabel.Text = "❌ Collez les données (Ctrl+V) avant d'importer"
statusLabel.TextColor3 = Color3.fromRGB(255, 100, 100)
return
end
statusLabel.Text = "⏳ Import en cours..."
statusLabel.TextColor3 = Color3.fromRGB(255, 200, 100)
wait()
local success, importData = pcall(function()
return HttpService:JSONDecode(box.Text)
end)
if not success then
statusLabel.Text = "❌ Données invalides"
statusLabel.TextColor3 = Color3.fromRGB(255, 100, 100)
return
end
if importData.StarterGui then
for _, guiData in ipairs(importData.StarterGui) do
local existing = StarterGui:FindFirstChild(guiData.Name)
if existing and existing.Name ~= "MapExporterUI" then
existing:Destroy()
end
end
end
local wsCount = 0
if importData.Workspace then
local created = {[0] = workspace}
for i, objData in ipairs(importData.Workspace) do
pcall(function()
local newObj = Instance.new(objData.ClassName)
newObj.Name = objData.Name
applyProperties(newObj, objData.Properties)
newObj.Parent = created[objData.Parent] or workspace
created[i] = newObj
wsCount = wsCount + 1
end)
end
end
local guiCount = 0
if importData.StarterGui then
local created = {[0] = StarterGui}
for i, objData in ipairs(importData.StarterGui) do
if objData.Name ~= "MapExporterUI" then
pcall(function()
local newObj = Instance.new(objData.ClassName)
newObj.Name = objData.Name
applyProperties(newObj, objData.Properties)
newObj.Parent = created[objData.Parent] or StarterGui
created[i] = newObj
guiCount = guiCount + 1
end)
end
end
end
statusLabel.Text = "✅ Import réussi ! " .. wsCount .. " objets, " .. guiCount .. " GUIs"
statusLabel.TextColor3 = Color3.fromRGB(100, 255, 100)
end)No comments yet for this script.



