Despite my lack of updates, only some of my lack of progress is because of Elden Ring. I can't help it. The game lets me marry a living doll. I have a type.
That said, I'm 100% going to miss the deadline but I don't care because I've been enjoying working on this game. My most recent efforts have been focusing on making a vehicle controller for the hoverbike thing the protagonist is going to be jetting around on and lemme tell ya, it has been an ordeal.[i] My first attempts basically just involved using invisible wheel colliders and having those provide all the functionality I needed, but it turns out that Unity's wheel colliders are kinda... awful for that? Figuring out what their specific dampening values and everything need to be is also an arduous process because they're all expecting ranges I'm expected to just guess I suppose.
My next solution was to use raycasts and physics forces. Figuring that the best way to ensure the bike from flipping would be to have some spread out forces, I put four of them around the bike and lowered the center of mass so that it was always inclined to stay upright. This [i]kinda worked, but it meant that applying forces at positions for steering had to have special offsets, and that resulted in weird torque behaviours that were a nightmare to diagnose and even more of a nightmare to code.
Not fun.
Then, one night, as I was tossing and turning in bed, I awoke in a start. Not because of inspiration, but because I'm prone to nightmares. To work myself down from the post-nightmare anxiety, I started thinking of new ways to get this to work, and I finally settled on a hybrid solution of an idea I had the night before and a new one as well.
Instead of using four raycasts, I use two, front and back. Next, I lock the bike's rotation along the z-axis and only ever change that with direct access from code to make the steering look "cool" by giving it a bit of a banking effect. Then, on top of all this, I added some dampening physics to it all. The front raycast gets a low dampening value to make it extra bouncy, and the rear raycast gets a high one to make it more rigid. In a way, it sorta recreates the suspension of a motorcycle! Neat!
After that, I added some extra quality of life stuff. Instead of immediately losing forward thrust in the air, I made it so that if you spend too much time in the air (about half a second), you start to have the amount of thrust the accelerator gives you drop to half its strength, meaning you can't fly around forever. I also added some functionality to make the bike automatically balance to face the horizon after a second or so in the air to help keep the player from flipping around all over the place. In the end, after far too many lines of code (both included, commented out, and deleted) I finally have something I think I really enjoy zipping around on, which is all I could really ever ask for!
Motion sickness warning on this video, by the way. I'm still mucking about with the camera system.
https://www.youtube.com/watch?v=IIZVrT5BFNA
I just think it's neat!
So! I decided to take part in the Open World Jam and the first realization I had was "this is a terrible idea."
However, that's pretty useless when it comes to getting things done, so I threw it away. Instead of focusing on that, I decided to focus first on streamlining the process of making terrain in Unity, only to be met with the fact that the Unity terrain shader is... kinda awful.
There's constant repeating textures, horrible smearing along sharp inclines, basically everything that drives me up the wall when I play an open world game! Luckily, I am very smart, or at least persistent. The first thing I wanted to tackle was getting rid of the awful tiling pattern since I prefer to create natural looking environments, and repeating patterns in nature generally aren't built along explicit grids. The solution to this problem is something known as Stochastic Sampling.
The idea behind stochastic sampling, at least from a very simplified perspective, is to tile things using a triangle grid with semi-random offsets and blend between the grid elements. If you want a better explanation than I'm able to give, there's a very in-depth paper here (Google Drive link to a PDF). It seems daunting at first, but with a little bit of finagling, I was able to get much better results.
As you can see, the tiling is effectively invisible! The downside to this is that it requires three texture samples to pull off, but even integrated hardware is so overwhelmingly beefy and bandwidth capable enough that that's not much of an issue. On top of that, stochastic sampling means I can get away with lower resolution textures in the first place. Unfortunately, we can still see some very ugly smearing. Fortunately, this is also much easier to fix because all it requires is something known as Triplanar Mapping.
Triplanar mapping is much easier to explain than stochastic sampling, thank god. Effectively, you're projecting the textures towards three different normal axes and blending them: X,Y, and Z. Again, this requires sampling three times, which is some overhead, but thanks to the stochastic sampling there's not a terrible amount of overhead. It DOES mean that my texture coordinates are now in World Space, which takes some adjustments, but by applying this method, we get some suddenly wonderful results!
Smearing? Gone! Tiling? Gone! Self-confidence? Through the roof baybeeeeeeeeeeeeeeeeeeee! Most of what was left was really just generic cleanup and making things play nice with Unity's terrain tools. By including a reference to the _Control texture sampler in my shader, I'm able to use four environment textures and paint them the same way I would a standard Unity terrain, but with none of the gross texture distortions. I can even paint holes in the texture by adding the _TerrainHolesTexture sampler. This is a massive boon even if it took a couple days to get to work because it massively streamlines dealing with terrain.
Now there is one last problem: authoring terrain in Unity is a dreadful experience. You really don't get much control over the specifics of the terrain, such as height and other features, and making terrain stamps only gets you partly there. Rather than let Unity control me like some kinda game engine cop, I cut it out of that part of the equation and took to Blender instead. Really there's nothing amazing going on here as I haven't gotten terribly far, but the general process is
1. Create a terrain in Blender
2. Join the meshes together in a big mess
3. Export that mesh to Unity
4. Use a free utility called Object2Terrain to convert that mesh into a terrain
In a perfect world (men like me would not exist, but this is not a perfect world) I would simply export a heightmap from Blender and use that heightmap to drive the Unity terrain, but Unity's terrain only accepts heightmaps in RAW format, which is notoriously difficult to export to from just about anything aside from expensive terrain authoring tools. Thankfully, Object2Terrain works a treat.
That's all for now, I suppose! I'm very pleased with the progress I've made, since it makes content authoring a lot easier on the terrain front, and that's always a tricky spot with open world games.