2D side-scroller with faked isometric camera

Hi,

I’m thinking about creating a simple side-scroller in the same style of the old Double Dragon or the more recent Castle Crashers.
That means 2.5D, but using sprites and vector-art for the level and characters.

My wish is to be able to use hand-drawn art for the level, where I manually rotate every wall that’s in the Z-direction 45 degrees to fake an “isometric” point of view. This also means that the player can move in Z, but it will be displayed as an offset in (world) X and Y on-screen.

I know there’s probably tens of ways to accomplish it, but my main concern is that it would be great if it’s possible to keep the player-position, collision-detection and a bunch of other stuff in full 3D internally. That way I can use PhysX, and I have no restrictions on what kind of framework I use for animation etc.

So, my initial thought is to create the level as two separate entities. A 2D representation where I put my hand-drawn background, foreground and so on. And then a 3D representation with all the colliders and other logic stuff for the level.
I then use standard ways of moving my character, such as CharacterController, in the 3D representation of the world.

What I don’t know is how I best display the characters on top of the 2D artwork best?

One way would be to have a clone of each character, and a simple script on that clone that moves it in X and Y according to the master objects Z-position, and then show that clone on camera instead of the “real” character. But then I’d have to keep the clone perfectly synced to the master for animations and such.

Another way would be to somehow shift the position of each character temporarily in X and Y according to Z before the actual rendering of each frame. But how?

Or is it possible to somehow script a separate orthographic camera that will act as if it’s rotated 45 degrees in X and Y, but still render all objects as billboards that always face the camera? And without affecting the objects transforms, so that PhysX won’t go haywire?

Sorry for a long post. As you probably see I’m a bit lost right now and perhaps not perfectly clear about what I want or how to properly describe it :slight_smile: .

Just thought of something: Is it possible to tweak the camera’s projectionMatrix to achieve what I want? So that an orthographic camera displays an object with a Z-value of 1f as being offset -1f on X and +1f on Y?

Edit:
I just found this link. That’s exactly what I’m after. Didn’t know it’s called Cavalier / Cabinet perspective… You learn something new every day :slight_smile: .

So I guess I’m no longer in need of assistance, I will try the matrix from Wikipedia as a.s.a.p. But I hope this thread can help anyone else having the same problem.

Check out MikaMobile posts, he talks about how he and his partner go about 2.5D games in some of his posts.

Posts he started

2D animation in 3D

just look around

Thank’s, sure will :slight_smile:

Hello again,

Sorry to say that my earlier findings didn’t lead to a complete solution…

I’ve implemented a custom projection-matrix for the orthographic camera seen below:

		viewMatrix = camera.projectionMatrix;
		
		float	xMult	= Mult * Mathf.Cos(Angle);
		float	yMult	= Mult * Mathf.Sin(Angle);
		
		viewMatrix[0,2] = xMult;
		viewMatrix[1,2] = -yMult;
		
		camera.projectionMatrix = viewMatrix;

Where Angle is set to 45 degrees.
I have two problems:

  1. The variable Mult has to be VERY small, like 0.01f in order to give objects the correct “skew”. If set higher, a 1x1x1 cube will distort wildly in the forced depth dimension compared to its “flat” front face. Why is that?

  2. I don’t get exactly 45 degrees of offset, and it varies depending on the width/height of the current monitor resolution.
    Is it possible to use the projection-matrix in a way that gives identical oblique projections regardless of whether the user has a 4:3 monitor or a 16:10 android phone?

I’m very thankful for any and all suggestions.
If there’s a better way to handle this, please let me know. I’ve looked a little at the worldToCameraMatrix, but I don’t know if that’s of any help in this case.

Edit:
Fixed it, see below. Had to account for the screen ratio in the matrix, and make sure to update the matrix on resolution-changes.

		camera.ResetProjectionMatrix();
		viewMatrix = camera.projectionMatrix;
	
		float	ratio 	= (Screen.width / (float) Screen.height);				
		float	xMult	= (Mult / ratio) * Mathf.Cos(Angle);
		float	yMult	= Mult * -Mathf.Sin(Angle);
		
		viewMatrix[0,2] = xMult;
		viewMatrix[1,2] = yMult;
		
		camera.projectionMatrix = viewMatrix;

I’ve built an extension that handles this sort of rendering and allows for simple tweaking, if you don’t want to get your hands dirty with the matrix stuff :wink:
You can find it here: 2.5d Isometric Camera