What I mean is that you could delete the model and replace it with a mesh with a script. But to do the mesh you first have to create it in studio.
Ok, I now see what you mean. But, have you already tried this in-game in Roblox Studio? Does it work?
Try breaking it down, combine each n (ex. 10) parts into a union, then recursively call the function that combined them so that it combines another n parts (randomly) and when there’s less than n, make it combine all the parts there, should theoretically work.
I’ve tried that already, It doesnt work.
Very weird, why doesn’t it work using that method? Wrong execution? Errors? Wrong algorithm?
It’s because there a too many polygons.
Oh, makes sense, did you try greedy meshing? Very complex but looks like it’s the only method right now, it works by combining close parts together. Did a quick search to get you some resources and found this, very helpful and made by a Roblox programmer!
The thing is to convert it to one single mesh. I tried to take the whole model and substract it to one part. And then substract that part to another part to get the shape like a single mesh. That works but it takes too much time.
The reason why I want a group of parts as one single part is because I want to apply a texture and detect when a player is touching the model
No
Probably, I guess. I’m relying on the guy who said you could make it a mesh.
That’s where optimization is needed. Unfortunately, I don’t have any other ideas atm so, I can do nothing better than wishing you good luck.
Actually got a small idea, if your “shape” is pre-made then just create it before runtime and when needed, clone it and place it instead of that model thing.
That’s what I meant, I already got this idea before. Sorry…
And here, your union-ing the part and itself, maybe that’s what caused problems?
Ah, no worries, I never saw it and just got it to my mind so said it.
It’s not pre-made. What the script does it’s making a shape made out of vector coordinates which act as vertices. The script makes a grid and fills the space in the perimeter that forms the coordinates, then it creates part for joining every coordinate and then it creates a cylinder for each cooridnate.
This is the whole script without the union async:
local partstable = {}
local players = game.Players
local FillBase = game.ReplicatedStorage.FillBase
local CreateBase = game.ReplicatedStorage.CreateBase
-- Define las coordenadas vectoriales de los vértices del polígono
local vertices = {}
local InitialBase = {}
-- Define el tamaño de las partes que se usarán para rellenar el polígono
local partSize = 1.1
-- Crea una función auxiliar para determinar si un punto está dentro del polígono usando el algoritmo de ray casting
local function isInside(point, verts)
local x = point.X
local z = point.Z
local inside = false
local j = #verts
for i = 1, #verts do
local xi = verts[i].X
local zi = verts[i].Z
local xj = verts[j].X
local zj = verts[j].Z
if (zi > z) ~= (zj > z) and (x < (xj - xi) * (z - zi) / (zj - zi) + xi) then
inside = not inside
end
j = i
end
return inside
end
-- Crea una función auxiliar para crear una parte con una posición y un color dados y añadirla a un modelo dado
local function createPart(position, color, model)
local part = Instance.new("Part")
part.Anchored = true -- Fija la parte en su lugar
part.CanCollide = false
part.Size = Vector3.new(partSize, 7, partSize) -- Establece el tamaño de la parte según la variable partSize
part.Position = position -- Establece la posición de la parte según el argumento position
part.Color = color -- Establece el color de la parte según el argumento color
part.Parent = model -- Añade la parte al modelo según el argumento model
part.Material = Enum.Material.SmoothPlastic
end
-- Crea una función auxiliar para rellenar un perímetro entre coordenadas vectoriales usando partes y luego unirlas para formar una sola unión con bordes suaves
local function fillPerimeter(verticestable)
-- Obtiene los límites del polígono en términos de coordenadas vectoriales
local minX = math.huge
local maxX = -math.huge
local minZ = math.huge
local maxZ = -math.huge
for _, vertex in ipairs(verticestable) do
local x = vertex.X
local z = vertex.Z
minX = math.min(minX, x)
maxX = math.max(maxX, x)
minZ = math.min(minZ, z)
maxZ = math.max(maxZ, z)
end
-- Crea un nuevo modelo para contener las partes que forman el polígono
local model = Instance.new("Model")
model.Name = "Polygon"
model.Parent = workspace
-- Recorre todas las posiciones dentro de los límites y crea una parte si están dentro del polígono
for x = minX, maxX, partSize do -- Incrementa x en incrementos de partSize
for z = minZ, maxZ, partSize do -- Incrementa z en incrementos de partSize
local position = Vector3.new(x + partSize / 2, 0, z + partSize / 2)
if isInside(position,verticestable) then -- Comprueba si la posición está dentro del polígono usando la función isInside()
createPart(position, Color3.new(1, 0.5, 0), model) -- Crea una parte con la posición y un color naranja y la añade al modelo
end
end
end
local thickness = 1.5
-- Loop through the coordinates and create a part for each edge
for i = 1, #verticestable do
-- Get the current coordinate and the next one in the loop or wrap around to the first one
local coordinate1 = verticestable[i]
local coordinate2 = verticestable[i + 1] or verticestable[1]
-- Get the distance and direction between the two coordinates
local distance = (coordinate2 - coordinate1).Magnitude
local direction = (coordinate2 - coordinate1).Unit
-- Create a new part with the given color and thickness
local part = Instance.new("Part", model)
part.Anchored = true
part.CanCollide = false
part.Color = Color3.new(1, 0.5, 0)
part.Size = Vector3.new(thickness, 7, distance)
part.Material = Enum.Material.SmoothPlastic
-- Position and orient the part to match the edge
part.CFrame = CFrame.new(coordinate1, coordinate2) * CFrame.new(0, 0, -distance / 2)
end
for i = 1, #verticestable do
local point = verticestable[i]
local cylinder = Instance.new("Part")
cylinder.Shape = "Cylinder"
cylinder.Anchored = true
cylinder.CanCollide = false
cylinder.Size = Vector3.new(7, thickness, thickness)
cylinder.CFrame = CFrame.new(point) * CFrame.Angles(math.rad(0), math.rad(0), math.rad(90))
cylinder.Parent = model
cylinder.Color = Color3.new(1, 0.5, 0)
cylinder.Material = Enum.Material.SmoothPlastic
end
for i, v in pairs(model:GetChildren()) do
table.insert(partstable,v)
end
end
FillBase.OnServerEvent:Connect(function(player)
local trails = game.Workspace:WaitForChild(player.Name.."Trails")
for i, v in pairs(trails:GetChildren()) do
table.insert(vertices,Vector3.new(v.Position.X, 0, v.Position.Z))
end
fillPerimeter(vertices)
end)
CreateBase.OnServerEvent:Connect(function(player)
local parts = game.Workspace:WaitForChild("InitialBase")
parts:PivotTo(CFrame.new(math.random(-100,100),0,math.random(-100,100)))
for i, v in pairs(parts:GetChildren()) do
table.insert(InitialBase,Vector3.new(v.Position.X * 5, 0, v.Position.Z * 5))
end
fillPerimeter(InitialBase)
player.Character.HumanoidRootPart.CFrame = parts:GetPivot() + Vector3.new(0, 2, 0)
end)
I can’t help you much sadly. I gave you all my ideas and.a
Are you sure you need it to be only 1 part? You could go through a loop through the group, and change the texture of every part in it. To detect if a player is touching the model, maybe use a raycast from the player downwards, detecting every part that the player touches. If the raycast hits a part, and that part’s parent is the group then you can know that the player is standing in the area. Just an idea, so I’m not sure if it will work for you.
Ok, I’ll see if it works, thanks for the idea