Back to Home

About the Project

For this project I programmed and designed a Virtual Reality Card Game using Unity, C# and the Meta Quest 3s. It's a relatively simple game in which you play against an AI opponent, summoning and fighting with troops in order to defeat them.

The primary focus of this project was to experiment with XR and VR development, as it's something I am interested in pursuing as a career option in the future. I wanted to get a handle on the unique challanges that working with virtual reality presents. Throughout development, I learned that working with VR requires you to change your approach to game design and user interactions, whilst many parts of the development process is similair to what I am used to (making games for Windows and PC) the actual testing and iterative process is quite different and requires a lot more patience.

Primary Goals

  1. VR Integration - Before even starting the project, I understood that working with VR can be a challenge, potentially highlighting the reason that the industry still hasn’t grown to the extent many people believed it would. Desipite the limitations of the technology, I wanted the experience to feel like playing an actual boardgame with the added benefits of the simulated environment.
  2. Haptic and Visual Feedback - Considering the fact the game is played in virtual reality, providing tactile and visual feedback is pretty important to the overall experience. Whilst you can’t currently simulate “touch”, grabbing a card can be made much more "real" through the use of haptic responses. Small controller vibrations when interacting with an object or colliding with the walls, definitely add polish to the game and it's the subtle details that make the game more immersive, at least in my own experience with VR games.
  3. The Actual Gameplay - Whilst I treated the core gameloop as a secondary priority throughout development, I still wanted the gameplay to be clear, intuitive and enjoyable. The core gameplay loop takes place in 3 parts, the card selection process in which you and the AI enemy choose troops and landscapes. The battle phase in which you select troops to attack or move. And of course winning or losing, in which the first player to defeat all their opponents troops, takes the win.

VR Implementation

The first mechanic I integrated was the VR controls and mechanics. I started with integrating the head and hand tracking. Unity provides many prebuilt tools, packages and components for this, but I specifically chose to avoid these components so I could fully grasp the mechanics taking place. I used the InputManager to track my devices, then calculated their change in positions and rotations to simulate hand and head tracking. You can see a short snippet of the VRController from early development here.

Later I went on to add hand collisions, whilst the players "real" hand can easily pass through tables, a technique commonly used in VR is to simulate the hands in the game space, taking the players real hand position as “Suggestion”. From the players perspective, this allows the hand to interact with the world in a real, physical way.

Movement Controller Code Snippet
Hand Collisions Showcase Card Grabbing Showcase

The Gameplay

The core gameplay loop was both fun and challanging to implement. There where many considerations to take into account when designing the gameplay for VR. For example, my early attempts at designing the combat system used "raycasts" to select troops and attack enemies. However this was unintuitive and clunky for VR use, especially since small "shakes" in the players hand would often result in the raycast missing the target. To solve this, I decided to add all sorts of "helper" systems to make gameplay feel more fluid. I used sphere casts instead of raycasts to make selecting targets easier, adding visual indicators to show what troop was selected and where that troop was going to move. I also added a snapping system, so even if you moved your hand slightly off target, the visual indicator would remain in place, which really helped with the overall experience.

I used this approach for the card grabbing too. Early play testing with friends proved that the card selecting was difficult and felt un-polished. To fix this I made the cards snap between your hands, the table and card pile, based on the distances between them, which greatly improved the overall feel of the interactions.

  1. Card Selection Phase - In this phase, the player is given a series of landscape and troop cards, from there they select cards from their decks to add to the table. The placement of landscapes and troops is relevant, as troops recieve a damage bonus for being placed on their matching landscape type. The AI opponent selects cards based on a simple algorithm that prioritises placing troops on their relevant landscape, but otherwise the process is entirely random.
  2. Battle Phase - During the battle phase, players can select troops using the aforementioned sphere cast systems. They can then point and select an enemy troop, and upon release their troop will attack. The AI opponent in this instance uses basic strategy, with weighted random choices, usually prioritising attacking the lower health opponents. I also implemented a simple "activate" ability to each card, these being Beserker, Heal or Fortify. Beserker increases damage for 1 turn, Heal restores health to a troop, and Fortify does both, at half effect.
  3. Winning the Game - The game continues until one player has no remaining troops on the board. When this happens, the game pauses briefly to show a "You Win!" or "You Lose!" screen, then reloads the game so you can try again.

Shell Texturing and Optimisations

While powerful, VR headsets are still not at the level of the modern day PCs meaning optimisations are super important to the player experience. This is particularly true, as research into VR games indicated that VR experiences running at less than 120fps would often result in the user experiencing Simulator Sickness. Whilst my scene is relatively small, and I could likely have gotten away with the classic billboard grass approach, I took this as an opportunity to develop my shader graph skills, as it felt relevant to the overall challenge of working in VR. The technique I landed on for my grass is called Shell Texturing.

Shell Texturing is a technique I learned about from the game “Viva Pinata” where it was used to create the illusion of fur. The technique is quite simple, by layering transparent planes on top of one another, with each one getting “thinner” than the last, you can create a pretty convincing looking grass that, from a distance, looks incredibly dense and detailed, all at an incredibly low performance cost. With this technique, you can draw one blade of grass or one-thousand with the exact same number of faces.

References and Assets

  • Textures are from the site Free Stylized.
  • Sound effects where created with Chiptone.
  • Troop models and animations are from the Quirky Series Free Animals Pack.
  • Hand model and animation from Valem.
  • All other models, shaders, etc where created by myself with Blender, URP Shader Graph and Unity.