Best way of creating curved ground for a 2d platformer

What is the best approach when creating ground (curves and slopes) for a 2d platform game? The game will have a lot of levels. Do I use 3d models or is it better to "draw" the levels in Unity? If it is better to draw it, is there a way of generating the level in code? That would make it easier editing the levels.

alt text

Unity doesn't have built-in tools to create new geometry or meshes, so you can't "draw" your levels in Unity.

You have to create meshes in external applications like 3ds Max, Maya, or Blender and import them into Unity.

You can either create a whole level in the external program, or create many "building blocks" that you can then assemble into a level inside Unity. The latter approach of course gives you greater flexibility in Unity and also means that you may be able to cut down on the data size of your game since the same building blocks can be reused many times.

It would be possible to make editor scripts to create tools so you could draw your level inside Unity. However, this will be a major effort, and will require good scripting knowledge. Examples of similar things exist: 3rd party tools for Unity exist (look in the Asset Store) for creating curved roads and rivers directly inside Unity. It just takes work to create such tools.

you could scale and rotate some cubes like this (prefab is just a simple unit cube)

		float segmentSize = 0.1f;
		int numSegments = 20;
		Vector3 nextPosition = new Vector3 (0, 0, 0);

		for (int i=0; i<numSegments; ++i) {
			Vector3 p1 = nextPosition;
			Vector3 p2 = p1;
			p2.x += segmentSize;

			// modulate Y coordinate to follow a sine wave
			float r = 2f;
			float s = (Mathf.PI * 2f) * 0.05f;
			p1.y += Mathf.Sin (p1.x * s) * r;
			p2.y += Mathf.Sin (p2.x * s) * r;
			
			float angle = Mathf.Atan2 (p2.y - p1.y, p2.x - p1.x) * Mathf.Rad2Deg;
			Vector3 scale = new Vector3 ();
			scale.x = Vector3.Distance (p1, p2);
			scale.y = 0.1f;	// make the ground thin
			scale.z = 1f;
			
			Transform o = (Transform)Instantiate (prefab);
			o.localScale = scale;
			o.localPosition = p1;
			o.localRotation = Quaternion.identity;
			o.Rotate (0f, 0f, angle);
			
			nextPosition.x += segmentSize;
		}