The next step is taking all my art content and getting it set up with the pickup and snapping system I have already posted about. For VR, it’s best to do as little as possible in tick events. Current VR headsets run at 90 frames per second and future headsets my run at higher framerates. For that reason, I built all of my functionality to work using Begin and End Overlap events. Basically, when car part type objects intersects another car part object it executes the system of communicating between parts to find out what is or isn’t installed, and then runs the logic to allow install or removal of the part when the the correct criteria are met. This seemed to work well in testing but when I started implementing my content I quickly noticed the status of what parts were installed, allowed to be installed, and allowed to be removed were not being updated reliably. This manifested itself as parts that said they could be removed when they should have been captive, or the game erroneously preventing installation. My game is essentially a whole lot of pieces trading and checking yes/no values. Figuring out where the systems were breaking down took me a few days and these were the major causes:
I stopped using overlap events for pickup since it wasn’t precise enough (I detailed that one of the other posts). When the player pulls the trigger to pick up an object I use a sphere trace instead of an overlap. I was still checking overlap of a capsule collider in order to set the hand status to “can pickup” which is a subtle hand animation and a recoloring of the pickup indicator to show if an object can or can’t be removed or picked up. I had this capsule on it’s own collision channel and the parts had extra collision boxes on a matching channel. I had thought having separate channels would prevent any interference. In retrospect, the event is On Overlap, not On Overlap of Channel. Any time there was unintended overlap event from this capsule collider the execution loop for snapping and updating variables would get disrupted. Depending on the shape of the collision volumes and way the parts were being held, this problem may or may not have manifested which made figuring out what was happening confusing. The solution I came to was to replace the capsule collider with a trace at a regular interval (every .2 seconds works well)
When two parts overlap I do a sphere trace that is about a meter wide to get references to nearby parts. When I set this up I accidentally used simple sphere trace. Unreal has two categories of traces. A simple trace which only returns the first actor it hits and a multi trace which returns a list of all the actors that the trace intersected. In testing I didn’t notice the mistake because I was only working with a few objects at a time and the actor it returned happened to be the correct one. Switching that out for a multi sphere trace allowed me to loop through a list of actors and get information from all of the nearby actors. Like the last issue, this one presented itself intermittently depending on position of all the actors in the area.
This one seems obvious in retrospect but took me several hours to figure out. When the overlap event begins, I get references to nearby objects and check the necessary objects to see what is or isn’t installed. For installation, I check to see if the parts it attaches to are currently installed along with any specific criteria I decide (does the player have access to it? Is it realistic or practical to allow install?). For example, if the player installed a coilover shock in the car without a spring in it, I’m not going to allow them to install that spring until the shock is removed from the car and the top hat is off of the shock. AllowRemoval works the same way, I check nearby objects and decide if the part is captive or should be allowed to be removed. After the part is snapped in place, I change the part’s status to Installed. Other parts check this installed status when their overlap events occur and the system seemed to work well. The issue is that for AllowRemoval this doesn’t actually make sense.
None of these issues were particularly difficult to fix but they way they interacted with each other made figuring them out challenging. Because they were intermittent, it was hard to tell where one issue started and another began. When it seemed like I knew what breaking the game, the fix didn’t do what I expected, or the debug messages seemed to be firing without a clear reason. The takeaway for me is to test my systems with more complicated content that replicates how the game will actually work and don’t assume that a system is only broken for one reason.
I am moving on to implementing these systems with all of my art content. This means I am making hundreds of copies of the child class BP and editing the details for each part. I did some cleanup and color coding to make that process quicker: