Run it
Copy the script and paste it into your executor.
Players = :()
RunService = :()
UserInputService = :()
TweenService = :()
Debris = :()
player = Players.LocalPlayer
character = player.Character player.CharacterAdded:()
humanoid = character:()
humanoidRootPart = character:()
camera = .CurrentCamera
Config = {
HandMaxLength = ,
HandSpeed = ,
RetractSpeed = ,
HandStickRadius = ,
LaunchForce = ,
LaunchVerticalBoost = ,
LaunchDuration = ,
StringRadius = ,
StringPulseSpeed= ,
HandSize = .(, , ),
WristSize = .(, , ),
BlueColor = .(, , ),
RedColor = .(, , ),
StringBlueColor = .(, , ),
StringRedColor = .(, , ),
ShootCooldown = ,
DoubleClickWindow = ,
MaxGrabbableSize = ,
GrabWeldStiffness = ,
BobSpeed = ,
BobAmount = ,
}
GrabPack = {
equipped = ,
bobTimer = ,
hands = {
blue = {
active = ,
extended = ,
grabbed = ,
grabTarget = ,
grabOffset = .(),
grabWeld = ,
grabNormal = .(,,),
position = .(),
direction = .(),
wrapPoints = {},
model = ,
= {},
returning = ,
clickCount = ,
clickTimer = ,
lastShotTime = ,
pulseTimer = ,
color = .(, , ),
stringColor = .(, , ),
side = ,
},
red = {
active = ,
extended = ,
grabbed = ,
grabTarget = ,
grabOffset = .(),
grabWeld = ,
grabNormal = .(,,),
position = .(),
direction = .(),
wrapPoints = {},
model = ,
= {},
returning = ,
clickCount = ,
clickTimer = ,
lastShotTime = ,
pulseTimer = ,
color = .(, , ),
stringColor = .(, , ),
side = ,
},
},
backpackModel = ,
gui = ,
}
(parent, size, color, transparency, anchored, cancollide, material)
p = .()
p.Size = size .(,,)
p.Color = color .(,,)
p.Transparency = transparency
p.Anchored = anchored ~= anchored
p.CanCollide = cancollide ~= cancollide
p.Material = material .Material.SmoothPlastic
p.CastShadow =
p.Parent = parent
p
(id, pos, vol, pitch)
p = .()
p.Anchored = ; p.CanCollide =
p.Transparency = ; p.Size = .(,,)
p.Position = pos .()
p.Parent =
s = .(, p)
s.SoundId = id ; s.Volume = vol
s.PlaybackSpeed = pitch
s.RollOffMaxDistance =
s:()
Debris:(p, )
(part, target, dur)
TweenService:(part,
TweenInfo.(dur , .EasingStyle.Quad),
{Transparency = target}
):()
(velocity, duration)
old = humanoidRootPart:()
old old:()
bv = .()
bv.Name =
bv.Velocity = velocity
bv.MaxForce = .(, , )
bv.P =
bv.Parent = humanoidRootPart
Debris:(bv, duration )
()
bv = humanoidRootPart:()
bv bv:()
(handData)
armName = handData.side ==
arm = character:(armName)
arm arm.Position
humanoidRootPart.Position
+ .(handData.side == - , , )
(extraExcludes)
p = RaycastParams.()
excludes = {character}
extraExcludes
_, v (extraExcludes)
.(excludes, v)
p.FilterDescendantsInstances = excludes
p.FilterType = .RaycastFilterType.Exclude
p
()
folder = .()
folder.Name =
folder.Parent =
body = (folder, .(, , ), .(, , ))
trim = (folder, .(, , ), .(, , ))
strap1 = (folder, .(, , ), .(, , ))
strap2 = (folder, .(, , ), .(, , ))
blueHousing = (folder, .(,,), Config.BlueColor)
blueHousing.Shape = .PartType.Ball
blueHousing.Material = .Material.Neon
redHousing = (folder, .(,,), Config.RedColor)
redHousing.Shape = .PartType.Ball
redHousing.Material = .Material.Neon
lightBlue = (folder, .(,,), Config.BlueColor)
lightBlue.Material = .Material.Neon; lightBlue.Shape = .PartType.Ball
lightRed = (folder, .(,,), Config.RedColor)
lightRed.Material = .Material.Neon; lightRed.Shape = .PartType.Ball
GrabPack.backpackModel = {
folder = folder, body = body, trim = trim,
strap1 = strap1, strap2 = strap2,
blueHousing = blueHousing, redHousing = redHousing,
lightBlue = lightBlue, lightRed = lightRed,
}
()
GrabPack.backpackModel
torso = character:() character:()
torso
GrabPack.bobTimer = GrabPack.bobTimer + (/) * Config.BobSpeed
bob = .(GrabPack.bobTimer) * Config.BobAmount
cf = torso.CFrame * .(, bob, )
m = GrabPack.backpackModel
m.body.CFrame = cf
m.trim.CFrame = cf * .(, , )
m.strap1.CFrame = cf * .(-, , -)
m.strap2.CFrame = cf * .( , , -)
m.blueHousing.CFrame = cf * .(-, , -)
m.redHousing.CFrame = cf * .( , , -)
m.lightBlue.CFrame = cf * .(-, -, -)
m.lightRed.CFrame = cf * .( , -, -)
t = ()
blueActive = GrabPack.hands.blue.active
redActive = GrabPack.hands.red.active
m.lightBlue.Transparency = blueActive ( + .(.(t*))*)
m.lightRed.Transparency = redActive ( + .(.(t*))*)
(handData, visible)
handData.model
t = visible
(handData.model.palm, t, )
(handData.model.wrist, t, )
(handData.model.thumb, t, )
(handData.model.forearm, t, )
_, f (handData.model.fingers) (f, t, )
_, k (handData.model.knuckles) (k, t, )
handData.model.visible = visible
handData.model.light
handData.model.light.Enabled = visible
(handData)
folder = .()
folder.Name = handData.side ..
folder.Parent =
palm = (folder, Config.HandSize, handData.color, )
palm.Shape = .PartType.Ball
fingers = {}
_ = ,
.(fingers,
(folder, .(, , ), handData.color, ))
thumb = (folder, .(, , ), handData.color, )
wrist = (folder, Config.WristSize, handData.color, )
forearm = (folder, .(, , ), handData.color, )
knuckles = {}
_ = ,
k = (folder, .(,,), handData.color, )
k.Shape = .PartType.Ball
.(knuckles, k)
core = (folder, .(,,), handData.color, ,
, , .Material.Neon)
core.Shape = .PartType.Ball
light = .()
light.Color = handData.color
light.Brightness =
light.Range =
light.Enabled =
light.Parent = palm
selBox = .()
selBox.LineThickness =
selBox.Color3 = handData.color
selBox.SurfaceTransparency =
selBox.SurfaceColor3 = handData.color
selBox.Visible =
selBox.Parent = folder
handData.model = {
folder = folder,
palm = palm,
fingers = fingers,
thumb = thumb,
wrist = wrist,
forearm = forearm,
knuckles = knuckles,
core = core,
light = light,
selBox = selBox,
visible = ,
}
(handData, )
(handData, dt)
handData.model
pos = handData.position
dir = handData.direction
dir.Magnitude < dir = .(,,-)
cf = .(pos, pos + dir)
handData.model.palm.CFrame = cf
handData.model.wrist.CFrame = cf * .(, , )
handData.model.forearm.CFrame = cf * .(, , )
handData.model.core.CFrame = cf
curl = handData.grabbed
fingerOffsets = {
.(-, , ) * .(curl, , ),
.(-, , ) * .(curl, , ),
.( , , ) * .(curl, , ),
.( , , ) * .(curl, , ),
}
i, f (handData.model.fingers)
f.CFrame = cf * fingerOffsets[i]
handData.model.thumb.CFrame = cf * .(-, , ) * .(, , )
knuckleOffsets = {
.(-, , ),
.(-, , ),
.( , , ),
.( , , ),
}
i, k (handData.model.knuckles)
k.CFrame = cf * knuckleOffsets[i]
handData.pulseTimer = (handData.pulseTimer ) + dt * Config.StringPulseSpeed
pulse = .(.(handData.pulseTimer))
handData.grabbed
handData.model.core.Color = handData.color
handData.model.core.Transparency = + pulse *
handData.model.light.Brightness = + pulse *
handData.model.core.Color = handData.color
handData.model.core.Transparency =
handData.model.light.Brightness =
handData.grabbed handData.grabTarget
handData.model.selBox.Adornee = handData.grabTarget
handData.model.selBox.Visible =
handData.model.selBox.Visible =
(handData)
_, seg (handData.string)
seg seg.Parent seg:()
handData.string = {}
(handData, dt)
(handData)
handData.active
folder = handData.model handData.model.folder
origin = (handData)
points = {origin}
_, wp (handData.wrapPoints)
.(points, wp.position)
.(points, handData.position)
handData.pulseTimer = (handData.pulseTimer ) + (dt ) * Config.StringPulseSpeed
pulseAlpha = + .(.(handData.pulseTimer)) *
pulseColor = handData.stringColor:(.(,,), pulseAlpha * )
i = , #points -
p1, p2 = points[i], points[i+]
dist = (p2 - p1).Magnitude
dist <
seg = .()
seg.Size = .(Config.StringRadius*, Config.StringRadius*, dist)
seg.CFrame = .((p1+p2)/, p2)
seg.Color = pulseColor
seg.Anchored = ; seg.CanCollide =
seg.Material = .Material.Neon; seg.CastShadow =
seg.Parent = folder
.(handData.string, seg)
(handData, oldPos, newPos)
params = (handData.model {handData.model.folder} )
dir = newPos - oldPos
dir.Magnitude < ,
result = :(oldPos, dir, params)
result
wrapPos = result.Position + result.Normal *
.(handData.wrapPoints, {
position = wrapPos,
normal = result.Normal,
instance = result.Instance,
})
, result.Position
,
(handData)
#handData.wrapPoints ==
origin = (handData)
lastWrap = handData.wrapPoints[#handData.wrapPoints]
prevPos = #handData.wrapPoints >
handData.wrapPoints[#handData.wrapPoints - ].position
origin
(handData.position - prevPos).Magnitude
< (handData.position - lastWrap.position).Magnitude *
.(handData.wrapPoints, #handData.wrapPoints)
(handData)
params = (handData.model {handData.model.folder} )
unitRay = camera:(
camera.ViewportSize.X / ,
camera.ViewportSize.Y /
)
result = :(
unitRay.Origin,
unitRay.Direction * Config.HandMaxLength,
params
)
result
result.Position + result.Normal * , result.Instance, result.Normal
spread =
offsets = {
.( spread, , ), .(-spread, , ),
.(, spread, ), .(, -spread, ),
.( spread, spread, ), .(-spread, -spread, ),
}
_, off (offsets)
tweakedDir = (unitRay.Direction + off).Unit * Config.HandMaxLength
r2 = :(unitRay.Origin, tweakedDir, params)
r2
r2.Position + r2.Normal * , r2.Instance, r2.Normal
unitRay.Origin + unitRay.Direction * Config.HandMaxLength, ,
(handData)
inst = handData.targetInstance
inst
inst:()
inst:(character)
sz = inst.Size
sz.X > Config.MaxGrabbableSize
sz.Y > Config.MaxGrabbableSize
sz.Z > Config.MaxGrabbableSize
handData.grabbed =
handData.grabTarget = inst
handData.grabNormal = handData.targetNormal .(,,)
handData.grabOffset = inst.CFrame:(.(handData.position))
(, handData.position, , )
(handData)
handData.grabWeld
handData.grabWeld:()
handData.grabWeld =
handData.extended =
handData.grabbed =
handData.grabTarget =
handData.returning =
handData.model
handData.model.selBox.Visible =
(, handData.position, , )
(handData)
handData.grabbed
target = handData.position
dir = (target - humanoidRootPart.Position)
dir.Magnitude <
launchDir = (dir.Unit
+ .(, Config.LaunchVerticalBoost / Config.LaunchForce, )).Unit
(launchDir * Config.LaunchForce, Config.LaunchDuration)
(, humanoidRootPart.Position, , )
.(Config.LaunchDuration + , ()
(handData)
)
handData.clickCount =
(handData)
now = ()
now - (handData.lastShotTime ) < Config.ShootCooldown
handData.active
handData.clickCount = handData.clickCount +
handData.clickTimer =
handData.clickCount >= handData.grabbed
(handData)
handData.grabbed
(handData)
handData.active =
handData.extended =
handData.grabbed =
handData.returning =
handData.wrapPoints = {}
handData.clickCount =
handData.clickTimer =
handData.lastShotTime = now
targetPos, targetInst, targetNormal = (handData)
handData.targetPos = targetPos
handData.targetInstance = targetInst
handData.targetNormal = targetNormal .(, , )
origin = (handData)
handData.position = origin
handData.direction = (targetPos - origin).Unit
handData.distance =
(handData, )
(, origin, , + .() * )
(handData, dt)
handData.active
origin = (handData)
handData.returning
target = #handData.wrapPoints >
handData.wrapPoints[#handData.wrapPoints].position
origin
moveDir = target - handData.position
moveDist = moveDir.Magnitude
moveDist <
#handData.wrapPoints >
.(handData.wrapPoints, #handData.wrapPoints)
handData.active =
handData.extended =
handData.returning =
handData.grabbed =
handData.clickCount =
handData.wrapPoints = {}
(handData, )
(handData)
step = .(Config.RetractSpeed * dt, moveDist)
handData.position = handData.position + moveDir.Unit * step
handData.direction = moveDir.Unit
handData.grabbed
handData.grabTarget handData.grabTarget.Parent
handData.grabTarget.Anchored
worldGrabPos = handData.grabTarget.CFrame
* handData.grabOffset
handData.position = worldGrabPos.Position
(handData)
(handData)
targetPos = handData.targetPos
moveDir = targetPos - handData.position
moveDist = moveDir.Magnitude
oldPos = handData.position
step = .(Config.HandSpeed * dt, moveDist)
newPos = handData.position
+ (moveDist > moveDir.Unit * step .())
wrapped, wrapPos = (handData, oldPos, newPos)
handData.position = wrapped (wrapPos newPos) newPos
moveDist >
handData.direction = moveDir.Unit
moveDist <= Config.HandStickRadius
handData.extended =
handData.position = targetPos
(handData)
.(, ()
handData.active handData.grabbed
(handData)
)
(handData.position - origin).Magnitude >= Config.HandMaxLength
handData.extended =
handData.grabbed
.(, ()
handData.active handData.grabbed
(handData)
)
(dt)
_, h (GrabPack.hands)
h.clickTimer < Config.DoubleClickWindow
h.clickTimer = h.clickTimer + dt
()
sg = .()
sg.Name =
sg.ResetOnSpawn =
sg.IgnoreGuiInset =
sg.Parent = player.PlayerGui
panel = .(, sg)
panel.Size = .(, , , )
panel.Position = .(, -, , -)
panel.BackgroundColor3 = .(, , )
panel.BackgroundTransparency =
panel.BorderSizePixel =
.(, panel).CornerRadius = .(, )
stroke = .(, panel)
stroke.Color = .(,,); stroke.Thickness = ; stroke.Transparency =
(color, x, label, keyText)
btn = .(, panel)
btn.Size = .(, , , ); btn.Position = .(, x, , )
btn.BackgroundColor3 = color; btn.Text = ; btn.BorderSizePixel =
.(, btn).CornerRadius = .(, )
title = .(, btn)
title.Size = .(,,,); title.Position = .(,,,)
title.BackgroundTransparency = ; title.Text = label
title.TextColor3 = .(,,); title.TextScaled =
title.Font = .Font.GothamBold
status = .(, btn)
status.Name = ; status.Size = .(,,,)
status.Position = .(,,,)
status.BackgroundTransparency = ; status.Text =
status.TextColor3 = .(,,); status.TextScaled =
status.Font = .Font.Gotham
coolBar = .(, btn)
coolBar.Name = ; coolBar.Size = .(,,,)
coolBar.Position = .(,,,-)
coolBar.BackgroundColor3 = .(,,); coolBar.BorderSizePixel =
coolBar.BackgroundTransparency =
.(, coolBar).CornerRadius = .(,)
keyLbl = .(, panel)
keyLbl.Size = .(,,,); keyLbl.Position = .(,x,,-)
keyLbl.BackgroundTransparency = ; keyLbl.Text = keyText
keyLbl.TextColor3 = color:(.(,,),)
keyLbl.TextScaled = ; keyLbl.Font = .Font.GothamBold
btn, status, coolBar
blueBtn, blueStatus, blueCool = (Config.BlueColor, , , )
redBtn, redStatus, redCool = (Config.RedColor, , , )
ch = .(, sg)
ch.Name = ; ch.Size = .(,,,)
ch.Position = .(,-,,-); ch.BackgroundTransparency =
(sz, pos)
f = .(, ch)
f.Size = sz; f.Position = pos
f.BackgroundColor3 = .(,,); f.BorderSizePixel =
f
(.(,,,), .(,,,-))
(.(,,,), .(,-,,))
chDot = .(, ch)
chDot.Size = .(,,,); chDot.Position = .(,-,,-)
chDot.BackgroundColor3 = .(,,); chDot.BorderSizePixel =
.(, chDot).CornerRadius = .(,)
chRing = .(, ch)
chRing.Name = ; chRing.Size = .(,,,)
chRing.Position = .(,-,,-)
chRing.BackgroundTransparency = ; chRing.BorderSizePixel =
.(, chRing).CornerRadius = .(,)
rs = .(, chRing)
rs.Thickness = ; rs.Color = .(,,); rs.Transparency =
instr = .(, sg)
instr.Size = .(,,,); instr.Position = .(,-,,-)
instr.BackgroundTransparency =
instr.Text =
instr.TextColor3 = .(,,); instr.TextScaled =
instr.Font = .Font.Gotham
GrabPack.gui = {
screen = sg,
panel = panel,
blueBtn = blueBtn,
redBtn = redBtn,
blueStatus = blueStatus,
redStatus = redStatus,
blueCool = blueCool,
redCool = redCool,
chRing = chRing,
}
(dt)
GrabPack.gui
now = ()
gui = GrabPack.gui
(h, btn, statusLbl, coolBar)
h.grabbed
statusLbl.Text = ; btn.BackgroundTransparency =
h.extended
statusLbl.Text = ; btn.BackgroundTransparency =
h.active
statusLbl.Text = ; btn.BackgroundTransparency =
statusLbl.Text = ; btn.BackgroundTransparency =
elapsed = .((now - (h.lastShotTime )) / Config.ShootCooldown, , )
TweenService:(coolBar,
TweenInfo.(, .EasingStyle.Linear),
{Size = .(elapsed, , , )}
):()
(GrabPack.hands.blue, gui.blueBtn, gui.blueStatus, gui.blueCool)
(GrabPack.hands.red, gui.redBtn, gui.redStatus, gui.redCool)
rs = gui.chRing:()
rs
GrabPack.hands.blue.grabbed
rs.Color = Config.BlueColor
GrabPack.hands.red.grabbed
rs.Color = Config.RedColor
GrabPack.hands.blue.active
rs.Color = Config.BlueColor:(.(,,), )
GrabPack.hands.red.active
rs.Color = Config.RedColor:(.(,,), )
rs.Color = .(,,)
()
gui = GrabPack.gui
gui.blueBtn.MouseButton1Click:(()
(GrabPack.hands.blue)
)
gui.redBtn.MouseButton1Click:(()
(GrabPack.hands.red)
)
UserInputService.InputBegan:((input, processed)
processed
kc = input.KeyCode
kc == .KeyCode.Q
(GrabPack.hands.blue)
kc == .KeyCode.E
(GrabPack.hands.red)
kc == .KeyCode.R
(GrabPack.hands.blue)
(GrabPack.hands.red)
)
()
()
(GrabPack.hands.blue)
(GrabPack.hands.red)
()
()
GrabPack.equipped =
()
()
()
()
()
RunService.RenderStepped:((dt)
GrabPack.equipped
character character.Parent
()
_, h (GrabPack.hands)
(h, dt)
h.active
(h, dt)
(h, dt)
(dt)
(dt)
)
player.CharacterRemoving:(()
GrabPack.equipped =
()
GrabPack.backpackModel
GrabPack.backpackModel.folder:()
_, h (GrabPack.hands)
(h)
h.model h.model.folder:()
GrabPack.gui GrabPack.gui.screen:()
)
()
Controls: InputAction Q or Blue ButtonShoot/control blue hand E or Red ButtonShoot/control red handPress once (extended) Retract handPress twice (grabbed) Launch to target

Universal