3D Pool Update
I’ve had a few inquiries asking how my 3D Pool game is going. So, I thought I’d put together a brief update.
At time of writing, I haven’t done any work on the engine for around 6 months. I’ve been working on other projects – some computer related, some photography related – so unfortunately it’s now been relegated to ‘back burner’ status (along with a bunch of other Unity stuff I was working on).
I decided to dig out the 3D Pool source code over the weekend to see what sort of state it was in. It does still run, and it is playable (on PC and mobile) – but it’s quite buggy. I developed the engine on Unity 4.6. However, since updating to Unity 5.0, the A.I. players no longer play like Steve Davis on crack (they would clear the table in around two and a half minutes from break). With the Unity 5 update, they play like they’re stoned…
A bit of background
As you may have found out elsewhere on my blog, I’m actually a video game artist. I decided to learn to code in order to improve my chances of getting work. It’s hard to make money just providing artwork these days.
I opted to create a 3D Pool game purely to learn Unity 3D. Pool has a bit of everything – physics, a set of clearly defined rules, the need for a well designed user interface and artificial intelligence. You need to track multiple objects, and monitor the status of the game (which isn’t as simple as it first looks). From a graphical perspective, you’re working with a fairly limited set of graphics per game. There are no sprawling maps. No complex characters. Just a bunch of balls and a table.
Also, Pool isn’t the intellectual property of some publishing behemoth, you can create a pool product without having to worry about someone suing your ass.
The old JavaScript Versus C# Question…
When I decided to learn Unity, I had to ask the question: Do I learn C# or Unity JavaScript? The general consensus on the internet was C# had a steeper learning curve and didn’t have as many tutorials as Unity JavaScript. Which, I found to be largely true. I read a book called Unity Game Development Essentials by Will Goldstone. That’s an excellent book and covers Unity JavaScript. I used that, in combination with all the reference on the internet in order to learn the language.
But I always harboured this nagging thought that I should have been learning C#, not Unity JavaScript. It turns out those worries were unfounded as when I eventually decided to switch over to C#. I literally switched to C# over a weekend – the languages aren’t really that far apart. The variable declarations are different (not quite as friendly as Unity JavaScript) and you have to include more header information relating to classes. But, I found it easy to make the switch.
One definite plus to switching to C# however, is it is far better catered for by IDEs. By far the worst thing about learning Unity JavaScript was having to use MonoDevelop, which didn’t even support something as simple as code folding for Unity JavaScript. It’s a different story with C# – MonoDevelop is much better. But, better still, when you start coding in C# you can use Visual Studio, which just just fantastic.
The Pool Engine in Unity 4.6
It took a few months to make solid progress with the 3D Pool engine. For the first part of development, I was intent on developing for mobile – so all my UI code was centered around the touch screen. In hindsight, I think this was a mistake. There’s a lot of trial and error involved in getting even the most basic code to work and having to port the build to a smartphone each time was a big time waster. I should really have got the ‘nuts and bolts’ of the engine written solely for PC, then converted that over to mobile. That would have been quicker. I did use Unity Remote for testing – which lets you control your PC build using touch screen on your mobile device. But, compiling and testing on PC, using the mouse, is a lot less hassle.
I eventually got to a stage where the engine had the following features:
- A robust touch user interface that worked in all orientations and all DPI (before Unity Canvas was released)
- Switchable viewing modes. You could play with a single hand in portrait, or two hands in landscape (each mode had its advantages in terms of seeing the table)
- 3D or 2D viewing mode. You could toggle to a dedicated 2D mode that gave you an accurate ‘above table’ view. It sort of felt like ‘two games in one’.
- Full Artificial Intelligence. As I mentioned at the beginning, in A.I. versus A.I. mode the players could clear the table in around 2 and a half minutes. You couldn’t really beat the A.I because they ‘always’ potted the balls when the table was starting to clear. I would have had to make the player’s shots less accurate to make the game challenging (easily done by tweaking the AI).
- Smooth object ball camera tracking. The cue ball and target ball would always remain in the view without jarring (in 3D and 2D mode).
- Passive cue collision. The cue would always avoid obstacles such as the other balls or cushions.
- Ball spin. You could apply spin to affect the shot. Although, this largely resulted in balls flying off the table.
Here are a couple of screenshots taken from the build on my phone:
The Engine in Unity 5.0
Of course, as I’ve documented elsewhere on my blog, I ran into problems when I upgraded to Unity 5.0. Unity 5.0 uses an all-new physics engine. Being so dependent on Unity’s PhysX physics engine, the upgrade trashed the game. To start with, I experienced a situation where the balls would move of their own accord – or wouldn’t stop. No amount of adjustment to the physics materials would fix it.
I eventually figured out that the problem was somehow linked to the mesh-based collision detection. The problem would occur on a simple mesh box. But, it would not occur on a primitive collision box with the same dimensions. So, as a work-around I replaced the collision mesh that formed the surface of the table (including pockets) with a collection of primitive collision objects – and I found the physics engine started to work properly again.
The green boxes represent the table collision:
But there was a caveat. In order to create the table pockets, some of the primitive collision blocks overlapped each other (as you can see above). And, after a while, I noticed that the balls veered / slowed on the boundaries between collision blocks. Not good.
As a work-around, I was going to build a set of primitive collision for the table that used smaller blocks to form the pockets. No overlap. A bit like this:
I know it looks a bit messy, but if done accurately there would be no overlap. I haven’t had time to put the geometry together to test this idea. Maybe it would have worked, or maybe I’d have seen more weirdness as the balls moved over the boundaries. Who knows. But that’s what I had planned.
Other issues…
Irrespective of the above table collision changes, the update to the physics engine caused more subtle problems with the engine. In Unity 4.6, the A.I would sometimes slice the target ball right at at its outermost edge in an attempt to knock it close to 80 degrees. This worked great in Unity 4.6, but in Unity 5.0 the same A.I. would either miss the target ball completely, or the struck ball would miss the target pocket. With these extreme angle shots, the physics didn’t seem as accurate…
I also came across another problem. On straight shots, unlike before, the cue ball nearly always follows the target ball ‘in off’ into the target pocket. I tried modifying all aspects of the physics to prevent this, but wasn’t able to. I added the facility to add ball spin when taking a shot. So you could add a bit of ‘back spin’ when taking the shot. But, the cue ball still followed the target ball into the pocket.
What Now?
Well, developing the Pool engine served the purpose. I managed to learn Unity SDK and had a lot of fun in the process. As for finishing the game… Well, if I’m honest, I think the code would benefit from being re-written to be better structured. I’d also covert it to C#. I’ve already used parts of the game in other products (the touch code, for example). And the A.I. system – which does all kinds of raycasting to build up a ‘risk assessment’ of the table – could definitely be upgraded and reused.
But, there are a number of hurdles to cross – the weird table collision, the shot inaccuracy, the ‘In Off’ problem. To be honest, I think that if I was going to pick back up on this project, I would likely bite the bullet and attempt to write the code that actually controlled the ball movements and rotations, bypassing the the Unity physics engine all together. But then, I’m probably underestimating the complexity of doing all that maths 🙂 It’s worth noting though, that I used good old fashioned SIN/COS/TAN calculations when writing this engine for calculating the shot angles. So I finally got to grips with all that boring geometry stuff I couldn’t be arsed to learn at school….
Finally, for anyone thinking about writing a game, I’ve made my Trello board public so that you can get some indication of what’s involved in writing a game. I use Trello a lot for keeping track of tasks, it’s perfect for game development – especially when you’re working as a team in separate locations.
As I say, I have no plans to further this project. But if anyone else out there has found solutions to any of the above, I’d be interested to hear how you tackled them!