Balloon Physics for Meta Quest 3
I am continuing my experiments with Unity and the Meta Quest 3. I have been working on a balloon physics game. I have been able to get the to (sort of) mimic a downward float of a balloon that is losing its helium. I have been able to get the collisons with the game controller working as well, but the physics is not quite where I would like that to be either.
I definitely have some work to do on figuring out the physics for the balloon, but I am happy with the progress that I have made so far.
The big challenge I am working through right now is trying to figure out a good workflow for development. It is cumbersome to have to put on the headset every time I want to test something. I am looking into ways to make the development process more efficient. There are tools out there such as MQDH that I am looking into as well as the Meta XR Simulator. I am looking forward to trying these out and seeing how they can help me in my development process.
As far as the XR All-in-One Toolkit, I am finding it pretty easy to use. I have been able to get the basic interactions working pretty easily and the prefabs that are available have been pretty drag and drop. I am looking forward to getting more into the XR Toolkit and seeing what else I can do with it for Meta Quest 3 development.
I am continuing to also learn the passthrough mechanics for the Meta Quest 3. I really think that this is going to be a big part of the future of VR, especially with the Apple Vision Pro coming out. The idea that you don’t have to fully be immersed in a VR world is a big stepping stone I think for more mass adoption. I don’t think it will be too long before we start seeing more and more headsets/glasses out in public.
Here are some code snippets that I have been working on for the balloon physics.
You need to make sure your balloon has a Rigidbody and a Sphere Collider and that all of your controllers have a Rigidbody and a Sphere Collider as well. For instructions on how to set all of that up, I found a great tutorial on YouTube by Valem Tutorials that has been a great starting point for me. Make sure to start with this one: How to Make a VR Game in Unity and follow along to set up the environment, controllers, and get started with an object that you can interact with. I started with those tutorials and then started working on the balloon physics once I got an idea of how to set up the environment and controllers.
Balloon Float Script
using UnityEngine;
public class BalloonDescentBehavior : MonoBehaviour
{
public float descentStrength = 0.2f; // Adjust this to control the descent speed
public float movementRandomness = 0.1f; // Adjust this for wobble effect
private Rigidbody rb;
private bool recentlyHit = false; // Flag to indicate if the balloon was recently hit
private float hitPauseDuration = 2f; // Time in seconds to pause descent after being hit
private float hitTimer = 0f; // Timer to track pause duration
void Start()
{
rb = GetComponent<Rigidbody>();
if (rb == null)
{
Debug.LogError("BalloonDescentBehavior script requires a Rigidbody component to work.");
return;
}
rb.useGravity = false;
}
void FixedUpdate()
{
if (recentlyHit)
{
hitTimer += Time.fixedDeltaTime;
if (hitTimer >= hitPauseDuration)
{
// Reset flag and timer after pause duration has elapsed
recentlyHit = false;
hitTimer = 0f;
}
}
else
{
ApplyDescentForce();
}
}
void ApplyDescentForce()
{
// Simulate controlled descent by applying a gentle downward force
Vector3 descentForce = -Vector3.up * descentStrength;
descentForce.x += Random.Range(-movementRandomness, movementRandomness);
descentForce.z += Random.Range(-movementRandomness, movementRandomness);
rb.AddForce(descentForce, ForceMode.Acceleration);
}
public void NotifyHit()
{
recentlyHit = true;
hitTimer = 0f; // Reset the timer every time the balloon is hit
}
}
Controller Interaction Script
using UnityEngine;
public class ControllerInteraction : MonoBehaviour
{
public float hitMultiplier = 50f; // Adjust this to scale the force based on controller velocity
public float upwardBonus = 5f; // Additional upward force to apply when hitting from below
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("Balloon"))
{
Rigidbody balloonRigidbody = collision.gameObject.GetComponent<Rigidbody>();
if (balloonRigidbody != null && collision.rigidbody != null)
{
// Use the velocity of the controller to calculate hit force
Vector3 controllerVelocity = collision.rigidbody.velocity;
float hitStrength = controllerVelocity.magnitude * hitMultiplier;
// Calculate hit direction
Vector3 hitDirection = collision.contacts[0].point - transform.position;
hitDirection = -hitDirection.normalized; // Consider adjusting this based on desired behavior
// Add more "upwardness" for hits from below
if (hitDirection.y > 0)
{
hitDirection += Vector3.up * upwardBonus;
}
// Apply dynamic force based on controller speed and direction
balloonRigidbody.AddForce(hitDirection * hitStrength, ForceMode.Impulse);
}
// Notify the BalloonDescentBehavior script that the balloon was hit
BalloonDescentBehavior balloonBehavior = collision.gameObject.GetComponent<BalloonDescentBehavior>();
if (balloonBehavior != null)
{
balloonBehavior.NotifyHit();
}
}
}
}