To keep this as concise as possible, I will be following the format generated when a post is going to be added.
- What do you want to achieve? Keep it simple and clear!
I’m seeking a CSG implementation that can work live in-experience and keep flickering down to an absolute minimum
- What is the issue? Include screenshots / videos if possible!
The issue is even when I use a map that has been completed converted to all PartOperations via GeometryService and ONLY PartOperation:SubstituteGeometry() is used, the flickering is STILL present.
I’ve tried many different solutions thus far to try to get this to work, I understand that the technology may just really not be there yet for this sort of thing, but I think it’s just a little misleading to claim that the function circumvents flickering, when in reality it seems to start flickering at the same point as flickering would likely start if the service was being used on traditional BaseParts. (replacing via parent, etc)
Video: Watch RobloxStudioBeta_NwGlHzzrtE | Streamable
- What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I’m not really sure what else to try, which is why I’m making this post. I’ll leave the code that utilizes SubstituteGeometry() below, all that you need to know for the map is it is entirely made up of PartOperations with MeshParts excluded of course. I can include that code if it is needed as well.
P.S - Just to be clear, it is 100% SubstituteGeometry() causing the flickering, removing the line of code inside of the for loop makes the flickering stop (which of course, results in no changes to the geometry.)
local mapConversionComplete : BoolValue = workspace:WaitForChild("MapConversionComplete");
print "waiting for the client map generation...";
repeat game:GetService("RunService").RenderStepped:Wait() until mapConversionComplete.Value;
print"READY!";
local findBasePart : MeshPart = workspace.Model:FindFirstChild("leafPileMain", true);
task.wait(5);
local Player : Player = game:GetService("Players").LocalPlayer;
local GeometryService : GeometryService = game:GetService("GeometryService");
local p : RaycastParams = RaycastParams.new();
p.FilterDescendantsInstances = (workspace.Model:GetDescendants());
p.FilterType = Enum.RaycastFilterType.Include;
Player.Character:PivotTo(findBasePart.CFrame * CFrame.new(0, 50, 0));
print "GO TIME!"
task.wait(4);
while true do
print "running!"
local Block = Instance.new("Part");
Block.Anchored = true;
Block.Material = Enum.Material.Grass;
Block.Color = Color3.fromRGB(0, 0, 100);
Block.Transparency = 1;
-- // Get floor being stood on
local r : RaycastResult = workspace:Raycast(Player.Character.HumanoidRootPart.Position + Vector3.new(0, 10, 0), Vector3.new(0, -1, 0).Unit * 5000, p);
if (r) then
if not (r.Instance:IsA("PartOperation")) then task.wait(1); continue; end;
Block.CFrame = CFrame.new(r.Position) * CFrame.new(Random.new():NextNumber(-40, 40), -2, Random.new():NextNumber(-40, 40));
Block.Size = Vector3.new(30, 30, 30);
print(r.Instance);
local results : {PartOperation} = GeometryService:SubtractAsync(r.Instance, {Block}, {SplitApart = false});
print(#results);
for i,v in pairs(results) do
r.Instance:SubstituteGeometry(v);
end
end
Block:Destroy();
task.wait(.5);
end