
KeylessUniversal

loadstring([[
if getgenv().ThorBallLoaded then
if game.CoreGui:FindFirstChild("ThorBallGui") then game.CoreGui.ThorBallGui:Destroy() end
if workspace:FindFirstChild("ThorBall_Thrown") then workspace.ThorBall_Thrown:Destroy() end
end
getgenv().ThorBallLoaded = true
getgenv().SelectedBallType = getgenv().SelectedBallType or "Light"
local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")
local Debris = game:GetService("Debris")
local player = Players.LocalPlayer
local thrownBall, isReturning, floatConn, lastSpeed = nil, false, nil, 70
local BallTypes = {
Light = {Color=Color3.fromRGB(255,255,0), Material=Enum.Material.Neon, Speed=160, Trail=Color3.fromRGB(255,255,150), Name="LIGHT [KIZARU]", SoundThrow="rbxassetid://12222025", SoundHit="rbxassetid://12222030", LightColor=Color3.fromRGB(255,255,100)},
Thor = {Color=Color3.fromRGB(255,0,0), Material=Enum.Material.Neon, Speed=70, Trail=Color3.fromRGB(255,0,0), Name="THOR", SoundThrow="rbxassetid://12222124", SoundHit="rbxassetid://12222216", LightColor=Color3.fromRGB(255,0,0)},
Flame = {Color=Color3.fromRGB(255,85,0), Material=Enum.Material.Neon, Speed=70, Trail=Color3.fromRGB(255,100,0), Name="FLAME", SoundThrow="rbxassetid://12222058", SoundHit="rbxassetid://12222116", LightColor=Color3.fromRGB(255,85,0)},
Lightning = {Color=Color3.fromRGB(0,200,255), Material=Enum.Material.ForceField, Speed=130, Trail=Color3.fromRGB(0,255,255), Name="LIGHTNING", SoundThrow="rbxassetid://12222086", SoundHit="rbxassetid://12222121", LightColor=Color3.fromRGB(0,200,255)},
Ice = {Color=Color3.fromRGB(100,200,255), Material=Enum.Material.Ice, Speed=60, Trail=Color3.fromRGB(150,220,255), Name="ICE", SoundThrow="rbxassetid://12221976", SoundHit="rbxassetid://12222066", LightColor=Color3.fromRGB(100,200,255)},
Magma = {Color=Color3.fromRGB(120,20,0), Material=Enum.Material.Slate, Speed=60, Trail=Color3.fromRGB(255,80,0), Name="MAGMA [AKAINU]", SoundThrow="rbxassetid://12222101", SoundHit="rbxassetid://12222106", LightColor=Color3.fromRGB(255,60,0)},
Galaxy = {Color=Color3.fromRGB(120,0,255), Material=Enum.Material.ForceField, Speed=75, Trail=Color3.fromRGB(180,0,255), Name="GALAXY", SoundThrow="rbxassetid://12222008", SoundHit="rbxassetid://12222045", LightColor=Color3.fromRGB(120,0,255)},
Blackhole = {Color=Color3.fromRGB(0,0,0), Material=Enum.Material.ForceField, Speed=60, Trail=Color3.fromRGB(80,0,130), Name="BLACKHOLE", SoundThrow="rbxassetid://12222009", SoundHit="rbxassetid://12222111", LightColor=Color3.fromRGB(50,0,100)},
Dragon = {Color=Color3.fromRGB(255,140,0), Material=Enum.Material.Neon, Speed=90, Trail=Color3.fromRGB(255,200,0), Name="DRAGON BALL", SoundThrow="rbxassetid://12222065", SoundHit="rbxassetid://12222212", LightColor=Color3.fromRGB(255,140,0)},
}
local gui = Instance.new("ScreenGui")
gui.Name = "ThorBallGui"
gui.ResetOnSpawn = false
gui.Parent = (gethui and gethui() or game.CoreGui)
local function makeCircleButton(name, text, pos, color, size)
local b = Instance.new("TextButton")
b.Name = name
b.Size = size or UDim2.new(0,65,0,65)
b.Position = pos
b.Text = text
b.TextScaled = true
b.Font = Enum.Font.GothamBold
b.TextColor3 = Color3.new(1,1,1)
b.BackgroundColor3 = color
b.Parent = gui
Instance.new("UICorner", b).CornerRadius = UDim.new(1,0)
local s = Instance.new("UIStroke", b)
s.Thickness = 2
s.Color = Color3.new(1,1,1)
return b
end
local ballBtn = makeCircleButton("BallBtn", "BALL", UDim2.new(0,15,0,15), Color3.fromRGB(255,50,50))
local returnBtn = makeCircleButton("ReturnBtn", "RETURN", UDim2.new(0,15,0,90), Color3.fromRGB(50,150,255))
-- NEW TOP RIGHT TOGGLE BUTTON (only shows when holding ball)
local changeBtn = makeCircleButton("ChangeBtn", "CHANGE", UDim2.new(1,-80,0,15), Color3.fromRGB(0,0,0), UDim2.new(0,65,0,65))
changeBtn.Visible = false
changeBtn.TextSize = 10
-- SELECTOR UI
local selectorFrame = Instance.new("Frame")
selectorFrame.Size = UDim2.new(0, 240, 0, 340)
selectorFrame.Position = UDim2.new(0.5, -120, 0.5, -170)
selectorFrame.BackgroundColor3 = Color3.fromRGB(15,15,15)
selectorFrame.Visible = false
selectorFrame.Parent = gui
Instance.new("UICorner", selectorFrame).CornerRadius = UDim.new(0,12)
local stroke = Instance.new("UIStroke", selectorFrame)
stroke.Color = Color3.fromRGB(255,255,255)
stroke.Thickness = 2
local title = Instance.new("TextLabel", selectorFrame)
title.Size = UDim2.new(1,0,0,30)
title.Text = "SELECTED: "..BallTypes[getgenv().SelectedBallType].Name
title.TextScaled = true
title.Font = Enum.Font.GothamBold
title.TextColor3 = Color3.new(1,1,1)
title.BackgroundTransparency = 1
local scroll = Instance.new("ScrollingFrame", selectorFrame)
scroll.Size = UDim2.new(1, -10, 1, -40)
scroll.Position = UDim2.new(0,5,0,35)
scroll.BackgroundTransparency = 1
scroll.ScrollBarThickness = 3
scroll.AutomaticCanvasSize = Enum.AutomaticSize.Y
local layout = Instance.new("UIGridLayout", scroll)
layout.CellSize = UDim2.new(0,105,0,45)
layout.CellPadding = UDim2.new(0,10,0,10)
for typeName, data in pairs(BallTypes) do
local btn = Instance.new("TextButton")
btn.Text = data.Name
btn.Font = Enum.Font.GothamBold
btn.TextScaled = true
btn.TextSize = 11
btn.TextColor3 = Color3.new(1,1,1)
btn.BackgroundColor3 = data.Color
btn.Parent = scroll
Instance.new("UICorner", btn).CornerRadius = UDim.new(0,8)
btn.MouseButton1Click:Connect(function()
getgenv().SelectedBallType = typeName
title.Text = "SELECTED: "..data.Name
lastSpeed = data.Speed
local char = player.Character
if char and char:FindFirstChild("ThorBall") and char.ThorBall:FindFirstChild("Handle") then
char.ThorBall.Handle.Color = data.Color
char.ThorBall.Handle.Material = data.Material
end
if thrownBall then
thrownBall.Color = data.Color
thrownBall.Material = data.Material
local light = thrownBall:FindFirstChildOfClass("PointLight")
if light then light.Color = data.LightColor end
end
end)
end
changeBtn.MouseButton1Click:Connect(function()
selectorFrame.Visible = not selectorFrame.Visible
end)
local function playSound(id, parent, volume)
local s = Instance.new("Sound")
s.SoundId = id
s.Volume = volume or 2
s.Parent = parent
s:Play()
Debris:AddItem(s, 4)
end
local function addBallVFX(ball, typeName)
local data = BallTypes[typeName]
local light = Instance.new("PointLight", ball)
light.Color = data.LightColor
light.Range = 15
light.Brightness = 3
light.Shadows = true
if typeName == "Flame" then
local f = Instance.new("Fire", ball) f.Size=12 f.Heat=10
local sm = Instance.new("Smoke", ball) sm.Color=Color3.fromRGB(255,100,0) sm.RiseVelocity=2 sm.Size=5
elseif typeName == "Light" then
local pe = Instance.new("ParticleEmitter", ball)
pe.Texture="rbxassetid://1084965043" pe.Color=ColorSequence.new(Color3.fromRGB(255,255,150)) pe.Lifetime=NumberRange.new(0.5) pe.Rate=150 pe.Speed=NumberRange.new(5) pe.Size=NumberSequence.new({NumberSequenceKeypoint.new(0,1), NumberSequenceKeypoint.new(1,0)})
elseif typeName == "Lightning" then
local pe = Instance.new("ParticleEmitter", ball)
pe.Texture="rbxassetid://241650881" pe.Color=ColorSequence.new(Color3.fromRGB(0,255,255)) pe.Lifetime=NumberRange.new(0.3) pe.Rate=200 pe.Speed=NumberRange.new(0)
elseif typeName == "Magma" then
Instance.new("Fire", ball).Size=15
local sm = Instance.new("Smoke", ball) sm.Color=Color3.fromRGB(50,10,0) sm.Size=8
elseif typeName == "Galaxy" or typeName=="Blackhole" or typeName=="Dragon" then
local pe = Instance.new("ParticleEmitter", ball)
pe.Texture="rbxassetid://1095708" pe.Color=ColorSequence.new(data.LightColor) pe.Lifetime=NumberRange.new(1) pe.Rate=100 pe.Speed=NumberRange.new(3)
end
end
local function applyEffect(pos, model, ballType)
if not model or not model:FindFirstChild("Humanoid") then return end
if Players:GetPlayerFromCharacter(model) or model == player.Character then return end
local data = BallTypes[ballType]
if ballType == "Light" then
playSound(data.SoundHit, model.HumanoidRootPart, 3)
for _,v in pairs(model:GetDescendants()) do if v:IsA("BasePart") then TweenService:Create(v, TweenInfo.new(0.3), {Color=Color3.fromRGB(255,255,150), Material=Enum.Material.Neon}):Play() local hl=Instance.new("Highlight", v) hl.FillColor=Color3.fromRGB(255,255,0) hl.FillTransparency=0.2 end end
task.wait(0.6)
for _,v in pairs(model:GetDescendants()) do if v:IsA("BasePart") then TweenService:Create(v, TweenInfo.new(1), {Transparency=1}):Play() end end
task.wait(1) model:Destroy()
elseif ballType == "Ice" then
playSound(data.SoundHit, model.HumanoidRootPart, 3)
for _,v in pairs(model:GetDescendants()) do if v:IsA("BasePart") then v.Anchored=true v.Color=Color3.fromRGB(100,200,255) v.Material=Enum.Material.Ice end end
task.wait(1.5) model.Humanoid.Health=0
elseif ballType == "Blackhole" then
playSound(data.SoundHit, workspace, 5)
local hole=Instance.new("Part",workspace) hole.Anchored=true hole.CanCollide=false hole.Shape=Enum.PartType.Ball hole.Size=Vector3.new(1,1,1) hole.CFrame=CFrame.new(pos) hole.Color=Color3.fromRGB(0,0,0) hole.Material=Enum.Material.ForceField
TweenService:Create(hole, TweenInfo.new(1), {Size=Vector3.new(20,20,20)}):Play()
for _,v in pairs(workspace:GetPartBoundsInRadius(pos,30)) do local m=v.Parent if m and m:FindFirstChild("Humanoid") and not Players:GetPlayerFromCharacter(m) and m~=player.Character then local hrp=m:FindFirstChild("HumanoidRootPart") if hrp then TweenService:Create(hrp,TweenInfo.new(0.8),{CFrame=CFrame.new(pos)}):Play() task.delay(0.9,function() if m.Parent then m.Humanoid.Health=0 end end) end end end
Debris:AddItem(hole,2)
else
playSound(data.SoundHit, model.HumanoidRootPart, 3)
local exp=Instance.new("Explosion",workspace) exp.BlastRadius=14 exp.BlastPressure=0 exp.Position=pos exp.DestroyJointRadiusPercent=0
model.Humanoid.Health=0
end
end
local function createTool()
if player.Backpack:FindFirstChild("ThorBall") or (player.Character and player.Character:FindFirstChild("ThorBall")) then return end
local tool = Instance.new("Tool")
tool.Name = "ThorBall"
tool.RequiresHandle = true
tool.CanBeDropped = false
local handle = Instance.new("Part")
handle.Name = "Handle"
handle.Shape = Enum.PartType.Ball
handle.Size = Vector3.new(2.8,2.8,2.8)
handle.Color = BallTypes[getgenv().SelectedBallType].Color
handle.Material = BallTypes[getgenv().SelectedBallType].Material
handle.CanCollide = false
handle.Massless = true
handle.Parent = tool
Instance.new("SpecialMesh", handle).MeshType = Enum.MeshType.Sphere
tool.Parent = player.Backpack
tool.Equipped:Connect(function()
changeBtn.Visible = true
end)
tool.Unequipped:Connect(function()
changeBtn.Visible = false
selectorFrame.Visible = false
end)
end
local function makeFloat(ball)
local att = Instance.new("Attachment", ball)
local force = Instance.new("VectorForce", ball)
force.Attachment0 = att
force.Force = Vector3.new(0, ball:GetMass() * workspace.Gravity, 0)
force.RelativeTo = Enum.ActuatorRelativeTo.World
force.Parent = ball
ball.AssemblyAngularVelocity = Vector3.new(0,5,0)
if floatConn then floatConn:Disconnect() end
-- NO SLOW DOWN FLOAT, keep Y level
floatConn = RunService.Heartbeat:Connect(function()
if not ball or not ball.Parent or isReturning then return end
-- keep same Y, no drop
local vel = ball.AssemblyLinearVelocity
-- only correct Y, keep X,Z speed same
if math.abs(vel.Y) > 1 then
ball.AssemblyLinearVelocity = Vector3.new(vel.X, vel.Y * 0.99, vel.Z)
else
ball.AssemblyLinearVelocity = Vector3.new(vel.X, 0, vel.Z)
end
-- enforce constant speed
if ball.AssemblyLinearVelocity.Magnitude < lastSpeed - 5 then
ball.AssemblyLinearVelocity = ball.AssemblyLinearVelocity.Unit * lastSpeed
end
end)
end
local function throwBall()
local char = player.Character
if not char or not char:FindFirstChild("HumanoidRootPart") then return end
if thrownBall then thrownBall:Destroy() end
if floatConn then floatConn:Disconnect() end
if char:FindFirstChild("ThorBall") then char.ThorBall.Handle.Transparency = 1 end
local typeData = BallTypes[getgenv().SelectedBallType]
lastSpeed = typeData.Speed
local ball = Instance.new("Part")
ball.Name = "ThorBall_Thrown"
ball.Shape = Enum.PartType.Ball
ball.Size = Vector3.new(3.2,3.2,3.2)
ball.Color = typeData.Color
ball.Material = typeData.Material
ball.CanCollide = true
ball.CustomPhysicalProperties = PhysicalProperties.new(0.1, 1, 0, 1, 1) -- Elasticity 1 = NO SLOW DOWN
ball.CFrame = char.HumanoidRootPart.CFrame * CFrame.new(0,1.5,-4)
ball.AssemblyLinearVelocity = char.HumanoidRootPart.CFrame.LookVector * typeData.Speed
ball.Parent = workspace
thrownBall = ball
makeFloat(ball)
addBallVFX(ball, getgenv().SelectedBallType)
playSound(typeData.SoundThrow, ball, 2)
local trail = Instance.new("Trail", ball)
trail.Attachment0 = Instance.new("Attachment", ball)
trail.Attachment1 = Instance.new("Attachment", ball)
trail.Attachment1.Position = Vector3.new(0,0.5,0)
trail.Color = ColorSequence.new(typeData.Trail)
trail.Lifetime = 0.7
local debounce=false
ball.Touched:Connect(function(hit)
if isReturning or not hit then return end
if hit:IsDescendantOf(char) then return end
local model=hit.Parent
-- DAMAGE CHECK FIRST
if model:FindFirstChild("Humanoid") and not Players:GetPlayerFromCharacter(model) then
if debounce then return end
debounce=true
local expl=Instance.new("Explosion",workspace) expl.BlastRadius=8 expl.BlastPressure=0 expl.Position=ball.Position expl.DestroyJointRadiusPercent=0
applyEffect(ball.Position, model, getgenv().SelectedBallType)
if floatConn then floatConn:Disconnect() end
ball:Destroy() thrownBall=nil
if char:FindFirstChild("ThorBall") then char.ThorBall.Handle.Transparency=0 end
return
end
-- BOUNCE WITH NO SLOW DOWN
if not debounce then
local normal = (ball.Position - hit.Position).Unit
local vel = ball.AssemblyLinearVelocity
local dot = vel:Dot(normal)
local reflected = vel - (2 * dot * normal)
-- KEEP SAME SPEED
ball.AssemblyLinearVelocity = reflected.Unit * lastSpeed
playSound("rbxassetid://12222030", ball, 1)
end
end)
Debris:AddItem(ball, 30)
end
local function returnBall()
if not thrownBall or isReturning then return end
isReturning=true
if floatConn then floatConn:Disconnect() end
playSound("rbxassetid://12222124", thrownBall, 3)
thrownBall.CanCollide=false
thrownBall.Anchored=true
local char=player.Character
if not char or not char:FindFirstChild("HumanoidRootPart") then isReturning=false return end
local tween=TweenService:Create(thrownBall, TweenInfo.new(0.35, Enum.EasingStyle.Quad), {CFrame=char.HumanoidRootPart.CFrame*CFrame.new(0,1.5,-4)})
tween:Play() tween.Completed:Wait()
if thrownBall then thrownBall:Destroy() thrownBall=nil end
if char:FindFirstChild("ThorBall") then char.ThorBall.Handle.Transparency=0 end
isReturning=false
end
ballBtn.MouseButton1Click:Connect(createTool)
returnBtn.MouseButton1Click:Connect(returnBall)
RunService.Heartbeat:Connect(function()
local char=player.Character
if not char then return end
local t=char:FindFirstChild("ThorBall")
if t and not t:FindFirstChild("ActivatedConn") then
local c=Instance.new("BoolValue", t) c.Name="ActivatedConn"
t.Activated:Connect(function() if not thrownBall then throwBall() end end)
end
end)
createTool()
]])()No comments yet for this script.



