local Players = game:GetService("Players") local UserInputService = game:GetService("UserInputService") local ConteAntProvider = game:GetService("ContentProvider") local player = Players.LocalPlayer local isMobile = UserInputService.TouchEnabled -- Função draggable (suporta mouse e touch) local function makeDraggable(frame) local dragging = false local dragInput = nil local dragStart = nil local startPos = nil local function update(input) local delta = input.Position - dragStart frame.Position = UDim2.new(startPos.X.Scale, startPos.X.Offset + delta.X, startPos.Y.Scale, startPos.Y.Offset + delta.Y) end frame.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragging = true dragStart = input.Position startPos = frame.Position input.Changed:Connect(function() if input.UserInputState == Enum.UserInputState.End then dragging = false end end) end end) frame.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.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) and dragging then update(input) end end) end -- ScreenGui local screenGui = Instance.new("ScreenGui") screenGui.Name = "WheelCustomizerGUI" screenGui.ResetOnSpawn = false screenGui.Parent = player:WaitForChild("PlayerGui") -- Botão abrir local openButton = Instance.new("TextButton") openButton.Size = UDim2.new(0, 40, 0, 40) openButton.Position = UDim2.new(1, -50, 0, 30) openButton.BackgroundColor3 = Color3.fromRGB(57, 57, 57) openButton.Text = "⚙" openButton.TextColor3 = Color3.new(1, 1, 1) openButton.Font = Enum.Font.GothamBold openButton.TextScaled = true openButton.Parent = screenGui local openCorner = Instance.new("UICorner") openCorner.CornerRadius = UDim.new(0, 8) openCorner.Parent = openButton makeDraggable(openButton) -- Menu principal (aumentado para mobile) local mainFrame = Instance.new("Frame") mainFrame.Size = isMobile and UDim2.new(0, 320, 0, 370) or UDim2.new(0, 420, 0, 430) mainFrame.Position = UDim2.new(0.5, isMobile and -160 or -210, 0.5, -180) -- centrado melhor mainFrame.BackgroundColor3 = Color3.fromRGB(25, 25, 35) mainFrame.BorderSizePixel = 0 mainFrame.Visible = false mainFrame.Parent = screenGui local mainCorner = Instance.new("UICorner") mainCorner.CornerRadius = UDim.new(0, 12) mainCorner.Parent = mainFrame makeDraggable(mainFrame) -- Título (menor em mobile) local title = Instance.new("TextLabel") title.Size = UDim2.new(1, 0, 0, isMobile and 40 or 50) title.BackgroundTransparency = 1 title.Text = "Customizador de Rodas" title.TextColor3 = Color3.fromRGB(0, 170, 255) title.Font = Enum.Font.GothamBold title.TextSize = isMobile and 20 or 24 title.Parent = mainFrame -- Colunas (ajustadas para mobile) local leftFrame = Instance.new("Frame") leftFrame.Size = UDim2.new(0.5, -5, 1, isMobile and -80 or -60) leftFrame.Position = UDim2.new(0, 5, 0, isMobile and 40 or 50) leftFrame.BackgroundTransparency = 1 leftFrame.Parent = mainFrame local rightFrame = Instance.new("Frame") rightFrame.Size = UDim2.new(0.5, -5, 1, isMobile and -80 or -60) rightFrame.Position = UDim2.new(0.5, 0, 0, isMobile and 40 or 50) rightFrame.BackgroundTransparency = 1 rightFrame.Parent = mainFrame -- Títulos colunas (menores em mobile) local rimTitle = Instance.new("TextLabel") rimTitle.Size = UDim2.new(1, 0, 0, 25) rimTitle.BackgroundTransparency = 1 rimTitle.Text = "Roda (Rim)" rimTitle.TextColor3 = Color3.fromRGB(0, 200, 255) rimTitle.Font = Enum.Font.GothamBold rimTitle.TextSize = isMobile and 16 or 18 rimTitle.Parent = leftFrame local tireTitle = Instance.new("TextLabel") tireTitle.Size = UDim2.new(1, 0, 0, 25) tireTitle.BackgroundTransparency = 1 tireTitle.Text = "Pneu (Tire)" tireTitle.TextColor3 = Color3.fromRGB(0, 200, 255) tireTitle.Font = Enum.Font.GothamBold tireTitle.TextSize = isMobile and 16 or 18 tireTitle.Parent = rightFrame -- Boxes local boxes = {} -- Função para extrair ID válido local function getAssetId(input) if input == "" or input == nil then return "" end local num = input:match("%d+") if num then return "rbxassetid://" .. num else warn("ID inválido (não contém números): " .. input) return "" end end local function createSection(parent, prefix, yStart) local y = yStart local labelSize = isMobile and 25 or 30 local boxSize = isMobile and 25 or 30 local ySpacing = isMobile and 40 or 50 local tripleSpacing = isMobile and 35 or 40 local tripleY = isMobile and 28 or 32 -- Mesh ID local meshLabel = Instance.new("TextLabel") meshLabel.Size = UDim2.new(0, 80, 0, labelSize) meshLabel.Position = UDim2.new(0, isMobile and 10 or 30, 0, y) meshLabel.BackgroundTransparency = 1 meshLabel.Text = "ID:" meshLabel.TextColor3 = Color3.new(1,1,1) meshLabel.Font = Enum.Font.GothamSemibold meshLabel.TextSize = isMobile and 14 or 16 meshLabel.TextXAlignment = Enum.TextXAlignment.Left meshLabel.Parent = parent local meshBox = Instance.new("TextBox") meshBox.Size = UDim2.new(1, isMobile and -60 or -72, 0, boxSize) meshBox.Position = UDim2.new(0, isMobile and 60 or 72, 0, y) meshBox.BackgroundColor3 = Color3.fromRGB(40, 40, 50) meshBox.TextColor3 = Color3.new(1,1,1) meshBox.PlaceholderText = "Número ou link" meshBox.Parent = parent boxes[prefix.."MeshId"] = meshBox local meshCorner = Instance.new("UICorner", meshBox) meshCorner.CornerRadius = UDim.new(0, 6) y = y + ySpacing -- Texture ID local texLabel = Instance.new("TextLabel") texLabel.Size = UDim2.new(0, 80, 0, labelSize) texLabel.Position = UDim2.new(0, isMobile and 10 or 30, 0, y) texLabel.BackgroundTransparency = 1 texLabel.Text = "Tx ID:" texLabel.TextColor3 = Color3.new(1,1,1) texLabel.Font = Enum.Font.GothamSemibold texLabel.TextSize = isMobile and 14 or 16 texLabel.TextXAlignment = Enum.TextXAlignment.Left texLabel.Parent = parent local texBox = Instance.new("TextBox") texBox.Size = UDim2.new(1, isMobile and -60 or -72, 0, boxSize) texBox.Position = UDim2.new(0, isMobile and 60 or 72, 0, y) texBox.BackgroundColor3 = Color3.fromRGB(40, 40, 50) texBox.TextColor3 = Color3.new(1,1,1) texBox.PlaceholderText = "Número ou link" texBox.Parent = parent boxes[prefix.."TexId"] = texBox local texCorner = Instance.new("UICorner", texBox) texCorner.CornerRadius = UDim.new(0, 6) y = y + ySpacing local function addTriple(labelText, fieldPrefix) local label = Instance.new("TextLabel") label.Size = UDim2.new(1, 0, 0, isMobile and 24 or 28) label.Position = UDim2.new(0, 0, 0, y) label.BackgroundTransparency = 1 label.Text = labelText label.TextColor3 = Color3.fromRGB(220, 220, 220) label.Font = Enum.Font.GothamBold label.TextSize = isMobile and 16 or 18 label.TextXAlignment = Enum.TextXAlignment.Left label.Parent = parent y = y + tripleY local default = labelText:find("Tamanho") and "1" or "0" for i, axis in ipairs({"X", "Y", "Z"}) do local box = Instance.new("TextBox") box.Size = UDim2.new(0, isMobile and 45 or 55, 0, isMobile and 24 or 28) box.Position = UDim2.new(0, isMobile and 5 + (i-1)*50 or 10 + (i-1)*65, 0, y) box.BackgroundColor3 = Color3.fromRGB(40, 40, 50) box.TextColor3 = Color3.new(1,1,1) box.Text = default box.Parent = parent boxes[fieldPrefix..axis] = box local corner = Instance.new("UICorner", box) corner.CornerRadius = UDim.new(0, 6) end y = y + tripleSpacing end addTriple("Tamanho (Scale)", prefix.."Scale") addTriple("Posição (Offset)", prefix.."Pos") addTriple("Rotação (Graus)", prefix.."Rot") end createSection(leftFrame, "Rim", 30) createSection(rightFrame, "Tire", 30) -- Botão Aplicar (ajustado para mobile) local applyButton = Instance.new("TextButton") applyButton.Size = UDim2.new(0, isMobile and 120 or 140, 0, isMobile and 35 or 40) applyButton.Position = UDim2.new(1, isMobile and -130 or -150, 1, isMobile and -40 or -44) applyButton.BackgroundColor3 = Color3.fromRGB(0, 170, 80) applyButton.Text = "Aplicar" applyButton.TextColor3 = Color3.new(1, 1, 1) applyButton.Font = Enum.Font.GothamBold applyButton.TextSize = isMobile and 18 or 20 applyButton.Parent = mainFrame local applyCorner = Instance.new("UICorner") applyCorner.CornerRadius = UDim.new(0, 10) applyCorner.Parent = applyButton -- Novos botões toggle para inversão (movidos 10px para baixo e mais próximos) local toggleFrame = Instance.new("Frame") toggleFrame.Size = UDim2.new(1, 0, 0, isMobile and 35 or 40) toggleFrame.Position = UDim2.new(0, 0, 1, isMobile and -45 or -50) toggleFrame.BackgroundTransparency = 1 toggleFrame.Parent = mainFrame local invertX = Instance.new("TextButton") invertX.Size = UDim2.new(0, isMobile and 50 or 60, 0, isMobile and 25 or 30) invertX.Position = UDim2.new(isMobile and 0.05 or 0.05, 0, 0, isMobile and 10 or 13) -- +10px para baixo invertX.BackgroundColor3 = Color3.fromRGB(170, 0, 0) invertX.Text = "Inv X" invertX.TextColor3 = Color3.new(1,1,1) invertX.Font = Enum.Font.GothamBold invertX.TextSize = isMobile and 12 or 14 invertX.Parent = toggleFrame local invertXCorner = Instance.new("UICorner") invertXCorner.CornerRadius = UDim.new(0, 6) invertXCorner.Parent = invertX local invertY = Instance.new("TextButton") invertY.Size = UDim2.new(0, isMobile and 50 or 60, 0, isMobile and 25 or 30) invertY.Position = UDim2.new(isMobile and 0.225 or 0.225, 0, 0, isMobile and 10 or 13) -- mais próximo invertY.BackgroundColor3 = Color3.fromRGB(170, 0, 0) invertY.Text = "Inv Y" invertY.TextColor3 = Color3.new(1,1,1) invertY.Font = Enum.Font.GothamBold invertY.TextSize = isMobile and 12 or 14 invertY.Parent = toggleFrame local invertYCorner = Instance.new("UICorner") invertYCorner.CornerRadius = UDim.new(0, 6) invertYCorner.Parent = invertY local invertZ = Instance.new("TextButton") invertZ.Size = UDim2.new(0, isMobile and 50 or 60, 0, isMobile and 25 or 30) invertZ.Position = UDim2.new(isMobile and 0.4 or 0.4, 0, 0, isMobile and 10 or 13) -- mais próximo invertZ.BackgroundColor3 = Color3.fromRGB(170, 0, 0) invertZ.Text = "Inv Z" invertZ.TextColor3 = Color3.new(1,1,1) invertZ.Font = Enum.Font.GothamBold invertZ.TextSize = isMobile and 12 or 14 invertZ.Parent = toggleFrame local invertZCorner = Instance.new("UICorner") invertZCorner.CornerRadius = UDim.new(0, 6) invertZCorner.Parent = invertZ -- Estados dos toggles local invertStates = {X = false, Y = false, Z = false} local function toggleButton(button, axis) button.MouseButton1Click:Connect(function() invertStates[axis] = not invertStates[axis] button.BackgroundColor3 = invertStates[axis] and Color3.fromRGB(0, 170, 0) or Color3.fromRGB(170, 0, 0) end) end toggleButton(invertX, "X") toggleButton(invertY, "Y") toggleButton(invertZ, "Z") -- Toggle menu openButton.MouseButton1Click:Connect(function() mainFrame.Visible = not mainFrame.Visible end) -- Encontrar carro e wheels local function findMyCar() if not workspace:FindFirstChild("Cars") then return nil end for _, model in pairs(workspace.Cars:GetChildren()) do if model:IsA("Model") then local stats = model:FindFirstChild("Stats") if stats then local owner = stats:FindFirstChild("Owner") if owner and owner.Value == player.Name then return model end end end end return nil end local function getWheels(car) local wheels = {} local wheelNames = {"FR", "FL", "RR", "RL"} for _, name in pairs(wheelNames) do for _, obj in pairs(car:GetDescendants()) do if obj.Name == name and obj:FindFirstChild("Wheel") then table.insert(wheels, obj.Wheel) end end end if #wheels == 0 then for _, desc in pairs(car:GetDescendants()) do if desc.Name == "Wheel" and desc:IsA("BasePart") then table.insert(wheels, desc) end end end return wheels end -- Aplicar applyButton.MouseButton1Click:Connect(function() local car = findMyCar() if not car then warn("Carro não encontrado!"); return end local wheels = getWheels(car) if #wheels == 0 then warn("Nenhuma roda encontrada!"); return end local function getText(name) return boxes[name].Text end local function getNum(name, default) return tonumber(getText(name)) or default end -- Parsing IDs local rimMeshId = getAssetId(getText("RimMeshId")) local rimTexId = getAssetId(getText("RimTexId")) local tireMeshId = getAssetId(getText("TireMeshId")) local tireTexId = getAssetId(getText("TireTexId")) local rimScale = Vector3.new(getNum("RimScaleX",1), getNum("RimScaleY",1), getNum("RimScaleZ",1)) local rimPos = Vector3.new(getNum("RimPosX",0), getNum("RimPosY",0), getNum("RimPosZ",0)) local rimRot = CFrame.fromEulerAnglesXYZ(math.rad(getNum("RimRotX",0)), math.rad(getNum("RimRotY",0)), math.rad(getNum("RimRotZ",0))) local tireScale = Vector3.new(getNum("TireScaleX",1), getNum("TireScaleY",1), getNum("TireScaleZ",1)) local tirePos = Vector3.new(getNum("TirePosX",0), getNum("TirePosY",0), getNum("TirePosZ",0)) local tireRot = CFrame.fromEulerAnglesXYZ(math.rad(getNum("TireRotX",0)), math.rad(getNum("TireRotY",0)), math.rad(getNum("TireRotZ",0))) local assetsToPreload = {} for _, wheel in pairs(wheels) do local parentName = wheel.Parent and wheel.Parent.Name or "" local isRightWheel = parentName:find("R$") ~= nil -- Aplicar inversão de 180° apenas no Rim das rodas direitas, se toggle ativado local rimExtraRot = CFrame.identity if isRightWheel then if invertStates.X then rimExtraRot = rimExtraRot * CFrame.Angles(math.rad(180), 0, 0) end if invertStates.Y then rimExtraRot = rimExtraRot * CFrame.Angles(0, math.rad(180), 0) end if invertStates.Z then rimExtraRot = rimExtraRot * CFrame.Angles(0, 0, math.rad(180)) end end -- Limpeza for _, child in pairs(wheel:GetChildren()) do if not (child.Name == "Attachment1" or child.Name == "Caliper" or child.Name == "Disc" or child.Name == "CustomRim" or child.Name == "CustomTire" or child.Name == "RimWeld" or child.Name == "TireWeld") then child:Destroy() end end -- Custom Rim (com extra rot se aplicável) local rimPart = wheel:FindFirstChild("CustomRim") or Instance.new("Part") rimPart.Name = "CustomRim" rimPart.Parent = wheel rimPart.Size = Vector3.new(0.2, 0.2, 0.2) rimPart.Transparency = 0 rimPart.Color = Color3.fromRGB(180, 180, 180) rimPart.CanCollide = false rimPart.Massless = true local rimMesh = rimPart:FindFirstChildOfClass("SpecialMesh") or Instance.new("SpecialMesh") rimMesh.Parent = rimPart rimMesh.MeshId = rimMeshId rimMesh.TextureId = rimTexId rimMesh.Scale = rimScale if rimMeshId ~= "" then table.insert(assetsToPreload, rimMeshId) end if rimTexId ~= "" then table.insert(assetsToPreload, rimTexId) end local rimWeld = wheel:FindFirstChild("RimWeld") or Instance.new("Weld") rimWeld.Name = "RimWeld" rimWeld.Parent = wheel rimWeld.Part0 = wheel rimWeld.Part1 = rimPart rimWeld.C0 = CFrame.new(rimPos) * rimRot * rimExtraRot -- aplica a rotação extra aqui -- Custom Tire (sem alteração) local tirePart = wheel:FindFirstChild("CustomTire") or Instance.new("Part") tirePart.Name = "CustomTire" tirePart.Parent = wheel tirePart.Size = Vector3.new(0.2, 0.2, 0.2) tirePart.Transparency = 0 tirePart.Color = Color3.fromRGB(180, 180, 180) tirePart.CanCollide = false tirePart.Massless = true local tireMesh = tirePart:FindFirstChildOfClass("SpecialMesh") or Instance.new("SpecialMesh") tireMesh.Parent = tirePart tireMesh.MeshId = tireMeshId tireMesh.TextureId = tireTexId tireMesh.Scale = tireScale if tireMeshId ~= "" then table.insert(assetsToPreload, tireMeshId) end if tireTexId ~= "" then table.insert(assetsToPreload, tireTexId) end local tireWeld = wheel:FindFirstChild("TireWeld") or Instance.new("Weld") tireWeld.Name = "TireWeld" tireWeld.Parent = wheel tireWeld.Part0 = wheel tireWeld.Part1 = tirePart tireWeld.C0 = CFrame.new(tirePos) * tireRot end -- Forçar carregamento if #assetsToPreload > 0 then pcall(function() ContentProvider:PreloadAsync(assetsToPreload) end) end print("Customizações aplicadas! Use os toggles para inverter eixos nas rodas direitas.") end) print("Customizador de Rodas atualizado para mobile! Clique no botão '⚙' para abrir.")