I’m trying to achieve some realistic destruction , similar to rainbow six siege or other games similar, where you can shoot / knife a wall and it’ll create a little hole you can peek through and shoot from.
I’m trying this using csg and it’s going really odd. for some reason it’s just really slow and not as efficent.
are there other methods I can use to achieve realistic destruction?
if hitPart and isWood(hitPart) then
local original = hitPart
local originalCF = original.CFrame
local hitPos = hitPoint or original.Position
if not (original:IsA("Part") or original:IsA("UnionOperation") or original:IsA("MeshPart")) then
warn("Hit part is not a valid target :", original.ClassName)
return
end
--small point to make hole
local sphere = Instance.new("Part")
sphere.Shape = Enum.PartType.Ball
sphere.Size = Vector3.new(0.8, 0.8, 0.8)
sphere.CFrame = CFrame.new(hitPos)
sphere.Anchored = true
sphere.CanCollide = false
sphere.Transparency = 1
sphere.Name = "CraterSphere"
sphere.Parent = workspace
game:GetService("Debris"):AddItem(sphere,0.4)
task.wait()
local options = {
CollisionFidelity = Enum.CollisionFidelity.PreciseConvexDecomposition,
RenderFidelity = Enum.RenderFidelity.Automatic,
SplitApart = true,
}
-- CSG subtract crater from the wood part
local success, result = pcall(function()
return GeometryService:SubtractAsync(original, {sphere},options)
end)
if success and result and #result > 0 then
for _, part in ipairs(result) do
end
original:SubstituteGeometry(result[1])
task.wait(0.09)
sphere:Destroy()
else
warn(" Reason---- ", result)
end
sphere:Destroy()
end
is this on the server or client?
try repalcing local sphere = Instance.new("Part") with premade parts
and remove every task.wait(...) i don’t think you really need them they only seem to slow your code or simulate lag ?
I mean, CSG (unions) are pretty slow to begin with, even when editing in studio. (and imprecise too)
have you tried turning the wall into voxels upon hit, and replace affected ones with premade debris?
I thought this was lag or something wrong with the code, but yeah “pretty slow” maybe there is still something wrong with the code for it to be > than 2 seconds, but still.
local start = os.clock()
local success, result = pcall(function()
return GeometryService:SubtractAsync(original, {sphere},options)
end)
print(os.clock() - start)
or maybe create thin layers of wood and use Enum.CollisionFidelity.Default the code a bit faster ( but I don’t think will be better for long term performance )
Video for Enum.CollisionFidelity.Default Speed difference
3rd way (layers of wood)
the code I used if you want it
local DestroyAfter = game:GetService("Debris")
local GeometryService = game:GetService("GeometryService")
local plr = game.Players.LocalPlayer
local char = plr.Character
local camera = workspace.CurrentCamera
local mouse = plr:GetMouse()
local rayParams = RaycastParams.new()
rayParams.FilterType = Enum.RaycastFilterType.Exclude
rayParams.FilterDescendantsInstances = {char}
local cached = {}
function CreateSphares(count)
local storage = Instance.new("Folder")
storage.Parent = workspace
for i=1,count do
local sphere = Instance.new("Part")
sphere.Shape = Enum.PartType.Ball
sphere.Size = Vector3.one *1.5
sphere.CFrame = CFrame.new(Vector3.new(0,5000,0))
sphere.Anchored = true
sphere.CanCollide = true
sphere.Transparency = 1
sphere.Name = "CraterSphere"
sphere.Parent = storage
table.insert(cached,sphere)
end
end
function GetSphare()
local sphare = cached[#cached]
cached[#cached] = nil
return sphare
end
function StartFiring()
local CamCF = camera.CFrame
local newRay = workspace:Raycast(
CamCF.Position,
CamCF.LookVector * 50,
rayParams
)
if not newRay then return end
local hitPart = newRay.Instance
--print(hitPart)
if hitPart then
local original = hitPart
local originalCF = original.CFrame
local hitPos = newRay.Position
-- [!]
local sphere = GetSphare()
sphere.Transparency = 1
sphere.CFrame = CFrame.new(hitPos)
local options = {
CollisionFidelity = Enum.CollisionFidelity.Default,
RenderFidelity = Enum.RenderFidelity.Automatic,
SplitApart = true,
}
-- CSG subtract crater from the wood part
local start = os.clock()
local success, result = pcall(function()
return GeometryService:SubtractAsync(original, {sphere},options)
end)
print(string.sub(os.clock() - start,1,5).."s")
--print(success,result)
if success and result then
for i,newPart: PartOperation in result do
newPart.Parent = original.Parent
newPart.CFrame = original.CFrame
newPart.Anchored = original.Anchored
end
original.Parent = nil
original:Destroy()
for _, otherPart in pairs({sphere}) do
otherPart.Parent = nil
otherPart:Destroy()
end
end
end
end
CreateSphares(100)
mouse.Button1Down:Connect(function()
StartFiring()
end)
Note that if you use layers of wood, you might need to do precise (concave) collision on each layer separately or something… which can be slow…
(in fact, concave collision is slowest type I think… and is correlated to the amount of triangles (I think, I could be wrong) so more holes = slower)
Union speed is also correlated to the amount of triangles intersecting, that’s why thinner layers are faster.
but may not be highly accurate, especially for holes, doorways, and cavities in general.
oh yeah you’re correct, didn’t see it.
OP has to give up something up to gain performance anyway, they can try it in their game and if it doesn’t fit ( or need more accuracy ) they will have to think of another way.
or try this one
hmm maybe, i like the plates of wood idea, should I switch to just negative unions instead of csg? also Im trying to go for more realistic looking destruction
If you want a more complicated shape for the hole via the union method, instead of doing instance.new you can do template:Clone() (you can make a custom negative union(s) to your desired detail, although more triangles are correlated with a slower union operation.)
you don’t have to make it realistic when destructing the wall but after.
for now just focus on making it work and performant then add the “realistic” part .I.E. Effects / Textures / Dust / Sounds and so on
Update : I created my own destruction system with indepth calculations. I got really over the top on this when theres probably some simpler one out there… It doesnt have the voxel features although but here it is.