Progress Update #33
Menus & Collision
This week was a real roller coaster. After trying to put a dent into the backlog work from last week and trying to get all of this week's tasks done, I managed to get a lot of it done and am one step closer to the closed beta.
Options Menu
The first menu that I wanted to implement was the settings or options menu. The goal for this was basically just to have a place to set display settings without having to use console commands. I was able to shortcut this process by copy/pasting the options menu from a previous Unreal Engine game that I had worked on with the working title "Top Down Game". This version of an options menu had all of the display settings I wanted as well as colorblind options which are always nice to have when it's a built in feature of the engine. I did find though that the framerate limiter option wasn't working for some reason. I was able to get around this by using the console command t.MaxFPS %FrameRate% instead of the game user settings framerate.
Because it was only midday by this point I decided to also add a graphics quality option. I implemented this with a quality switch node in the material graph which uses a different value based on the quality level. I tested this out with the atmosphere using less ray steps at lower quality levels. I plan to expand this a bit more in the future but it is a good proof-of-concept for now.
I then spent the rest of the day making little transition animations between the main and options menu.
Pause Menu
The other menu that I needed to add was an in-game pause menu. This menu would give the ability to pause simulation, access the settings menu, and save/quit the game (which was previously only accessible through console commands). I was uncharacteristically nervous when starting work in this menu only because in previous games that I've worked on, the pause menu was always an afterthought and was crammed in at the last second and would always result in a cascade of bugs. But this time around would be different as now I had the experience to know how to do it right.
The main habit to break was putting pausing functionality in more places than it needed to be. I remedied this by putting one pause method in the game-mode and the call to that function in the player controller. So now, no matter what the controller is possessing, or whatever state the game is in, the game can be reliably paused. The other historically big issue with pause menus was that sub-menus (e.g. options menu or achievements viewer) would be left on the screen even after the main pause menu had disappeared. I don't really know why this was a problem for so long as now I now to just make those menu widgets children of the main pause menu.
The only remaining issue with the pause menu that I have ended up with is the animations. The pause menu widget is added to the screen last so that when it's constructor is called (don't really know why the constructor is called when the widget is added to the screen because it already exists in memory, but, whatever) an animation will play. This animation will then play in reverse if the player hits "Resume".
The problem, then, is that if the player hits the escape key to resume, as I think many people would, I don't know how to play that animation before removing the widget from the screen. The result is the pause menu just disappearing in a frame which is quite jarring to say the least.
Collision
To give some background, up until now there was no collision in the game whatsoever; planets would phase through each other, the player could fly around inside of planets, it was not ideal. This is what I spent the majority of my time on for this sprint. It went through three iterations before being stable enough by my testing.
Iteration 1: Unreal Collision
I started out relying entirely on engine functionality to handle collisions. I added "BlockAll" colliders to the player and the planets: nothing. I watched for the hit event: nothing. I watched for the overlap event: nothing. I saw something online saying that the root component of an actor needed to be a child type of UPrimitiveComponent but that didn't fix it either. It was clear that, for whatever reason, Unreal would not handle my collisions for me.
As one final hail mary I made the root component the collider; I was finally able to get overlap events.
Iteration 2: Apply Force on Overlap
At this point I supposed the reason why the engine collision didn't work is that I'm doing all of my celestial physics manually, and since collision relies on physics I would need to do collision myself as well. I started this by catching the overlap event and applying a force to the body. Essentially, since everything in-game that requires collision (planets, stars, the player) can be approximated as a sphere, I can just get a vector of (this.position - other.position).GetSafeNormal() which will point directly away from the other object. I can then multiply that normalized vector by some force amount to push the body out of the other one and get them to stop overlapping.
The problem with this was it was wildly unpredictable. At very slow collision speeds it would push away too hard, at medium speeds it would seem about right, at medium-high speeds it would almost trap you in place, and at very high speeds you could phase through planets anyway. I started thinking more about how collision in a game engine would work. I realized that you probably wouldn't have just a single force applied to keep you from going through an object, but instead a sustained force that would apply until the objects are no longer overlapping
Iteration 3: Sustained force
The way I accomplished this was actually pretty simple. On begin overlap I would set a variable for the actor that is being overlapped with. Then on the physics tick, if that variable isn't nullptr then we do the same normal vector calculation as before and apply a force proportional to the current velocity in that normal direction. That keeps happening until the overlap ends and the overlapped actor variable is set to nullptr.
Finally, I did a little tweaking to the player's collider so that the camera would clip through the mesh less frequently. Not perfect but a definite improvement.
Also, adding collisions has temporarily broken the ability to teleport to planets, as the teleport sets the player's position to exactly that of the desired planet which happens to be at the planet's center. This means that teleporting to a planet right now will basically be guaranteed to shoot you off into space at max speed.
Backlog Tasks
The two backlog tasks I have are the final save/load polish, and a main menu graphical improvement.
The save/load polish is only following this video/the action RPG demo and creating a slate UI widget that runs on a separate thread and will mask the level transition. I'm only hung up on this because Unreal keeps complaining that the module is made in a different engine version and needs to be compiled but refuses to compile.
The main menu graphical improvement is arguably done as I did change the button sprites and animations and such but imo that's not enough to constitute a full graphical improvement.
Comments
Post a Comment