How would I be able to create a sphere of polygons?

Hello, I’d like to create a kind of shield around the player made of polygons / parts, something like this:

image

3D though, and I have no idea how I’d be able to do this inside a script and still be able to get each one of the faces of the shield, as my purpose for this would be so that each one of the faces would have its own “durability”.

Other references:

image

image

The references are mainly to help you understand what I’m asking and for visuals.

Thanks for the attention!

2 Likes

I guess you would have one instance of the faces and clone and position them in a spherical shape using trigonometry functions to get the position from spherical coordinates (radial distance, polar angle, and azimuthal angle).

  • Any oddities are the fault of Google Translator
  • Everything in this post is just an idea, not a full and high-quality implementation

I agree with @socean’s answer. It’s just that there is also the possibility of implementing the faces of a polygon (polygon), through trigonometric functions.

To do this, you only need the formula for obtaining the coordinates of the n-gon

function Polygon:_get_points_of_polygon(n,r) 
		local points = {}
		for i = 1,n do
			table.insert(points,Vector2.new(r* math.cos(2 * math.pi * i / n),r *math.sin(2 * math.pi * i / n)))
		end
		return  points
	end

And of course safely paint it all
Of course, it is possible that I cheated a little with the painting of the polygon, but let it remain an idea, and an incomplete implementation


function Polygon:_create_line(Vec1,Vec2,Width,Lenght,Parent)
		Width=Width or 0.2;Lenght=Lenght or 0.2
		return _create({"Part",Parent= Parent or workspace,Anchored = true,Shape = Enum.PartType.Block,
			Size = Vector3.new(Width,(Vec1-Vec2).Magnitude,Lenght),
			["CFrame"] = CFrame.new( 
				Vec1:Lerp(Vec2,1/2),
				Vec2	
			)*CFrame.Angles(math.pi/2,0,0),Name=Polygon.NAMES.LINE
		})
	end

Code example:

local _create=setmetatable({},{ __call = function(tab,props)
	local Object = Instance.new(props[1] or props["ClassName"])
	for Property,Value in pairs(props) do
		if Property~= "ClassName" and Property~=1 then
			Object[Property] = Value
		end
	end return Object end  })  

local Polygon = {} do
	Polygon.NAMES = {
		POLYGON = "PolygonModel",
		LINE = "PolygonPart",
		PRIMARYPART= "PolygonPrimaryPart",
		CENTER = "Center"
	}
	Polygon.METAINDEXES = {
		POSITION = "Position",
		CFRAME = "CFrame",
	}
	
	function Polygon:_create_line(Vec1,Vec2,Width,Lenght,Parent)
		Width=Width or 0.2;Lenght=Lenght or 0.2
		return _create({"Part",Parent= Parent or workspace,Anchored = true,Shape = Enum.PartType.Block,
			Size = Vector3.new(Width,(Vec1-Vec2).Magnitude,Lenght),
			["CFrame"] = CFrame.new( 
				Vec1:Lerp(Vec2,1/2),
				Vec2	
			)*CFrame.Angles(math.pi/2,0,0),Name=Polygon.NAMES.LINE
		})
	end
	function Polygon:_get_points_of_polygon(n,r) 
		local points = {}
		for i = 1,n do
			table.insert(points,Vector2.new(r* math.cos(2 * math.pi * i / n),r *math.sin(2 * math.pi * i / n)))
		end
		return  points
		
	end
	function Polygon.new(N,R,WidthLine,LenghtLine,Parent) -- N - Number of vertices; R - radius
		----
		Parent=Parent or workspace
		---
		local self = {
			Model = _create({"Model",Name=Polygon.NAMES.POLYGON,Parent=Parent})
		}
		self.PrimaryPart = _create({"Part",Anchored = true,Shape=Enum.PartType.Block,
			Size = Vector3.new(R,1,R),Transparency=1,
			Position = Vector3.new(nil),Name=Polygon.NAMES.PRIMARYPART,Parent=self.Model});self.Model.PrimaryPart =self.PrimaryPart
		self.AllLines = {}
		self.AllPoints = Polygon:_get_points_of_polygon(N,R)
		self.Center=nil
		self.Suburbs ={}
		for Number,_ in ipairs(self.AllPoints) do
			if self.AllPoints[Number+1] then
				table.insert(self.AllLines,Polygon:_create_line(Vector3.new(self.AllPoints[Number].X,0,self.AllPoints[Number].Y),Vector3.new(self.AllPoints[Number+1].X,0,self.AllPoints[Number+1].Y),WidthLine,LenghtLine,self.Model))
			else
				table.insert(self.AllLines,Polygon:_create_line(Vector3.new(self.AllPoints[1].X,0,self.AllPoints[1].Y),Vector3.new(self.AllPoints[Number].X,0,self.AllPoints[Number].Y),WidthLine,LenghtLine,self.Model ))
			end
		end
		-------Center Polygon(Painting)
		self.Center= _create({"Part",
			Shape=Enum.PartType.Cylinder,
			Anchored=true,
			Orientation = Vector3.new(0,0,90),
			Size=Vector3.new(0.2,R*(math.pi/2),R*(math.pi/2)),
			Parent=self.Model,
			Name = Polygon.NAMES.CENTER,
			Position=self.PrimaryPart.Position
		})
		for _,obj in ipairs(self.AllLines) do
			table.insert(self.Suburbs,_create({"Part",
				Shape=Enum.PartType.Block,
				Anchored=true,
				Size=Vector3.new(R/2,obj.Size.Y,0.2),
				Parent=self.Model,
				Name = Polygon.NAMES.CENTER,
				CFrame=CFrame.fromMatrix(obj.CFrame.Position/1.5,obj.CFrame.XVector,obj.CFrame.YVector,obj.CFrame.ZVector)
			}))
		end
		-------
		return setmetatable(self,{
			__tostring=function()return "Polygon" end,
			__newindex = function(t,k,v)
				if k==Polygon.METAINDEXES.CFRAME then
					t.Model:SetPrimaryPartCFrame(v)
				end
				if k==Polygon.METAINDEXES.POSITION then
					t.Model:MoveTo(v)
				end
			end
		})
	end
