Please note: These GIF’s are quite dark as Realtime Global Illumination is disabled for recording; when there are a large amount of Tiles in the camera’s view frustum, we have trouble rendering the shadows for each one at the same time (in other words it looks shitty). Workin on that!
So WTF is Going On in these GIF’s?
This is our implementation of a classic autorunner’s 3-lane system (ex: Temple Run) inside Sky Labyrinth. It’s a lot more complex than a classic 3-lane system for several reasons (WARN + INFO: this is about to get really technical, the code is available here) The system needs to be able to:
- handle omni-directional movement
- handle rotation and left/right movement at anytime
- prevent the player from being inside two tiles at once (ie: in-between tiles)
- handle the “edge case” of the player landing anywhere inside the maze, such as falling into maze initially or after getting a SuperJump power-up (yellow blobs in GIFs)
Both implementations address these by doing the following:
- Each Subtile has NSEW boolean flags that designate where the player can go (which are set automagically by our automated maze generator – a topic for another blog post)
- The Player is “anchored” to the center of a Subtile, to handle #2 and #3 and sort of #4
The original jittery implementation did the following:
- When the Player collides with a Subtile, the Subtile updates the Player class with a reference of itself
- The Player class is anchored to that Subtile immediately
The problem with this approach was that it created a “race condition” of sorts. When the player collected a SuperJump. Sometimes, the Subtile update would be beaten by the Player classes anchoring code, so the character would get snapped back to the “previous” Subtile they had jumped off of instead of the one they landed on. It was also, super fucking jittery.
The new less-jittery (but still not yet perfect) implementation does the following:
- Subtiles still update the Player class with it’s reference, but that is only used for NSEW flag checking, not anchoring. Anchoring is now done via a method call, each Subtile calls a method inside the Player class CenterToSubtile(Vector3), passing it’s own position.
- This method will call the anchoring coroutine LerpToSubtile() only if a boolean flag subtileCenterNeeded is true.
- This boolean is set to true only when the player rotates, or is airborne (such as initially falling into the level, getting a SuperJump)
Essentially, this implementation is less jittery because it anchors the player much less often. In retrospect, this seems like a “no-brainer, duh-doy” solution, but goddamn I’ve been too busy to get around to thinking of it (until today). Been balls deep in engineering+design tests for potential employers. ୧( ಠ Д ಠ )୨