Playing Pool in Space

This text is a written version of the video above, with future plans to incorporate graphics and figures for illustration.
As I'm working my way through the backlog of videos that were published before this website, I suggest reading the article alongside the video for a comprehensive experience.

If you want to play pool in space, you're going to have a hard time keeping the balls on the table, as the low gravity will send them flying everywhere. So obviously a pool table on a spaceship would need who have some sort of embedded magnet to pull the balls down, or rather, against the table, to emulate some sort of gravity. But what if instead of trying to make up for that lack of gravity, you sort of... Lean into it?

VR

Hi there! Welcome to my spaceship. That's where we're going to make a 3d pool game. For starters I set up a virtual reality environment and now I can walk around in the spaceship.
Pool is a very simple game to setup because the physics engine us going to do most of the heavy lifting. So I just need a ball prefab with a rigid body, and disabling gravity, and we're mostly done we'll have to figure out drag and mass later but we could already add a cue.

Rigidbody settings I have found to work best

The cue is just a long cylinder with again a rigidbody, I debated making only the tip a solid collider to prevent bumping into balls by accident, but I figured that was already a part of regular pool so I left it in.

But the balls fly everywhere in the ship so we need some kind of physical boundary to keep them within the play area. I modeled this sort of cube with exits at the corners to make the pockets. Except when I'm outside I can't see what inside, soooo it's shader time!

Play area with default shader Cool Holographic Shader™

Cool, a holographic play area. Now to make the colliders. I wish unity had a sort of... Anti-collider feature to make everything outside the mesh solid, but it doesn't so I hacked together a bunch of walls. Don't worry they'll be hidden. Now in the pockets I just have to place more triggers to know when a ball has exited the uh... Table, and we're mostly done? Ready to start codi- nope! Wait, we still have those ugly pub balls, any decent spaceship needs space themed pool balls. And so, once again, it's shader time

New cool planet balls

So what I settled with for the striped balls was striped planets and for the solid balls have a galaxy texture. Also it's screen space so it looks funny when you move.

Coding

Now we're ready to start coding. Again there isn't much to pool, we just need to detect when a ball enters a pocket, and disable it. Unless it's the white ball in which case we'll simply reset its position. Oh and obviously we need a big button to reset the game. And we're done, we'll let the players figure out scoring and who goes when and penalties, just like a regular game in a pub. Well I say players but this isn't truly a multiplayer game, I'm already very late on making this video and I have plans for another multiplayer project in the near future anyway. So if you want to play this with a friend you're going to have to alternate who is wearing the headset after each strike.

I had to remove the outline effect because it didn't work in VR and I couldn't figure out how to fix it, but other than that I was able to play a game of space pool without trouble. It's pretty hard to get used to but once you get the hang of it it's pretty fun!

Gravity

Although... We're in space. And we're playing with planets... I wonder what would happen if we were to turn gravity back on, but this time, proper space gravity, where each planet attracts each other, and can orbit around other planets. If I recall my high school days correctly, the simple formula for gravity between two objects is this, where G is a constant, which we'll gladly tweak to get cool looking results, m1 and m2 are the mass of each of the two objects, and is the squared distance between them. To apply this force we just need to iterate over every ball, then again to get each pair of balls, and add the force to one of the balls. With this double loop we will visit each pair of planets twice, once in each direction.

foreach (var ball1 in poolBalls)
{
    if (!ball1.gameObject.activeInHierarchy) continue;

    foreach (var ball2 in poolBalls)
    {
        if (ball1 == ball2) continue; // Don't want to risk a division by zero now do we
        if (!ball2.gameObject.activeInHierarchy) continue;

        Vector3 diff = ball1.transform.position - ball2.transform.position;

        float strength = g * (ball1.Rigidbody.mass * ball2.Rigidbody.mass) / diff.sqrMagnitude;

        ball2.Rigidbody.AddForce(strength * diff.normalized, ForceMode.Force);
    }
}

The result is uhhhhh... Chaotic to say the least. The interesting thing though is if I exclude the white ball from receiving gravity forces and lower the strength of gravity, the other balls end up pooling together and it's easier to aim at the big cluster. But even then, it's extremely hard to get a single shot right as the targets are always moving. But it's fun to have my own planetary system inside my spaceship, and I kinda like it.

Conclusion

That's it for this project, if you have VR gear you can download the game on itch.io, it's a bit rough around the edges but do let me know what you think in the comments of the video. I'm also always on the lookout for cool VR games as there aren't many of these out there, and I have finished the absolute masterclass that is The Last Clockwinder, so any suggestion is welcome. Have a good one, and I'll see you in the next video.

Credits

Assets

Music