I'm trying to plan out a cover system for a 3D game.
The mechanic
- When the player approaches a surface they can take cover behind...
- A prompt appears indicating they can enter cover, and what to press to do so.
- If the player presses the prompted button, their avatar is locked into a path following the scenery they're taking cover behind.
- If the cover is a half wall, the avatar should crouch.
- If the player approaches a gap in cover the camera should peek around the corner and
- ...they should be prompted to jump to the next cover
- ...otherwise, the player can exit cover by pressing another action button.
As seen from directly overhead (please forgive the side view character):
The plan so far
As far as I know, cover must be either
- baked into the level by algorithm
- explicitly created by the level designer
- somehow handled on the fly
What I think should happen is the environment should be baked into hidden geometry which qualifies as cover. Then, I would detect sphere collisions (blue) with the generated cover areas (purple) to find out when one is in range.
Static geometry would qualify as cover if it were higher than a certain amount from adjacent ground (ie. at least 2.5 feet tall), and another threshold would indicate whether the character should crouch (at least 6 feet for standing cover, otherwise crouch). It seems like this would also be helpful for NPC vision and path finding.
This sphere detection process could be used similarly to locate gaps with cover available on the other side. Finally, once in cover, the player would move tangent to the cover surface (purple regions). Cover surfaces with angles less than a certain threshold would interpolate the current path into the path the player should follow to continue, otherwise they would be counted as a corner. So when the player reaches the end of cover, the angle of the adjacent surface determines that cover has ended and will prevent the player from accidentally breaking cover. They could press a button to move around the corner.
But I prefer not to reinvent the wheel - so is this "correct," or is there some accepted way of doing this that's totally different?