local Players = game:GetService("Players") local ReplicatedStorage = game:GetService("ReplicatedStorage") local UserInputService = game:GetService("UserInputService") local RunService = game:GetService("RunService") local TweenService = game:GetService("TweenService") local SoundService = game:GetService("SoundService") local Debris = game:GetService("Debris") local Player = Players.LocalPlayer local PlayerGui = Player:WaitForChild("PlayerGui") local Event = ReplicatedStorage:WaitForChild("MenuToys"):WaitForChild("SpawnToyRemoteFunction") local Gui = Instance.new("ScreenGui") Gui.Name = "PalletSpawner" Gui.ResetOnSpawn = false Gui.IgnoreGuiInset = true Gui.ZIndexBehavior = Enum.ZIndexBehavior.Global Gui.DisplayOrder = 2147483647 Gui.Parent = PlayerGui local Image = Instance.new("ImageButton") Image.Name = "PalletButton" Image.Size = UDim2.fromOffset(110, 110) Image.AnchorPoint = Vector2.new(0.5, 0.5) Image.Position = UDim2.fromScale(0.5, 0.5) Image.BackgroundTransparency = 1 Image.BorderSizePixel = 0 Image.Image = "rbxassetid://95292521131861" Image.ImageTransparency = 1 Image.ScaleType = Enum.ScaleType.Fit Image.AutoButtonColor = false Image.Active = false Image.Selectable = false Image.Visible = false Image.ZIndex = 2147483647 Image.Parent = Gui local UIScale = Instance.new("UIScale") UIScale.Scale = 1 UIScale.Parent = Image local IntroSound = Instance.new("Sound") IntroSound.Name = "PalletIntroSound" IntroSound.SoundId = "rbxassetid://17556446241" IntroSound.PlaybackSpeed = 0.9 IntroSound.Volume = 1 IntroSound.Parent = SoundService local ready = false local activeInput = nil local dragStart = nil local startPosition = nil local targetPosition = Image.Position local dragging = false local moved = false local smoothness = 32 local dragThreshold = 8 local screenPadding = 4 local pressScaleTween local releaseScaleTween local function KeepGuiOnTop() if Gui.Parent ~= PlayerGui then Gui.Parent = PlayerGui end Gui.DisplayOrder = 2147483647 Gui.ZIndexBehavior = Enum.ZIndexBehavior.Global Image.ZIndex = 2147483647 end PlayerGui.ChildAdded:Connect(function(child) if child:IsA("ScreenGui") and child ~= Gui then task.defer(KeepGuiOnTop) end end) local function PlayClickSound() local sound = Instance.new("Sound") sound.SoundId = "rbxassetid://100809160609628" sound.Volume = 1 sound.Parent = SoundService sound:Play() Debris:AddItem(sound, 10) end local function ClampPosition(position) local camera = workspace.CurrentCamera if not camera then return position end local viewport = camera.ViewportSize local halfWidth = Image.AbsoluteSize.X * 0.5 local halfHeight = Image.AbsoluteSize.Y * 0.5 local minX = halfWidth + screenPadding local maxX = math.max(minX, viewport.X - halfWidth - screenPadding) local minY = halfHeight + screenPadding local maxY = math.max(minY, viewport.Y - halfHeight - screenPadding) local x = math.clamp( viewport.X * position.X.Scale + position.X.Offset, minX, maxX ) local y = math.clamp( viewport.Y * position.Y.Scale + position.Y.Offset, minY, maxY ) return UDim2.fromOffset(x, y) end local function PlayPressEffect() if pressScaleTween then pressScaleTween:Cancel() end if releaseScaleTween then releaseScaleTween:Cancel() end UIScale.Scale = 1 pressScaleTween = TweenService:Create( UIScale, TweenInfo.new(0.12, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), {Scale = 0.92} ) releaseScaleTween = TweenService:Create( UIScale, TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), {Scale = 1} ) pressScaleTween:Play() pressScaleTween.Completed:Once(function(state) if state == Enum.PlaybackState.Completed then releaseScaleTween:Play() end end) end local function SpawnPallet() local camera = workspace.CurrentCamera if not camera then return end local lookVector = camera.CFrame.LookVector local spawnPosition = camera.CFrame.Position + lookVector * 3 local spawnCFrame = CFrame.lookAt( spawnPosition, spawnPosition + lookVector ) task.spawn(function() pcall(function() Event:InvokeServer( "PalletLightBrown", spawnCFrame, Vector3.zero ) end) end) end local function IsInsideImage(position) local imagePosition = Image.AbsolutePosition local imageSize = Image.AbsoluteSize return position.X >= imagePosition.X and position.X <= imagePosition.X + imageSize.X and position.Y >= imagePosition.Y and position.Y <= imagePosition.Y + imageSize.Y end Image.InputBegan:Connect(function(input) if not ready or activeInput then return end local inputType = input.UserInputType if inputType ~= Enum.UserInputType.Touch and inputType ~= Enum.UserInputType.MouseButton1 then return end activeInput = input dragStart = input.Position startPosition = Image.Position targetPosition = Image.Position dragging = false moved = false end) local function UpdateDrag(position, isTouch) if not ready or not activeInput then return end if isTouch then if activeInput.UserInputType ~= Enum.UserInputType.Touch then return end else if activeInput.UserInputType ~= Enum.UserInputType.MouseButton1 then return end end local delta = position - dragStart if delta.Magnitude >= dragThreshold then moved = true dragging = true end if dragging then local proposed = UDim2.new( startPosition.X.Scale, startPosition.X.Offset + delta.X, startPosition.Y.Scale, startPosition.Y.Offset + delta.Y ) targetPosition = ClampPosition(proposed) end end UserInputService.TouchMoved:Connect(function(input) if activeInput == input then UpdateDrag(input.Position, true) end end) UserInputService.InputChanged:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseMovement then UpdateDrag(input.Position, false) end end) UserInputService.InputEnded:Connect(function(input) if not activeInput or input ~= activeInput then if not activeInput or activeInput.UserInputType ~= Enum.UserInputType.MouseButton1 or input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end end local inputType = activeInput.UserInputType if inputType == Enum.UserInputType.Touch and input ~= activeInput then return end if inputType == Enum.UserInputType.MouseButton1 and input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end local wasDragging = dragging local wasMoved = moved local releasePosition = input.Position activeInput = nil dragging = false moved = false if wasDragging or wasMoved then targetPosition = ClampPosition(targetPosition) return end if not IsInsideImage(releasePosition) then return end PlayClickSound() PlayPressEffect() SpawnPallet() end) IntroSound:Play() IntroSound.Ended:Wait() if not Gui.Parent then return end Image.Visible = true local fadeTween = TweenService:Create( Image, TweenInfo.new(0.7, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), {ImageTransparency = 0} ) fadeTween:Play() fadeTween.Completed:Wait() if Gui.Parent then Image.Active = true ready = true end RunService.RenderStepped:Connect(function(dt) KeepGuiOnTop() if not ready then return end if not activeInput then targetPosition = ClampPosition(targetPosition) end local alpha = 1 - math.exp(-smoothness * dt) Image.Position = UDim2.new( Image.Position.X.Scale + (targetPosition.X.Scale - Image.Position.X.Scale) * alpha, Image.Position.X.Offset + (targetPosition.X.Offset - Image.Position.X.Offset) * alpha, Image.Position.Y.Scale + (targetPosition.Y.Scale - Image.Position.Y.Scale) * alpha, Image.Position.Y.Offset + (targetPosition.Y.Offset - Image.Position.Y.Offset) * alpha ) end)