NOT FE Texture Changer GUI
Key RequiredUniversal

NOT FE Texture Changer GUI

Universal Scriptddorredoreddorredore 1.1K views 428 executesUpdated Mar 27, 2026
Unrated
00
Lua Script•598 lines (15028 chars)
--// Texture Changer GUI
--// Put this LocalScript in StarterPlayerScripts or StarterGui
--// Local-only visual changer

local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")

local player = Players.LocalPlayer
local rng = Random.new()

--========================
-- EDIT HERE
--========================
local guiTitle = "Texture Changer"
local mainButtonText = "Apply"
local smallButtonText = "Open"

local defaultTextureId = ""      -- example: 5373446510 or rbxassetid://5373446510
local defaultColorText = ""       -- example: 255,0,0 or #FF0000
local defaultChaosPool = ""       -- comma-separated texture ids for chaos mode
local defaultMaterialName = "Plastic"
--========================

local materialList = {
	Enum.Material.Plastic,
	Enum.Material.SmoothPlastic,
	Enum.Material.Neon,
	Enum.Material.Wood,
	Enum.Material.WoodPlanks,
	Enum.Material.Glass,
	Enum.Material.Concrete,
	Enum.Material.Granite,
	Enum.Material.Slate,
	Enum.Material.Metal,
	Enum.Material.CorrodedMetal,
	Enum.Material.DiamondPlate,
	Enum.Material.Foil,
	Enum.Material.Ice,
	Enum.Material.Fabric,
	Enum.Material.Grass,
	Enum.Material.Pebble,
	Enum.Material.ForceField,
}

local materialIndex = 1
for i, mat in ipairs(materialList) do
	if mat.Name == defaultMaterialName then
		materialIndex = i
		break
	end
end

local chaosOn = false
local chaosToken = 0

local originalState = {} -- [part] = {Color=, Material=, Reflectance=, Transparency=, Extras={clones...}}

local faces = {
	Enum.NormalId.Front,
	Enum.NormalId.Back,
	Enum.NormalId.Left,
	Enum.NormalId.Right,
	Enum.NormalId.Top,
	Enum.NormalId.Bottom,
}

local function trimText(s)
	return (tostring(s or ""):gsub("^%s+", ""):gsub("%s+$", ""))
end

local function normalizeTextureId(text)
	text = trimText(text)
	if text == "" then
		return nil
	end

	local id = text:match("(%d+)")
	if not id then
		return nil
	end

	return "rbxassetid://" .. id
end

