I've been looking at props recently, something which will allow for a little bit more freedom when decorating rooms, etc. While doing so, however, I ended making another pass on the building system. Which I'd like to talk about today.
In this pass, there were a few things I wanted to focus on.
- Tile Rotation
- Tile Elevation
- Tile Edge case
The Middle mouse button isn't ideal. Although I know a lot of people have already been getting used to it. Personally I have my middle mouse button mapped to the side of the mouse as an individual button. This is from years having to use the middle mouse button in 3D applications. So when I was mocking up the building system, it felt natural for me to have something on that button. But as some people might know, and I've been reminded of, the middle mouse button is a fickle creature. One which seems to have a different personality across every instance of mice. Some of them are mean.
Not going to remove the middle mouse button (will be mappable later) but I am playing around with adding some more options. Both of which centers around the [Left-ALT] key (also mappable later). We're already using Alt for rotation on creatures. This works by holding down the key and then pointing the mouse in the direction you want the creature to turn. This sounded like a decent idea when looking into props (not in this update). After some tests, I thought this might also work alright for tiles. Which it did:
So with that we've started unifying "object" rotation across the board.
What about elevation?
There are a few different systems for tile elevation. One is the mouse scroll wheel. Which allows you to lock the tile in place and scroll it up and down. The other is changing the Build-Plane (grid) to match up where you should build. Neither of these feels like they work very well. The mouse wheel is cumbersome and the Build-plane takes multiple inputs, despite there being some shortcuts to sample the plane elevation. But that still requires there to tile present to sample
Taking inspiration from the object rotation, by unifying input, I've mapped this to the [left-CTRL] key. (as this will also be needed for flying creatures).
Now you can hold down the key and drag tiles up and down. This will also move the Build-plane (grid). Still needs a bit of work, especially on visualizing. It does feel quicker than previous methods though.
There are a lot of edge cases in the Building system. Things that make is rather twitchy. There is one more literal edge case that has been bothering me for a long time. And I decided to address this. But before I get to that I'd like to talk a little bit about how the tile placement work, and why this can be a bit tricky.
The tile placement is based on the projected mouse position. So the pointer raycasts into the scene and hit colliders set up on the tiles themselves. Then it uses that placement to find the correct snapping on the grid, which draws the binding volume and dictates where the tile will be placed once the left mouse button is pressed. So far it's not too complicated.
But this would cause the tile to be in an illegal state (intersecting with other tiles) in most cases. Whenever you'd hit a wall of another tile, for instance, you'd be intersecting with that tile. So to remedy that we also check the normal of the hit. And then used a snapped version of the normal to push the tile out in that direction. Now, this causes the tile to find a legal position on the side of the tile. It also allows for the GM to place tiles on the vertical surfaces of other tiles.
The final step to this is. If it is not able to cling to a wall but find itself in an illegal location. Can it go up? So the tile then starts checking by climbing upwards to find a legal location. It only climbs a few units, enough to allow placement on top of tile you're interacting with.
This has been working alright, but it does have a lot of issues. Especially the final step. It is one we might have to change.
Back to the edge case I was talking about though. And it is this:
When wanting to place one 2x2 floor/wall piece on top of another, it takes a lot of maneuvering. We can hold down [Left-SHIFT], of course, which will solve this problem. But it is part of what makes the building system feel so jittery. And fixing this become very important to me personally.
Why is it happening?
As I mentioned before the position is found via a raycast into the scene from the camera. It is actually a sphere cast with a little bit of a radius to cancel out some noise. A box cast would make sense which would allow us to match the Tile somewhat but also make it hard to place tiles in without lining up the camera perfectly (tangent: as I'm typing this though, I had some ideas on how to get around that, need to test).
There isn't a ton of data being captured between these two cases of almost lining up, and missing it entirely. But one thing we can see is that the new point has significantly moved. So if it does move more than let's say half a unit, we know that something has happened. We can assume that the raycast has missed the ledge. Checking the Y-axis of the new point and comparing it to the previous one we can see if it has moved up or down. If it moved down, we can do a new ray, this time hitting a plane created on the previous location. This now allows the tile to slide along that plane. Of course, it will continue to do this until we tell it not to. So the tile starts to checks by doing a box-cast downwards just 0.24 units. If it doesn't hit anything we're likely no longer on the ledge and we can restart raycasting as normal.
And the fix. So satisfying.
This was a lot of talking for what seems to be a very small victory. It just felt so good to get this working. I had to share. It is important that building is satisfying. And there are so many cases where it just isn't. I hope there might be some more general solutions for most of those cases.
Anyway, I'll be talking about props in a later update.
PS: it is going to take a little while for these fixes and changes to make it into the game proper.