project showcase

FitLab - Health EDU

Created a beginner-friendly VR app for the Oculus Quest 3 that guides users through interactive bodyweight exercises, offering real-time feedback and educational content on proper techniques.
Project Type
Personal Project
Timeline
2023
Developer
Solo Developer & Designer
Further Demonstration
Code Available Upon Request

VR Racing App

Developed a Virtual Reality racing app, incorporating 3D physics and immersive gameplay to create an engaging and interactive driving experience.

scroll

Project Overview

Scope

Concept: 

Developed a beginner-friendly VR application using Unity for the Oculus Quest 3 that guides users through interactive bodyweight exercises. The platform provides real-time feedback and educational content on exercise techniques, promoting accessible fitness education. By combining immersive VR technology with fitness instruction, the application makes learning exercise routines engaging and accessible, encouraging users to maintain a healthy lifestyle.

Technical:

Exercise Selection and Animation Control

Implemented a system that allows users to select different bodyweight exercises and view animations demonstrating proper form. This feature helps users understand how to perform each exercise correctly.

Code Snippet:
1public class ExerciseSelection : MonoBehaviour
2{
3    public Animator characterAnimator; // Assigned in the Unity Inspector
4
5    void Start()
6    {
7        // Initialize to Idle state
8        characterAnimator.SetBool("IsJumpin", false);
9        characterAnimator.SetBool("IsSquats", false);
10    }
11
12    // Called when Jumping Jacks is selected
13    public void SelectJumpingJacks()
14    {
15        characterAnimator.SetBool("IsJumpin", true);
16        characterAnimator.SetBool("IsSquats", false);
17    }
18
19    // Called when Squats is selected
20    public void SelectSquats()
21    {
22        characterAnimator.SetBool("IsSquats", true);
23        characterAnimator.SetBool("IsJumpin", false);
24    }
25
26    // Called to return to Idle state
27    public void ReturnToIdle()
28    {
29        characterAnimator.SetBool("IsJumpin", false);
30        characterAnimator.SetBool("IsSquats", false);
31    }
32}
33
  • The ExerciseSelection class manages the animations for different exercises by setting animator parameters. When an exercise is selected, the corresponding animation parameter is set to true, triggering the animation. This allows users to see a visual demonstration of the exercise.

Real-Time Feedback and Energy Meter

Developed a feedback system that monitors user movements and provides real-time guidance and encouragement. An energy meter visually represents the user's progress and effort during exercises.

Code Snippet:
1public class UnifiedExerciseFeedback : MonoBehaviour
2{
3    public Animator characterAnimator; // Assigned in Inspector
4    public EnergyMeter energyMeter; // Reference to EnergyMeter
5
6    public Transform headsetTransform; // Assigned in Inspector
7    public Transform leftControllerTransform; // Assigned in Inspector
8    public Transform rightControllerTransform; // Assigned in Inspector
9
10    public float squatThreshold = 0.2f; // Threshold for squat detection
11    public float jjjThreshold = 0.2f; // Threshold for jumping jacks detection
12
13    private float squatStandingY;
14    private float jjjStandingY;
15
16    private bool squatStarted = false;
17    private bool jjjStarted = false;
18
19    void Update()
20    {
21        bool isSquats = characterAnimator.GetBool("IsSquats");
22        bool isJumpingJacks = characterAnimator.GetBool("IsJumpin");
23
24        if (isSquats)
25        {
26            if (!squatStarted)
27            {
28                squatStandingY = headsetTransform.position.y;
29                squatStarted = true;
30            }
31
32            HandleSquatFeedback();
33        }
34        else
35        {
36            squatStarted = false;
37        }
38
39        if (isJumpingJacks)
40        {
41            if (!jjjStarted)
42            {
43                jjjStandingY = (leftControllerTransform.position.y + rightControllerTransform.position.y) / 2f;
44                jjjStarted = true;
45            }
46
47            HandleJJJFeedback();
48        }
49        else
50        {
51            jjjStarted = false;
52        }
53    }
54
55    void HandleSquatFeedback()
56    {
57        float currentY = headsetTransform.position.y;
58        float deltaY = currentY - squatStandingY;
59
60        if (deltaY < -squatThreshold)
61        {
62            // User is squatting down
63            energyMeter.ModifyEnergy(0.05f);
64            // Provide positive feedback (e.g., update UI or display message)
65        }
66    }
67
68    void HandleJJJFeedback()
69    {
70        float leftY = leftControllerTransform.position.y;
71        float rightY = rightControllerTransform.position.y;
72        float averageY = (leftY + rightY) / 2f;
73        float deltaY = averageY - jjjStandingY;
74
75        if (deltaY > jjjThreshold)
76        {
77            // User is raising arms for jumping jacks
78            energyMeter.ModifyEnergy(0.1f);
79            // Provide positive feedback
80        }
81    }
82}
83
  • The UnifiedExerciseFeedback class monitors the user's movements by tracking the positions of the headset and controllers. It calculates changes in position to detect when the user is performing squats or jumping jacks. The HandleSquatFeedback and HandleJJJFeedback methods provide real-time feedback by adjusting the energy meter based on the user's actions.

Energy Meter Implementation:

1public class EnergyMeter : MonoBehaviour
2{
3    public Slider energySlider;  // The UI Slider for energy
4    public float maxEnergy = 100f;  // The maximum energy level
5    private float currentEnergy;
6
7    void Start()
8    {
9        // Initialize energy at half for a challenging start
10        currentEnergy = maxEnergy / 2;
11        UpdateEnergyUI();
12    }
13
14    public void ModifyEnergy(float amount)
15    {
16        currentEnergy += amount;
17        currentEnergy = Mathf.Clamp(currentEnergy, 0f, maxEnergy);  // Ensure energy stays within bounds
18        UpdateEnergyUI();
19    }
20
21    void UpdateEnergyUI()
22    {
23        energySlider.value = currentEnergy / maxEnergy;  // Normalize value between 0 and 1 for the slider
24    }
25}
26
  • The EnergyMeter class manages the energy level displayed to the user. It increases or decreases the energy based on the user's performance, providing a visual representation of their progress and motivating them to continue exercising.

Impact

  • Immersive Experience: The application serves as an interactive tool for learning proper exercise techniques. By providing visual demonstrations and real-time feedback, it helps users understand and perform exercises correctly, making fitness education more accessible and engaging.
  • User Experience: The immersive VR environment captures users' attention and encourages active participation. The real-time feedback and energy meter gamify the exercise experience, fostering motivation and a deeper interest in maintaining physical health.
  • Innovation: By leveraging VR technology and motion tracking, the project demonstrates how technology can enhance fitness education. It offers an innovative platform that can be used in various settings, such as home workouts, fitness centers, or rehabilitation programs, highlighting the potential of VR in promoting healthy lifestyles.

Heading

Client
Apple
Date
November 2023
Role
Designer & Developer

Team section

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse tincidunt sagittis eros. Quisque quis euismod lorem.