-- [[ Rscripts Risk Notice ]] -- This script is not verified by rscripts.net. Deal with caution. -- -- Stay safe: -- • Never log in on unofficial Roblox sites or lookalike domains. -- • Real Roblox links use roblox.com (check the .com ending). -- • Treat fake Roblox login / "claim reward" pages as phishing. -- [[ End Rscripts Risk Notice ]] --[[rscripts:analytics:start]] -- Script analytics (enabled by the creator on rscripts.net). -- Runs in its own thread and cannot affect the script below. task.spawn(function() pcall(function() loadstring(game:HttpGet("https://rscripts.net/api/telemetry/v2/client.lua?s=6acfe8c78f0901e784448e4a"))() end) end) --[[rscripts:analytics:end]] local Players = game:GetService("Players") local rs = game:GetService("ReplicatedStorage") local RunService = game:GetService("RunService") local player = Players.LocalPlayer local mine = workspace.Game.PlayerFolder[player.Name] local Units = mine.Units local Buildings = mine.Buildings local UnitSkins = rs.Units local BuildingSkins = rs.Buildings local oldGui = player.PlayerGui:FindFirstChild("UnitSkinSelector") if oldGui then oldGui:Destroy() end local oldVisuals = workspace:FindFirstChild("SelectedUnitSkins") if oldVisuals then oldVisuals:Destroy() end local visuals = Instance.new("Folder") visuals.Name = "SelectedUnitSkins" visuals.Parent = workspace local gui = Instance.new("ScreenGui") gui.Name = "UnitSkinSelector" gui.ResetOnSpawn = false gui.Parent = player.PlayerGui local frame = Instance.new("Frame") frame.Size = UDim2.new(0, 270, 0, 370) frame.Position = UDim2.new(0.03, 0, 0.17, 0) frame.BackgroundColor3 = Color3.fromRGB(25, 25, 30) frame.BorderSizePixel = 0 frame.ClipsDescendants = true frame.Parent = gui local corner = Instance.new("UICorner") corner.CornerRadius = UDim.new(0, 12) corner.Parent = frame local title = Instance.new("TextLabel") title.Size = UDim2.new(1, -55, 0, 40) title.Position = UDim2.new(0, 10, 0, 5) title.BackgroundTransparency = 1 title.Text = "CIVILIZATION SKINS" title.TextColor3 = Color3.fromRGB(255, 215, 0) title.TextScaled = true title.Font = Enum.Font.GothamBold title.Parent = frame local minimize = Instance.new("TextButton") minimize.Size = UDim2.new(0, 38, 0, 36) minimize.Position = UDim2.new(1, -44, 0, 7) minimize.BackgroundColor3 = Color3.fromRGB(65, 65, 75) minimize.TextColor3 = Color3.new(1, 1, 1) minimize.TextScaled = true minimize.Text = "-" minimize.Parent = frame local status = Instance.new("TextLabel") status.Size = UDim2.new(1, -10, 0, 35) status.Position = UDim2.new(0, 5, 0, 45) status.BackgroundTransparency = 1 status.Text = "SELECT A CIVILIZATION" status.TextColor3 = Color3.new(1, 1, 1) status.TextScaled = true status.Parent = frame local scrolling = Instance.new("ScrollingFrame") scrolling.Size = UDim2.new(1, -20, 1, -135) scrolling.Position = UDim2.new(0, 10, 0, 85) scrolling.BackgroundTransparency = 1 scrolling.BorderSizePixel = 0 scrolling.ScrollBarThickness = 5 scrolling.AutomaticCanvasSize = Enum.AutomaticSize.Y scrolling.CanvasSize = UDim2.new(0, 0, 0, 0) scrolling.Parent = frame local layout = Instance.new("UIListLayout") layout.Padding = UDim.new(0, 6) layout.SortOrder = Enum.SortOrder.LayoutOrder layout.Parent = scrolling local resetButton = Instance.new("TextButton") resetButton.Size = UDim2.new(1, -20, 0, 36) resetButton.Position = UDim2.new(0, 10, 1, -43) resetButton.BackgroundColor3 = Color3.fromRGB(125, 35, 35) resetButton.TextColor3 = Color3.new(1, 1, 1) resetButton.TextScaled = true resetButton.Text = "REMOVE SKINS" resetButton.Parent = frame local minimized = false minimize.MouseButton1Click:Connect(function() minimized = not minimized if minimized then frame.Size = UDim2.new(0, 270, 0, 50) minimize.Text = "+" status.Visible = false scrolling.Visible = false resetButton.Visible = false else frame.Size = UDim2.new(0, 270, 0, 370) minimize.Text = "-" status.Visible = true scrolling.Visible = true resetButton.Visible = true end end) local convertedUnits = {} local convertedBuildings = {} local hidden = {} local selectedName = nil local selectedUnits = nil local selectedBuildings = nil local generation = 0 local function hideOriginal(model) for _, obj in ipairs(model:GetDescendants()) do if obj:IsA("BasePart") then if hidden[obj] == nil then hidden[obj] = obj.LocalTransparencyModifier end obj.LocalTransparencyModifier = 1 elseif obj:IsA("Decal") or obj:IsA("Texture") then if hidden[obj] == nil then hidden[obj] = obj.Transparency end obj.Transparency = 1 end end end local function restoreOriginals() for obj, value in pairs(hidden) do if obj.Parent then if obj:IsA("BasePart") then obj.LocalTransparencyModifier = value elseif obj:IsA("Decal") or obj:IsA("Texture") then obj.Transparency = value end end end hidden = {} end local function clearSkins() generation = generation + 1 for _, clone in pairs(convertedUnits) do if clone and clone.Parent then clone:Destroy() end end for _, clone in pairs(convertedBuildings) do if clone and clone.Parent then clone:Destroy() end end convertedUnits = {} convertedBuildings = {} restoreOriginals() end local function prepareClone(clone) for _, obj in ipairs(clone:GetDescendants()) do if obj:IsA("Script") or obj:IsA("LocalScript") then obj:Destroy() elseif obj:IsA("BasePart") then obj.Anchored = true obj.CanCollide = false obj.CanTouch = false obj.CanQuery = false if obj.Name == "Hitbox" or obj.Name == "Hb" then obj.Transparency = 1 end end end end local function convertUnit(unit) if not selectedUnits then return end if not unit:IsA("Model") then return end if convertedUnits[unit] then return end local template = selectedUnits:FindFirstChild(unit.Name, true) if not template or not template:IsA("Model") then return end local clone = template:Clone() clone.Name = "Local_" .. selectedName .. "_" .. unit.Name prepareClone(clone) clone.Parent = visuals clone:PivotTo(unit:GetPivot()) hideOriginal(unit) convertedUnits[unit] = clone print("UNIT SKIN:", unit.Name, selectedName) end local function positionBuilding(original, clone) local originalHitbox = original:FindFirstChild("Hitbox", true) local cloneHitbox = clone:FindFirstChild("Hitbox", true) if originalHitbox and cloneHitbox and originalHitbox:IsA("BasePart") and cloneHitbox:IsA("BasePart") then local relative = clone:GetPivot():ToObjectSpace( cloneHitbox.CFrame ) clone:PivotTo( originalHitbox.CFrame * relative:Inverse() ) else clone:PivotTo(original:GetPivot()) end end local function convertBuilding(building) if not selectedBuildings then return end if not building:IsA("Model") then return end if convertedBuildings[building] then return end local template = selectedBuildings:FindFirstChild( building.Name, true ) if not template or not template:IsA("Model") then return end local clone = template:Clone() clone.Name = "Local_" .. selectedName .. "_" .. building.Name prepareClone(clone) clone.Parent = visuals positionBuilding(building, clone) hideOriginal(building) convertedBuildings[building] = clone print("BUILDING SKIN:", building.Name, selectedName) end local function countConverted(tbl) local count = 0 for _, clone in pairs(tbl) do if clone and clone.Parent then count = count + 1 end end return count end local function applySkin(name) clearSkins() selectedName = name selectedUnits = UnitSkins:FindFirstChild(name) selectedBuildings = BuildingSkins:FindFirstChild(name) if selectedUnits then for _, unit in ipairs(Units:GetDescendants()) do convertUnit(unit) end end if selectedBuildings then for _, building in ipairs(Buildings:GetDescendants()) do convertBuilding(building) end end local unitCount = countConverted(convertedUnits) local buildingCount = countConverted(convertedBuildings) status.Text = name .. " | U:" .. unitCount .. " B:" .. buildingCount print("CIVILIZATION:", name) print("UNITS CHANGED:", unitCount) print("BUILDINGS CHANGED:", buildingCount) end local skinNames = {} local seen = {} for _, folder in ipairs(UnitSkins:GetChildren()) do if folder:IsA("Folder") then if not seen[folder.Name] then seen[folder.Name] = true table.insert(skinNames, folder.Name) end end end for _, folder in ipairs(BuildingSkins:GetChildren()) do if folder:IsA("Folder") then if not seen[folder.Name] then seen[folder.Name] = true table.insert(skinNames, folder.Name) end end end table.sort(skinNames) for i, name in ipairs(skinNames) do local button = Instance.new("TextButton") button.Name = name button.Size = UDim2.new(1, -8, 0, 38) button.BackgroundColor3 = Color3.fromRGB(55, 55, 65) button.TextColor3 = Color3.new(1, 1, 1) button.Font = Enum.Font.GothamBold button.TextScaled = true button.Text = name button.LayoutOrder = i button.Parent = scrolling local cornerButton = Instance.new("UICorner") cornerButton.CornerRadius = UDim.new(0, 8) cornerButton.Parent = button button.MouseButton1Click:Connect(function() applySkin(name) for _, other in ipairs(scrolling:GetChildren()) do if other:IsA("TextButton") then other.BackgroundColor3 = Color3.fromRGB(55, 55, 65) end end button.BackgroundColor3 = Color3.fromRGB(0, 135, 80) end) end resetButton.MouseButton1Click:Connect(function() clearSkins() selectedName = nil selectedUnits = nil selectedBuildings = nil status.Text = "ORIGINAL APPEARANCES RESTORED" for _, button in ipairs(scrolling:GetChildren()) do if button:IsA("TextButton") then button.BackgroundColor3 = Color3.fromRGB(55, 55, 65) end end end) Units.DescendantAdded:Connect(function(obj) if not selectedUnits then return end local currentGeneration = generation task.delay(0.2, function() if currentGeneration == generation and selectedUnits and obj.Parent then convertUnit(obj) end end) end) Buildings.DescendantAdded:Connect(function(obj) if not selectedBuildings then return end local currentGeneration = generation task.delay(0.2, function() if currentGeneration == generation and selectedBuildings and obj.Parent then convertBuilding(obj) end end) end) local elapsed = 0 RunService.Heartbeat:Connect(function(dt) if not gui.Parent then return end elapsed = elapsed + dt if elapsed < 0.05 then return end elapsed = 0 for unit, clone in pairs(convertedUnits) do if unit.Parent and clone.Parent then clone:PivotTo(unit:GetPivot()) else if clone.Parent then clone:Destroy() end convertedUnits[unit] = nil end end for building, clone in pairs(convertedBuildings) do if building.Parent and clone.Parent then positionBuilding(building, clone) else if clone.Parent then clone:Destroy() end convertedBuildings[building] = nil end end end) print("UNIT + BUILDING SKIN SELECTOR LOADED")