In Unity3d you have a plenty of choices to make several objects but, in case that you need to make an object like a ring where you can get through its center it’s difficult with the prebuild already objects (Sphere, cube, capsule etc) you probably should swivel in torus technique, of course, there are some other tips for example circles with particle systems. In geometry, a torus is a surface of revolution generated by revolving a circle in three-dimensional space about an axis co planar with the circle. If the axis of revolution does not touch the circle, the surface has a ring shape and is called a torus of revolution. Let’s see how to make it. Don’t forget to attach the script in an empty game object.

public class Torus : MonoBehaviour { // Use this for initialization public float curveRadius, torusRadius; public int curveSegmentCount, torusSegmentCount; //Mesh Render private Mesh mesh; private Vector3[] vertices; private int[] triangles; private void Awake() { GetComponent<MeshFilter>().mesh = mesh = new Mesh(); mesh.name = "Torus"; SetVertices(); SetTriangles(); } //Create Torus private Vector3 GetPointOnTorus(float u, float v) { Vector3 p; float r = (curveRadius + torusRadius * Mathf.Cos(v)); p.x = r * Mathf.Sin(u); p.y = r * Mathf.Cos(u); p.z = torusRadius * Mathf.Sin(v); return p; } //Draw Torus private void OnDrawGizmos() { float uStep = (2f * Mathf.PI) / curveSegmentCount; float vStep = (2f * Mathf.PI) / torusSegmentCount; for (int u = 0; u < curveSegmentCount; u++) { for (int v = 0; v < torusSegmentCount; v++) { Vector3 point = GetPointOnTorus(u * uStep, v * vStep); Gizmos.color = new Color(1f, (float)v / torusSegmentCount,(float)u / curveSegmentCount); Gizmos.DrawSphere(point, 0.1f); } } } //each quad share vertices with its neighbors, or give each quad its own four vertices. private void SetVertices() { vertices = new Vector3[torusSegmentCount * curveSegmentCount * 4]; float uStep = (2f * Mathf.PI) / curveSegmentCount; CreateFirstQuadRing(uStep); int iDelta = torusSegmentCount * 4; for (int u = 2, i = iDelta; u <= curveSegmentCount; u++, i += iDelta) { CreateQuadRing(u * uStep, i); } mesh.vertices = vertices; } //Each quad has two triangles, so six vertex indices. private void SetTriangles() { triangles = new int[torusSegmentCount * curveSegmentCount * 6]; for (int t = 0, i = 0; t < triangles.Length; t += 6, i += 4) { triangles[t] = i; triangles[t + 1] = triangles[t + 4] = i + 1; triangles[t + 2] = triangles[t + 3] = i + 2; triangles[t + 5] = i + 3; } mesh.triangles = triangles; } private void CreateFirstQuadRing(float u) { float vStep = (2f * Mathf.PI) / torusSegmentCount; Vector3 vertexA = GetPointOnTorus(0f, 0f); Vector3 vertexB = GetPointOnTorus(u, 0f); for (int v = 1, i = 0; v <= torusSegmentCount; v++, i += 4) { vertices[i] = vertexA; vertices[i + 1] = vertexA = GetPointOnTorus(0f, v * vStep); vertices[i + 2] = vertexB; vertices[i + 3] = vertexB = GetPointOnTorus(u, v * vStep); } } private void CreateQuadRing(float u, int i) { float vStep = (2f * Mathf.PI) / torusSegmentCount; int ringOffset = torusSegmentCount * 4; Vector3 vertex = GetPointOnTorus(u, 0f); for (int v = 1; v <= torusSegmentCount; v++, i += 4) { vertices[i] = vertices[i - ringOffset + 2]; vertices[i + 1] = vertices[i - ringOffset + 3]; vertices[i + 2] = vertex; vertices[i + 3] = vertex = GetPointOnTorus(u, v * vStep); } }

[…] The main architecture is simple, we put the player into a 3D space to run through pipes, with some obstacles and stuff. Due to the fact that straight pipes are boring, we made curving pipes! In a previews post there is an article how to make a torus ring. […]