-- LocalScript: Snake Plus+ with Dynamic Color Modes + Head + Accessories -- StarterPlayer -> StarterPlayerScripts local Players = game:GetService("Players") local RunService = game:GetService("RunService") local player = Players.LocalPlayer -- ================= GUI ================= local function createGui() local gui = Instance.new("ScreenGui") gui.Name = "SnakePlusPlusGui" gui.ResetOnSpawn = false gui.Parent = player:WaitForChild("PlayerGui") local frame = Instance.new("Frame") frame.AnchorPoint = Vector2.new(0.5,1) frame.Position = UDim2.new(0.5,0,1,-20) frame.Size = UDim2.new(0,500,0,70) frame.BackgroundTransparency = 0.2 frame.BackgroundColor3 = Color3.fromRGB(25,25,25) frame.Parent = gui Instance.new("UICorner", frame).CornerRadius = UDim.new(0,10) local layout = Instance.new("UIListLayout", frame) layout.FillDirection = Enum.FillDirection.Horizontal layout.HorizontalAlignment = Enum.HorizontalAlignment.Center layout.VerticalAlignment = Enum.VerticalAlignment.Center layout.Padding = UDim.new(0,8) local padding = Instance.new("UIPadding", frame) padding.PaddingLeft = UDim.new(0,12) padding.PaddingRight = UDim.new(0,12) local box = Instance.new("TextBox") box.Size = UDim2.new(0,120,0,46) box.PlaceholderText = "Snake length" box.Text = "" box.ClearTextOnFocus = false box.TextScaled = true box.BackgroundColor3 = Color3.fromRGB(40,40,40) box.TextColor3 = Color3.new(1,1,1) box.Parent = frame Instance.new("UICorner", box).CornerRadius = UDim.new(0,8) box:GetPropertyChangedSignal("Text"):Connect(function() box.Text = box.Text:gsub("%D","") -- numbers only end) local function createBtn(txt,col) local b = Instance.new("TextButton") b.Size = UDim2.new(0,60,0,46) b.Text = txt b.TextScaled = true b.BackgroundColor3 = col b.TextColor3 = Color3.new(1,1,1) Instance.new("UICorner", b).CornerRadius = UDim.new(0,8) b.Parent = frame return b end local plus = createBtn("+",Color3.fromRGB(60,120,60)) local plus2 = createBtn("++",Color3.fromRGB(60,150,60)) local inf = createBtn("∞",Color3.fromRGB(150,60,150)) local clear = createBtn("Clear",Color3.fromRGB(120,60,60)) local colorBtn = createBtn("Color",Color3.fromRGB(60,60,150)) return gui, box, plus, plus2, inf, clear, colorBtn end -- ================= Character ================= local character local humanoid local hrp local function bindCharacter(char) character = char humanoid = character:WaitForChild("Humanoid") hrp = character:WaitForChild("HumanoidRootPart") end if player.Character then bindCharacter(player.Character) end player.CharacterAdded:Connect(bindCharacter) local function getRigPartNames() if not humanoid then return {} end if humanoid.RigType==Enum.HumanoidRigType.R6 then return {"Head","Torso","Left Arm","Right Arm","Left Leg","Right Leg"} else return { "Head", "UpperTorso","LowerTorso", "LeftUpperArm","LeftLowerArm","LeftHand", "RightUpperArm","RightLowerArm","RightHand", "LeftUpperLeg","LeftLowerLeg","LeftFoot", "RightUpperLeg","RightLowerLeg","RightFoot" } end end local function buildRelativeMap() local map = {} for _, name in ipairs(getRigPartNames()) do local p = character:FindFirstChild(name,true) if p and p:IsA("BasePart") then map[name] = hrp.CFrame:ToObjectSpace(p.CFrame) end end return map end -- ================= Snake Management ================= local snakeSegments = {} local trail = {} local FRAMES_PER_SEGMENT = 3 local MAX_SEGMENTS = 250 local WIGGLE_SPEED = 4 local WIGGLE_AMOUNT = 0.22 local colorMode = "Rainbow" local solidColor = Color3.new(1,1,1) local function clearSnake() for _, seg in ipairs(snakeSegments) do for _, part in pairs(seg.parts) do part:Destroy() end end snakeSegments = {} trail = {} end local function getSegmentColor(idx,total) if colorMode=="Rainbow" then local hue = (idx/total) % 1 return Color3.fromHSV(hue,0.8,1) elseif colorMode=="Random" then return Color3.fromRGB(math.random(0,255),math.random(0,255),math.random(0,255)) else return solidColor end end local function updateSnakeColors() for i, seg in ipairs(snakeSegments) do local total = #snakeSegments for _, part in pairs(seg.parts) do part.Color = getSegmentColor(i,total) end -- Update accessories attached to head if seg.parts.Head then for _, acc in ipairs(seg.parts.Head:GetChildren()) do if acc:IsA("BasePart") then acc.Color = getSegmentColor(i,total) end end end end end local function createSegment(relMap, idx, total) local seg = {parts={},rel=relMap} for name, rel in pairs(relMap) do local src = character:FindFirstChild(name,true) if src and src:IsA("BasePart") then local clone = src:Clone() clone.Anchored = true clone.CanCollide = false clone.Massless = true clone.Name = "Snake_"..name for _, child in ipairs(clone:GetChildren()) do if child:IsA("Motor6D") or child:IsA("Weld") or child:IsA("WeldConstraint") then child:Destroy() end end -- Color & scale clone.Color = getSegmentColor(idx,total) local scale = 1 - (idx/total)*0.5 clone.Size = clone.Size * scale clone.CFrame = hrp.CFrame * rel clone.Parent = workspace seg.parts[name] = clone -- Head accessories if name=="Head" then for _, acc in ipairs(character:GetChildren()) do if acc:IsA("Accessory") then local accClone = acc:Clone() for _, child in ipairs(accClone:GetDescendants()) do if child:IsA("Motor6D") or child:IsA("Weld") or child:IsA("Attachment") then child:Destroy() end end accClone.Parent = clone end end end end end return seg end local function spawnSnake(length) length = math.clamp(math.floor(length),0,MAX_SEGMENTS) local relMap = buildRelativeMap() while #snakeSegments < length do table.insert(snakeSegments, createSegment(relMap,#snakeSegments+1,length)) end while #snakeSegments > length do local seg = table.remove(snakeSegments) for _, part in pairs(seg.parts) do part:Destroy() end end trail = {} local need = length*FRAMES_PER_SEGMENT+10 for i=1,need do table.insert(trail,1,hrp.CFrame*CFrame.new(0,0,-i*1.5)) end end RunService.Heartbeat:Connect(function() if not hrp or #snakeSegments==0 then return end table.insert(trail,1,hrp.CFrame) local maxTrail = #snakeSegments*FRAMES_PER_SEGMENT+20 while #trail>maxTrail do table.remove(trail) end for i,seg in ipairs(snakeSegments) do local idx = i*FRAMES_PER_SEGMENT+1 local baseCF = trail[idx] or (hrp.CFrame*CFrame.new(0,0,-i*2)) local wiggle = math.sin(os.clock()*WIGGLE_SPEED+i*0.35)*WIGGLE_AMOUNT local vertical = math.sin(os.clock()*WIGGLE_SPEED*0.5+i*0.2)*0.1 local segCF = baseCF * CFrame.Angles(vertical, wiggle, 0) for name,part in pairs(seg.parts) do local rel = seg.rel[name] if rel then part.CFrame = segCF*rel end end end end) player.CharacterAdded:Connect(clearSnake) -- ================= GUI Actions ================= local gui, box, plus, plus2, inf, clearBtn, colorBtn = createGui() plus.MouseButton1Click:Connect(function() spawnSnake(#snakeSegments+1) end) plus2.MouseButton1Click:Connect(function() spawnSnake(#snakeSegments+10) end) inf.MouseButton1Click:Connect(function() spawnSnake(MAX_SEGMENTS) end) clearBtn.MouseButton1Click:Connect(clearSnake) box.FocusLost:Connect(function(enterPressed) if enterPressed and box.Text~="" then local n = tonumber(box.Text) if n then spawnSnake(n) end end end) -- ================= Color Button Action ================= local modes = {"Rainbow","Solid","Random"} local modeIndex = 1 colorBtn.MouseButton1Click:Connect(function() modeIndex = modeIndex + 1 if modeIndex > #modes then modeIndex = 1 end colorMode = modes[modeIndex] updateSnakeColors() end)