Throughout my career, I have found myself repeating the following mantra:
Don't build an engine in an engine. Use the engine.
If you need a way to have a flexible schema in SQL, implement SQL CREATE/INSERT COLUMN etc. If you need a series of page that follow one after another then use ASP.NET with HTML hyperlinks, don't build another engine inside it.
The building grid was going fine. You could select buildings and place them on the Cloudship base without physics going mental. It was a bit tricky to click on spaces in the middle but better camera movement would have helped with that. The next task was "rotate building". That's easy if you consider that the building is 1x1 but then it starts getting nasty if it's 2x2. I began working out the maths and realised that I was building a rotational engine. Which is mental. What if, I thought, what if I just removed the bloody grid?
All the things I was getting from the grid weren't that helpful:
- Collision was easy (was the space taken).
- Selecting a space to put the building was easy.
- Lining stuff up was easy.
However, some stuff started to get hard:
- Rotating buildings
- Buildings that were odd shapes (imagine Tetris piece from above).
- Filling up all of the base so that it looked crowded rather than having these edges
So I decided to clear out the grid and just plonk the buildings down. Here's a WIP montage:
I started naively, knowing full well that some things would need to change. I accidentally left physics on at one point and had good fun making the ship go mad. There's a possibility in the future for the physics engine to take the weight of the buildings into account.
As the video shows, I managed to get collision working but the buildings would overlap the edge. So began "edge detection" Odyssey.
The edge detection problem is:
The building must not overhang the edge (much)
My first thought was to have a series of flat planes will colliders on them. If a building touched these flat planes then it would disappear (can't be placed). Unity doesn't do collision on a flat plane. So many boxes, then? Possibly but costly in terms of time to set up on each base. Then I got the idea of rather than detecting the building entering a boundary, you detect it leaving one. I wanted to use a standard (optimised) collider rather than the expensive mesh collider but it's only for building purposes and you can't make the standard ones into an ellipse.
Here's my notes for edge detection:
The elliptical boundary collider would scale depending on how big the building is. Small buildings can get nearer to the edge, so the boundary collider would shrink only a little bit. When the building's collider stopped intersecting with the elliptical boundary collider then the event would fire, I could trap that and switch off the building.
That worked at first but as I was experimenting with bigger buildings, I realised that if the building took up more than half the width of the cloudship then the boundary collider would have a negative width and it would stop working. Instead I had to add more colliders to the buildings, split out the collision scripts and track "building colliding with building" and "building staying in the safe zone with boundary collider". So, rather than the boundary collider working with the actual dimensions of the building, it would only collide with a little collider.
Here's a little video if it in action:
As I move the first building toward the edge, it only disappears when the little collider leaves the safe zone of the elliptical boundary collider. The main building dimensions are still well within the boundary collider here.
I hope all that makes sense.
I'm going to play with the shader graph so that the building becomes an outline rather than disappearing completely. As part of all this work, I've updated Unity to 2018.1 and moved over to using the lightweight render pipeline. There's still a little bit of faff (you'll notice the lighting on the controller is gone overexposed) but I'll figure that out.
Rotating buildings is then REALLY easy and I can make another building or two.