- Home /
Circular (Inside cylinder) World for 2d Platformer
I'm wondering what would be the best way to have a 2.5D side-scrolling platformer play out on the inside of a cylinder. So in a simple example, the character would be able to run all the way around the inside back to where they started.
I've thought about possibly having the character not move left or right but rather the cylinder rotate around them when pressing left/right, but wouldn't this cause problems with the camera?
Basically, is there some efficient way to restrict the character's left/right movement to a circular motion around the inside face of a cylinder world?
I have a hard time visualizing a side-scrolling game in an enclosed pipe, so a visual (even a hand-drawn one) would be helpful. Having a game where the player runs down the inside of a pipe has been covered a number of times in the last year. Assu$$anonymous$$g the character movement is only on the inside of the pipe, you can use Transform.RotateAround() to rotate the character, or you can place an empty game object at the longitudinal axis of the pipe, make the player a child, and rotate the empty game object. Consider leaving the character at the origin and moving the pipe rather than moving the character.
Sorry about that, I understand that it's hard to visualize; I'll draw up something soon. You said this idea has been covered many times in the last year? Do you have an example of this? Thank you!
Answer by thinkyhead_ · Feb 27, 2014 at 11:17 AM
I just built a looping 2D/3D world recently, and I considered using a scheme like you describe with the inside of a cylinder, but I dropped that approach; it's too messy and involves too much computation to have things move in arcs. Instead, split your scenery into two or more pieces that are at least wider than the screen. Two pieces —each half the size of the world— is ideal. Attach a script to these scenery groups called "LoopingScenery." Then have all your game objects inherit from a class named "LoopingWorldObject" (or just attach it as a component). Then your scenery and game objects will move as needed according to the position of the main camera. Here's what these classes look like for my game, which uses a world 10,000 units wide and two scenery chunks that are each half the size of the world:
public class LoopingScenery : MonoBehaviour {
Transform T, mainT;
// Manual Initialization, if needed...
public void Init() { gameObject.SetActive(true); }
// Initialization once in the world
public virtual void Awake() {
T = transform;
mainT = Camera.main.transform;
}
// Move this object to the other end of the world as-needed
void Update() {
float diff = mainT.position.x - (T.position.x + 2500f); // 2500 = center of the chunk
if (diff > 5000f)
T.position += Vector3.right * 10000f;
else if (diff < -5000f)
T.position += Vector3.left * 10000f;
}
}
public class LoopingWorldObject : MonoBehaviour {
protected Transform T, mainT;
// Manual Initialization, if needed...
public virtual void Init() { gameObject.SetActive(true); }
public virtual void Awake() {
T = transform;
mainT = Camera.main.transform;
while (CorrectForCamera()) { /* do nothing */ }
}
// Move this object to the other end of the world as-needed
public virtual void FixedUpdate() { CorrectForCamera(); }
bool CorrectForCamera() {
bool didCorrect = false;
float diff = mainT.position.x - T.position.x;
if (diff > 5000f) {
T.position += Vector3.right * 10000f;
didCorrect = true;
}
else if (diff < -5000f) {
T.position += Vector3.left * 10000f;
didCorrect = true;
}
return didCorrect;
}
}
NOTE: Since your gameObjects probably have to collide with the scenery, your particular solution will therefore need to involve one extra copy of the scenery chunks to ensure nothing falls through when the scenery is moved. Or, to avoid the extra scenery copies, you could devise a solution similar to this one which keeps each gameObject inside the same group as the scenery that it's closest to, changing its parent as it moves from one to the other. In that case, you just need to make sure the gameObjects have access to the scenery groups and check them against their positions rather than the camera.