end

Notes to the sample code:

To create a polygon model with n-vertices of r-radius, you can use the Polygon class constructor

Polygon.new(5,2) ---5 Vertexes with radius 2 studs

There are also additional arguments to this function

 Polygon.new([[Number of vertices]],[[Radius]] ,[[Polygon Line Width]], [[Polygon line length]],[[Polygon model parents]])

An object of the Polygon class has attributes:

PrimaryPart -- Primary Part of the model
AllLines -- Contours of the model
AllPoints -- Vector 2 coordinates of points
Center -- Central cylinder
Suburbs -- The inner edges of the polygon (they cover the holes)
3 Likes

Just use “add” in blender, insert a sphere and use bevel then export it and use it on a meshpart

2 Likes

There is a clever trick for doing this in blender, using instancing. I used it to make a circle of crystals, but this is possible as well. Start by making the “panel.” parent it to a sphere with suitable low resolution (I think it’s isosphere, I can look it up). Turn on instances in the sphere. Apply those instances “make instances real” then delete the sphere.

I’ll be back at my computer in a bit. I’ll give myself 5 minutes to build something and load it into Roblox, for giggles.

1 Like

I forgot to scale it, so it took a little longer than 5 minutes to get it all in the screen.

This is the secret right here! In the sphere’s properties. “Align to Vertex Normal” should probably be checked for this.
image

That was fun, so I took a little more time to do it right!

1 Like

Of course, it is possible, as it was noted earlier, it is best to convert the polygon into mesh, otherwise it may lead to lags

To implement a sphere from polygons, you can use the formula for converting spherical to Cartesian coordinates

Radius = 3
for X = 0,180 do
	for Z = 0,360 do
		if (X - math.floor(X/10)*10)==0 and (Z - math.floor(Z/10)*10)==0 then
			local pol = Polygon.new(5,0.2,0.1,0.1)
				
			pol.CFrame	=CFrame.new(Vector3.new(
Radius*math.sin(Z)*math.sin(X),
Radius*math.cos(X),
Radius*math.cos(Z)*math.sin(X)
),Vector3.new(0,0,0))*CFrame.Angles(math.rad(90),0,0)+Vector3.new(0,2.5,0)
			
		end
	end
end

1 Like

Wait do you want the script for the durability? Or the 3D model itself

In Unity and other game engines, this would be achieved by using shaders - Code ran on the GPU.
In Roblox, this is almost impossible without making the game laggy, as in Roblox, Scripts and LocalScripts are ran on the CPU. There is currently no way to make a shader in Roblox, so this may be hard to implement.
You can do it on the CPU by, as almost everyone else said, creating new parts or using particle effects.
I think it would also be possible to make in blender, but I’m not really a modeler so I don’t know how to do that.
What is possible is making a Spherical part with the ForceField material, add some scrolling textures to it and it should look similar. One issue with this is that I’m not sure if scrolling textures would work on a sphere.