Reputation: 69
I'm trying to create a voxel-style cone shape in C#. I've got the cone building using cubes, but can't work out how to only build the outer layer (make it hollow) rather than build a solid cone as shown in the pic.
The code so far (Edited from someone else's script)
// Create a cone made of cubes. Can be called at runtime
public void MakeVoxelCone()
{
for (int currentLength = 0; currentLength < maxLength; currentLength++)
MakeNewLayer(currentLength);
}
// Make a new layer of cubes on the cone
private void MakeNewLayer(int currentLength)
{
center = new Vector3(0, currentLength, 0);
for (int x = -currentLength; x < currentLength; x++)
{
for (int z = -currentLength; z < currentLength; z++)
{
// Set position to spawn cube
Vector3 pos = new Vector3(x, currentLength, z);
// The distance to the center of the cone at currentLength point
float distanceToMiddle = Vector3.Distance(pos, center);
// Create another layer of the hollow cone
if (distanceToMiddle < currentLength)
{
// Add all cubes to a List array
Cubes.Add(MakeCube(pos));
}
}
}
}
// Create the cube and set its properties
private GameObject MakeCube(Vector3 position)
{
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.GetComponent<Renderer>().material.color = Color.blue;
if (!AddCollider)
Destroy(cube.GetComponent<BoxCollider>());
cube.transform.position = position;
cube.transform.parent = transform;
cube.name = "cube [" + position.y + "-" + position.x + "," + position.z + "]";
return cube;
}
I think its probably simple, but cant figure it out.
Maybe something about the if (distanceToMiddle < currentLength)
part, but swapping <
for ==
breaks the whole shape.
@Jax297 >= (currentLength-1)
Closer, but not correct just yet. Now its a pyramid with a cone cut out.
Upvotes: 3
Views: 439
Reputation: 2234
If you want to create a "empty" cone. Try to describe that shape in English first.
Create a circle at height going from 0...h with increasing radius for each step from 0..r
So now you need to find equation of a circle (should take you back to HS trig): sin(theta)^2 + cos(theta)^2 = radius
:
Now you want to create this circle while increasing the height.
This will create only the empty cone you wish.
Here's an quick implementation (adjust as needed):
public List<GameObject> instantiatedObjects = new List<GameObject>();
public GameObject rootParent;
public int numOfRows = 10;
public int incrementPerRow = 4;
public float radiusStep = 0.5f;
public float height = 5;
[Button]
public void CreateVoxelCone()
{
// first one. root object.
rootParent = GameObject.CreatePrimitive(PrimitiveType.Cube);
rootParent.name = "Pivot";
rootParent.transform.position = Vector3.zero;
var itemsForThisRow = incrementPerRow;
var heightStep = height / numOfRows;
// for each row...
for (int i = 0; i < numOfRows; i++)
{
// create items in a circle
var radianStep = Mathf.PI * 2 / itemsForThisRow;
for (float j = 0; j < Mathf.PI*2; j=j+radianStep)
{
var newPosition = new Vector3(Mathf.Cos(j) * radiusStep * i, heightStep * i, Mathf.Sin(j) * radiusStep*i);
var point = GameObject.CreatePrimitive(PrimitiveType.Cube);
point.name = ($"Row: {i}, {j}");
point.transform.SetParent(rootParent.transform);
point.transform.localPosition = newPosition;
instantiatedObjects.Add(point);
}
itemsForThisRow += incrementPerRow;
}
}
[Button]
public void CleanUp()
{
DestroyImmediate(rootParent);
}
Upvotes: 0
Reputation: 483
assuming your currentlength is the outer diameter you have to introduce a thickness vareable and compare to currentleght - thickness, so there is a inner diameter to be kept free
(currentLength - thickness) < distanceToMiddle && distanceToMiddle < currentLength
Upvotes: 3