local function parseColor(text)
	text = trimText(text)
	if text == "" then
		return nil
	end

	if text:sub(1, 1) == "#" then
		text = text:sub(2)
	end

	if #text == 6 and text:match("^[%da-fA-F]+$") then
		local r = tonumber(text:sub(1, 2), 16)
		local g = tonumber(text:sub(3, 4), 16)
		local b = tonumber(text:sub(5, 6), 16)
		if r and g and b then
			return Color3.fromRGB(r, g, b)
		end
	end

	local nums = {}
	for n in text:gmatch("%d+") do
		nums[#nums + 1] = tonumber(n)
	end

	if #nums >= 3 then
		return Color3.fromRGB(
			math.clamp(nums[1], 0, 255),
			math.clamp(nums[2], 0, 255),
			math.clamp(nums[3], 0, 255)
		)
	end

	return nil
end

local function parseTexturePool(text)
	text = trimText(text)
	local pool = {}

	if text == "" then
		return pool
	end

	for token in text:gmatch("[^,%s;]+") do
		local id = normalizeTextureId(token)
		if id then
			pool[#pool + 1] = id
		end
	end

	return pool
end

local function getAllParts()
	local parts = {}
	for _, obj in ipairs(workspace:GetDescendants()) do
		if obj:IsA("BasePart") then
			parts[#parts + 1] = obj
		end
	end
	return parts
end

local function saveOriginal(part)
	if originalState[part] or not part or not part.Parent then
		return
	end

	local extras = {}

	for _, child in ipairs(part:GetChildren()) do
		if child:IsA("Texture") or child:IsA("Decal") or child:IsA("SurfaceAppearance") then
			extras[#extras + 1] = child:Clone()
			child:Destroy()
		end
	end

	originalState[part] = {
		Color = part.Color,
		Material = part.Material,
		Reflectance = part.Reflectance,
		Transparency = part.Transparency,
		Extras = extras,
	}
end

local function clearGeneratedTextures(part)
	for _, face in ipairs(faces) do
		local tex = part:FindFirstChild("TC_" .. face.Name)
		if tex and tex:IsA("Texture") then
			tex:Destroy()
		end
	end
end

local function applyTextureToPart(part, textureId)
	if not textureId or textureId == "" then
		clearGeneratedTextures(part)
		return
	end

	saveOriginal(part)
	clearGeneratedTextures(part)

	for _, face in ipairs(faces) do
		local tex = Instance.new("Texture")
		tex.Name = "TC_" .. face.Name
		tex.Face = face
		tex.Texture = textureId
		tex.StudsPerTileU = 1
		tex.StudsPerTileV = 1
		tex.Parent = part
	end
end

local function applyColorToPart(part, color3)
	if color3 then
		saveOriginal(part)
		part.Color = color3
	end
end

local function applyMaterialToPart(part, materialEnum)
	if materialEnum then
		saveOriginal(part)
		part.Material = materialEnum
	end
end

local function restorePart(part)
	if not (part and part.Parent and originalState[part]) then
		clearGeneratedTextures(part)
		return
	end

	local old = originalState[part]
	part.Color = old.Color
	part.Material = old.Material
	part.Reflectance = old.Reflectance
	part.Transparency = old.Transparency

	clearGeneratedTextures(part)

	for _, childClone in ipairs(old.Extras or {}) do
		childClone.Parent = part
	end

	originalState[part] = nil
end

local function restoreAll()
	chaosOn = false
	chaosToken += 1

	for part, _ in pairs(originalState) do
		restorePart(part)
	end
end

local function applyToAllParts(textureId, color3, materialEnum)
	for _, part in ipairs(getAllParts()) do
		if textureId then
			applyTextureToPart(part, textureId)
		else
			clearGeneratedTextures(part)
		end

		if color3 then
			applyColorToPart(part, color3)
		end

		if materialEnum then
			applyMaterialToPart(part, materialEnum)
		end
	end
end

-- GUI
local screenGui = Instance.new("ScreenGui")
screenGui.Name = "TextureChangerGui"
screenGui.ResetOnSpawn = false
screenGui.Parent = player:WaitForChild("PlayerGui")

local mainFrame = Instance.new("Frame")
mainFrame.Size = UDim2.new(0, 340, 0, 430)
mainFrame.Position = UDim2.new(0.5, -170, 0.5, -215)
mainFrame.BackgroundColor3 = Color3.fromRGB(25, 25, 25)
mainFrame.BorderSizePixel = 0
mainFrame.Active = true
mainFrame.ClipsDescendants = true
mainFrame.Parent = screenGui

local mainCorner = Instance.new("UICorner")
mainCorner.CornerRadius = UDim.new(0, 12)
mainCorner.Parent = mainFrame

local titleBar = Instance.new("TextLabel")
titleBar.Size = UDim2.new(1, 0, 0, 35)
titleBar.BackgroundColor3 = Color3.fromRGB(35, 35, 35)
titleBar.BorderSizePixel = 0
titleBar.Text = guiTitle
titleBar.TextColor3 = Color3.fromRGB(255, 255, 255)
titleBar.TextScaled = true
titleBar.Font = Enum.Font.GothamBold
titleBar.Active = true
titleBar.Parent = mainFrame

local titleCorner = Instance.new("UICorner")
titleCorner.CornerRadius = UDim.new(0, 12)
titleCorner.Parent = titleBar

local hideButton = Instance.new("TextButton")
hideButton.Size = UDim2.new(0, 60, 0, 25)
hideButton.Position = UDim2.new(1, -65, 0, 5)
hideButton.BackgroundColor3 = Color3.fromRGB(70, 70, 70)
hideButton.Text = "Hide"
hideButton.TextColor3 = Color3.fromRGB(255, 255, 255)
hideButton.TextScaled = true
hideButton.Font = Enum.Font.Gotham
hideButton.BorderSizePixel = 0
hideButton.Parent = mainFrame

local hideCorner = Instance.new("UICorner")
hideCorner.CornerRadius = UDim.new(0, 8)
hideCorner.Parent = hideButton

local closeButton = Instance.new("TextButton")
closeButton.Size = UDim2.new(0, 25, 0, 25)
closeButton.Position = UDim2.new(1, -30, 0, 5)
closeButton.BackgroundColor3 = Color3.fromRGB(170, 50, 50)
closeButton.Text = "X"
closeButton.TextColor3 = Color3.fromRGB(255, 255, 255)
closeButton.TextScaled = true
closeButton.Font = Enum.Font.GothamBold
closeButton.BorderSizePixel = 0
closeButton.Parent = mainFrame

local closeCorner = Instance.new("UICorner")
closeCorner.CornerRadius = UDim.new(0, 8)
closeCorner.Parent = closeButton

local scrollFrame = Instance.new("ScrollingFrame")
scrollFrame.Size = UDim2.new(1, 0, 1, -35)
scrollFrame.Position = UDim2.new(0, 0, 0, 35)
scrollFrame.BackgroundTransparency = 1
scrollFrame.BorderSizePixel = 0
scrollFrame.ScrollBarThickness = 5
scrollFrame.CanvasSize = UDim2.new(0, 0, 0, 0)
scrollFrame.Parent = mainFrame

local content = Instance.new("Frame")
content.Size = UDim2.new(1, -10, 0, 0)
content.Position = UDim2.new(0, 5, 0, 5)
content.BackgroundTransparency = 1
content.BorderSizePixel = 0
content.Parent = scrollFrame

local layout = Instance.new("UIListLayout")
layout.Padding = UDim.new(0, 6)
layout.SortOrder = Enum.SortOrder.LayoutOrder
layout.Parent = content

layout:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(function()
	content.Size = UDim2.new(1, -10, 0, layout.AbsoluteContentSize.Y)
	scrollFrame.CanvasSize = UDim2.new(0, 0, 0, layout.AbsoluteContentSize.Y + 10)
end)

local function roundify(obj, radius)
	local c = Instance.new("UICorner")
	c.CornerRadius = UDim.new(0, radius)
	c.Parent = obj
	return c
end

local function makeLabel(text, height)
	local lbl = Instance.new("TextLabel")
	lbl.Size = UDim2.new(1, 0, 0, height or 22)
	lbl.BackgroundTransparency = 1
	lbl.Text = text
	lbl.TextColor3 = Color3.fromRGB(255, 255, 255)
	lbl.TextScaled = true
	lbl.Font = Enum.Font.Gotham
	lbl.Parent = content
	return lbl
end

local function makeBox(labelText, defaultText)
	local row = Instance.new("Frame")
	row.Size = UDim2.new(1, 0, 0, 52)
	row.BackgroundColor3 = Color3.fromRGB(32, 32, 32)
	row.BorderSizePixel = 0
	row.Parent = content
	roundify(row, 10)

	local lbl = Instance.new("TextLabel")
	lbl.Size = UDim2.new(1, -12, 0, 18)
	lbl.Position = UDim2.new(0, 6, 0, 4)
	lbl.BackgroundTransparency = 1
	lbl.Text = labelText
	lbl.TextColor3 = Color3.fromRGB(255, 255, 255)
	lbl.TextScaled = true
	lbl.Font = Enum.Font.Gotham
	lbl.Parent = row

	local box = Instance.new("TextBox")
	box.Size = UDim2.new(1, -12, 0, 22)
	box.Position = UDim2.new(0, 6, 0, 26)
	box.BackgroundColor3 = Color3.fromRGB(45, 45, 45)
	box.Text = defaultText
	box.TextColor3 = Color3.fromRGB(255, 255, 255)
	box.TextScaled = true
	box.Font = Enum.Font.Gotham
	box.BorderSizePixel = 0
	box.ClearTextOnFocus = false
	box.Parent = row
	roundify(box, 8)

	return box
end

local function makeButton(text, color, height)
	local btn = Instance.new("TextButton")
	btn.Size = UDim2.new(1, 0, 0, height or 30)
	btn.BackgroundColor3 = color
	btn.Text = text
	btn.TextColor3 = Color3.fromRGB(255, 255, 255)
	btn.TextScaled = true
	btn.Font = Enum.Font.GothamBold
	btn.BorderSizePixel = 0
	btn.Parent = content
	roundify(btn, 10)
	return btn
end

makeLabel("Edit everything here", 22)

local textureBox = makeBox("Texture ID", defaultTextureId)
local colorBox = makeBox("Color (RGB or Hex)", defaultColorText)
local chaosPoolBox = makeBox("Chaos Texture Pool", defaultChaosPool)

local materialButton = makeButton("Material: " .. materialList[materialIndex].Name, Color3.fromRGB(80, 80, 140), 30)
local applyButton = makeButton(mainButtonText, Color3.fromRGB(50, 120, 50), 34)
local chaosButton = makeButton("CHAOS! : OFF", Color3.fromRGB(150, 90, 40), 34)
local returnButton = makeButton("Return", Color3.fromRGB(120, 60, 60), 34)

local statusLabel = makeLabel("Status: Ready", 24)

local smallButton = Instance.new("TextButton")
smallButton.Size = UDim2.new(0, 70, 0, 30)
smallButton.Position = UDim2.new(0, 10, 0.5, -15)
smallButton.BackgroundColor3 = Color3.fromRGB(35, 35, 35)
smallButton.Text = smallButtonText
smallButton.TextColor3 = Color3.fromRGB(255, 255, 255)
smallButton.TextScaled = true
smallButton.Font = Enum.Font.GothamBold
smallButton.BorderSizePixel = 0
smallButton.Visible = false
smallButton.Active = true
smallButton.Parent = screenGui
roundify(smallButton, 10)

local function updateStatus(text)
	statusLabel.Text = "Status: " .. text
end

local function refreshMaterialText()
	materialButton.Text = "Material: " .. materialList[materialIndex].Name
end

materialButton.MouseButton1Click:Connect(function()
	materialIndex += 1
	if materialIndex > #materialList then
		materialIndex = 1
	end
	refreshMaterialText()
	updateStatus("Material selected: " .. materialList[materialIndex].Name)
end)

applyButton.MouseButton1Click:Connect(function()
	local textureId = normalizeTextureId(textureBox.Text)
	local color3 = parseColor(colorBox.Text)
	local materialEnum = materialList[materialIndex]

	applyToAllParts(textureId, color3, materialEnum)

	if textureId or color3 or materialEnum then
		updateStatus("Applied to all parts")
	else
		updateStatus("Nothing to apply")
	end
end)

returnButton.MouseButton1Click:Connect(function()
	restoreAll()
	updateStatus("Restored to normal")
end)

chaosButton.MouseButton1Click:Connect(function()
	chaosOn = not chaosOn
	chaosToken += 1
	local myToken = chaosToken

	if chaosOn then
		chaosButton.Text = "CHAOS! : ON"
		chaosButton.BackgroundColor3 = Color3.fromRGB(170, 60, 60)
		updateStatus("Chaos running")

		task.spawn(function()
			while chaosOn and chaosToken == myToken and screenGui.Parent do
				local pool = parseTexturePool(chaosPoolBox.Text)
				local textureId = nil

				if #pool > 0 then
					textureId = pool[rng:NextInteger(1, #pool)]
				elseif normalizeTextureId(textureBox.Text) then
					textureId = normalizeTextureId(textureBox.Text)
				end

				for _, part in ipairs(getAllParts()) do
					saveOriginal(part)

					if textureId then
						applyTextureToPart(part, textureId)
					else
						clearGeneratedTextures(part)
					end

					part.Color = Color3.fromRGB(
						rng:NextInteger(0, 255),
						rng:NextInteger(0, 255),
						rng:NextInteger(0, 255)
					)

					part.Material = materialList[rng:NextInteger(1, #materialList)]
				end

				task.wait(0.06)
			end

			if not chaosOn then
				chaosButton.Text = "CHAOS! : OFF"
				chaosButton.BackgroundColor3 = Color3.fromRGB(150, 90, 40)
			end
		end)
	else
		restoreAll()
		chaosButton.Text = "CHAOS! : OFF"
		chaosButton.BackgroundColor3 = Color3.fromRGB(150, 90, 40)
		updateStatus("Chaos stopped")
	end
end)

hideButton.MouseButton1Click:Connect(function()
	mainFrame.Visible = false
	smallButton.Visible = true
end)

smallButton.MouseButton1Click:Connect(function()
	mainFrame.Visible = true
	smallButton.Visible = false
end)

closeButton.MouseButton1Click:Connect(function()
	restoreAll()
	screenGui:Destroy()
end)

-- Fixed draggable: drag the TITLE BAR to move the whole GUI
local function makeDraggable(handle, target)
	local dragging = false
	local dragInput
	local dragStart
	local startPos

	handle.InputBegan:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1
			or input.UserInputType == Enum.UserInputType.Touch then
			dragging = true
			dragStart = input.Position
			startPos = target.Position

			input.Changed:Connect(function()
				if input.UserInputState == Enum.UserInputState.End then
					dragging = false
				end
			end)
		end
	end)

	handle.InputChanged:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseMovement
			or input.UserInputType == Enum.UserInputType.Touch then
			dragInput = input
		end
	end)

	UserInputService.InputChanged:Connect(function(input)
		if input == dragInput and dragging then
			local delta = input.Position - dragStart
			target.Position = UDim2.new(
				startPos.X.Scale,
				startPos.X.Offset + delta.X,
				startPos.Y.Scale,
				startPos.Y.Offset + delta.Y
			)
		end
	end)
end

makeDraggable(titleBar, mainFrame)
makeDraggable(smallButton, smallButton)

refreshMaterialText()
updateStatus("Ready")

Features & Information

--// Texture Changer GUI --// Open Source | Credit: Me --// Local-only visual changer --// Easily change textures, colors, and materials of all parts in your game. --// Includes CHAOS mode for random fun! --// Put this LocalScript in StarterPlayerScripts or StarterGui

Community Comments (1)

Yogurt121234Yogurt121234Mar 30, 2026

not working

More Scripts for Universal Scripts