I’m going back to perspective camera rendering (instead of orthographic) and full-on 3D world, just with 2D sprites.
To briefly recap, I originally started the project using perspective camera, but then I later decided to just do orthographic camera due to rendering difficulties. I outlined my reasoning about these in various other posts. In short, perspective looks better (more dynamic). But orthographic’s generally easier.
My issue is that I have over-complicated custom physics. And I really miss the game looking better, at least the potential to do so. I think my problem was that I did incompatible things — tried to do pseudo-3D, but not actually use Unity’s physics. I should instead stick to a feature and fully realize it rather than taking it “to the next level” but poorly.
So my plan now is to do 2 things: make everything 3D, but with 2D sprites instead of models. And convert my physics to Unity’s. The first is not too hard, but the latter is a big change (which I will think on). This will take time and will mean I wasted a bunch of time before. But, at the end of the day, I am confident that I can make it work (in reasonable time).
I could just stop changing things and clean up the game for polish. But I feel like I need to do a better job of visuals if I have any chance of this being any better than average. It might be a sunk cost fallacy on my part to try to preserve old stuff. And I think I can do a much better job with collisions, lighting, and rendering polish if I use more of Unity’s stuff.
Let’s start with camera changes.
First thing to do is to “lean back” the camera — film things at an angle, giving that view of depth. This is easy enough — I literally just change the camera angle.
Of course, changing the angle means the camera is now pointing not at the player. So I need the absolute camera offset (again):
Of course, everything is still “flat” — I only changed the camera angle, not anything about the world objects:
So now I need all of them to “face the camera”, that is, have their angles be the same as the camera lean angle. This is essentially billboarding, although I keep them billboarded to the camera plane and not the camera origin. I can change the prefabs to match:
And the mob in-game then appear angled to the camera in relation to the “flat” ground:
In fact, every world object I have can be adjusted to do this (projectiles, props, items, decals, effects).
Now, I don’t want to change every prefab of every type of world object that angles itself towards the camera every time I tweak the angle value. I chose 20° here, but that’s just an estimate. So I want to add this a parameter for my camera system:
And each prefab, instead of “hard-coding” the angle, controls the container dedicated to facing the camera and set the same angle to match:
And this works out nicely: the mob is facing the camera exactly, at least when they are in the middle of the screen:
My camera is not orthographic, so my orthographic camera size or “camera distance” doesn’t apply anymore. Now, I specify the camera distance (from the world) manually, and this means it’s wrong — the above screenshot is not a multiple of my sprite pixel size.
Instead, I want to manually calculate the necessary frustrum height and the distance that I need at the camera’s field of view that results in the exact 1:1 sprite pixel to screen pixel ratio. After some tedious math, I can do that:
I could also technically calculate the exact offset I need to have the camera point at the player instead of specifying it manually, but I am not actually pointing it exactly at the player, because the bottom of the screen is “less visible” due to camera perspective. I want to manually position it, so it’s not worth the hassle doing maths when I will just offset it even more manually anyway.
Fixing walls is more problematic. As a quick proof of concept, I made them 3D with separate walls:
Of course, none of this has proper sprites:
Fixing walls and doors is a large feature and topic in itself, so I will cover it in the next post.
There are also rendering issues now with the walls and floors:
A quick look at this also feels like it will be a bigger feature as I cannot simply adjust my sorting layer numbers.
What’s somewhat nice and surprising is that the rest of the game still works fine. I am basically changing the rendering layer, so the logic is not affected. This won’t be true once I start using colliders and Unity physics, but for now it’s all still as before.