--[[Created by agent767, give me credit or not.
How to use:
Place everything you want to be fragmentable in a Model in Workspace that is named "Fragmentable"
To start the Fragmentation create an Explosion and parent it to the Workspace.
To create a "fakeexplosion" create a Vector3Value and a NumberValue.
Name the NumberValue "Radius" and parent it to the Vector3Value.
Then Change the Value of the Vector3Value to the position of the fakeexplosion and the Value of the NumberValue to the fakeexplosion-radius.
After that just parent the Vector3Value to this script.
]]
local minimumsize = Vector3.new(1.6,1.15,1.6) --Minimumsize for a part to get divided,higher numbers = less detailed and bigger/less bricks
local surface_between_splitted_parts = Enum.SurfaceType.Universal --the surface between splitted parts
--local fragmented = workspace:FindFirstChild("Fragmented")
local fragmentable = workspace:FindFirstChild("Fragmentable") --all fragmentable objects should be stored in here
local list = {}
local brickcount = 0
--local m = Instance.new("Hint",workspace)
local storage = {}
local fillup = 1000 --it constantly generates new parts until it reaches this number(hacky way to prevent lagspikes if there is a large explosion),change it to 0 if you don�t want it to generate (useless) parts.
local maximumstorage = 2000 --it will recycle parts if the number of parts in the storage doesnt exceed this number
local storage_position = Vector3.new(0,0,5000) --place them somewhere off the map
local stored_partsize = Vector3.new(1,1,1) --make them small
local parts_created_per_frame = 5 --number of parts being created per frame to fill up the storage
function fragmentate(cframe,size,color,explosion_position,explosion_blastradius,backsurface,bottomsurface,frontsurface,leftsurface,rightsurface,topsurface,transparency,reflectance,mat)
local xi = size.X >= minimumsize.X*(1+explosion_blastradius/16) and 2 or 1 --to reduce the lagg in large explosions we increase minimumsize based on the explosionradius...
local yi = size.Y >= minimumsize.Y*(1+explosion_blastradius/16) and 2 or 1
local zi = size.Z >= minimumsize.Z*(1+explosion_blastradius/16) and 2 or 1
if xi == 1 and yi == 1 and zi == 1 or (cframe.p-explosion_position).magnitude > size.magnitude/2 + explosion_blastradius then --don�t fragmentate parts, that are too small to fragmentate or too far away from the explosion
if xi == 1 and yi == 1 and zi == 1 then return end --optional
if #storage > 0 then
local p = storage[1]
p.BrickColor = color
p.Size = size
p.BackSurface = backsurface
p.BottomSurface = bottomsurface
p.FrontSurface = frontsurface
p.LeftSurface = leftsurface
p.RightSurface = rightsurface
p.TopSurface = topsurface
p.Transparency = transparency
p.CFrame = cframe
p.Material = mat
p.Reflectance = reflectance
table.remove(storage,1)
else
local p = Instance.new("Part",fragmentable)
p.BrickColor = color
p.Anchored = true
p.FormFactor = "Custom"
p.Size = size
p.BackSurface = backsurface
p.BottomSurface = bottomsurface
p.FrontSurface = frontsurface
p.LeftSurface = leftsurface
p.RightSurface = rightsurface
p.TopSurface = topsurface
p.Material = mat
p.Transparency = transparency
p.CFrame = cframe
p.Reflectance = reflectance
end
--p:MakeJoints()
-- m.Text = m.Text+1
return --stop the function
end
local mody = math.random(-125,125)/1000 --some randomization
for y = 1,yi do
if math.random()> 0.5 then
local modx = math.random(-125,125)/1000
for x = 1,xi do
local modz = math.random(-125,125)/1000
for z = 1,zi do --offset = x/xi-0.75+modx)
fragmentate(cframe*CFrame.new(size.X*(xi==1 and 0 or x/xi-0.75+modx),size.Y*(yi==1 and 0 or y/yi-0.75+mody),size.Z*(zi==1 and 0 or z/zi-0.75+modz)), --maths
Vector3.new(xi == 2 and size.X*(1-2*math.abs(x/xi-0.75+modx)) or size.X,yi == 2 and size.Y*(1-2*math.abs(y/yi-0.75+mody)) or size.Y,
zi == 2 and size.Z*(1-2*math.abs(z/zi-0.75+modz)) or size.Z or agent767_was_here),color,explosion_position,explosion_blastradius,
z~=zi and surface_between_splitted_parts or backsurface,y==2 and surface_between_splitted_parts or bottomsurface,
z==2 and surface_between_splitted_parts or frontsurface,x==2 and surface_between_splitted_parts or leftsurface,x~=xi and surface_between_splitted_parts or rightsurface,
y~=yi and surface_between_splitted_parts or topsurface,transparency,reflectance)
end
end
else
local modz = math.random(-125,125)/1000
for z = 1,zi do
local modx = math.random(-125,125)/1000
for x = 1,xi do
fragmentate(cframe*CFrame.new(size.X*(xi==1 and 0 or x/xi-0.75+modx),size.Y*(yi==1 and 0 or y/yi-0.75+mody),size.Z*(zi==1 and 0 or z/zi-0.75+modz)),
Vector3.new(xi == 2 and size.X*(1-2*math.abs(x/xi-0.75+modx)) or size.X,yi == 2 and size.Y*(1-2*math.abs(y/yi-0.75+mody)) or size.Y,
zi == 2 and size.Z*(1-2*math.abs(z/zi-0.75+modz)) or size.Z),color,explosion_position,explosion_blastradius,
z~=zi and surface_between_splitted_parts or backsurface,y==2 and surface_between_splitted_parts or bottomsurface,
z==2 and surface_between_splitted_parts or frontsurface,x==2 and surface_between_splitted_parts or leftsurface,x~=xi and surface_between_splitted_parts or rightsurface,
y~=yi and surface_between_splitted_parts or topsurface,transparency,reflectance)
end
end
end
end
end
function start_fragmentation(position,radius)
local search = Region3.new(position-Vector3.new(radius,radius,radius)*1.1,position+Vector3.new(radius,radius,radius)*1.1)
repeat
local finish = false
local parts = workspace:FindPartsInRegion3WithIgnoreList(search,list,100) --maximum number of parts that FindPartsInRegion3 can find is 100, so we have to do this to find them all
for i = 1,#parts do
table.insert(list,1,parts[i])
end
finish = true
until #parts < 100 and finish
print(#list)
local t = tick()
for i = 1,#list do
local p = list[i]
if p:IsDescendantOf(fragmentable) then
fragmentate(p.CFrame,p.Size,p.BrickColor,position,radius,p.BackSurface,p.BottomSurface,p.FrontSurface,p.LeftSurface,p.RightSurface,p.TopSurface,p.Transparency,p.Reflectance,p.Material)
if #storage < maximumstorage and p.Shape == "Block" then --recycle them
p.Anchored = true
p.FormFactor = "Custom"
p.Size = stored_partsize
p.Position = storage_position
table.insert(storage,1,p)
else --storage is full
p:Destroy()
end
-- m.Text = m.Text-1
end
end
list = {}
-- print(tick()-t)
end
workspace.ChildAdded:connect(function(thing)
if thing and thing.ClassName == "Explosion" then
start_fragmentation(thing.Position,thing.BlastRadius)
end
end)
script.ChildAdded:connect(function(thing)
if thing and thing.ClassName == "Vector3Value" and thing:FindFirstChild("Radius") then
start_fragmentation(thing.Value,thing.Radius.Value)
wait()
thing:Destroy()
end
end)
while wait() do --oh noes,a loop! So inefficient!
if #storage < fillup then
for i = 1, parts_created_per_frame do --creates parts to fill up the storage
local p = Instance.new("Part",fragmentable)
p.Anchored = true
p.FormFactor = "Custom"
p.Size = stored_partsize
p.Position = storage_position
table.insert(storage,1,p)
end
end
end
i use agent767 script
20:12:19.125 tin_nim - Server - CrowbarScript:3
20:12:19.125 5 - Server - Fragmentation_Script:111
20:12:19.125 Invalid value for enum Material - Server - Fragmentation_Script:44
20:12:19.125 Stack Begin - Studio
20:12:19.126 Script ‘Workspace.Fragmentation_Script’, Line 44 - function fragmentate - Studio - Fragmentation_Script:44
20:12:19.126 Script ‘Workspace.Fragmentation_Script’, Line 89 - function fragmentate - Studio - Fragmentation_Script:89
20:12:19.126 Script ‘Workspace.Fragmentation_Script’, Line 116 - function start_fragmentation - Studio - Fragmentation_Script:116
20:12:19.126 Script ‘Workspace.Fragmentation_Script’, Line 135