Happy New Year!

Well, 2016 has certainly been, shall we say, an “interesting” year!  Perhaps many people will be glad to the see the back of it, but somehow I’ve a feeling 2017 won’t be any less eventful.  Anyway, here’s hoping the new year brings good things to you all!

Back in my little GearBlocks corner of the world, in many ways things have progressed pretty well this year, getting through the Unity 5 hurdle was definitely a big step forward.  I’m a bit frustrated to not be further ahead with the game generally by now though.  I’ll just have to keep chipping away at it, it’ll get there eventually.  I’m very appreciative to all those of you who have played the demo, built some amazing creations, and given me really useful feedback.  It helps motivate me to keep going!

Over the past couple of months I’ve been working on a bunch of different things.  I was looking at improving the construction controls, but kinda got stuck with “designer’s / programmer’s block” if you can call it that.  So while thinking on this some more, to keep progress going I did several other smaller tasks:-

  • Made a load of new parts (gears, control wheels, suspension parts, connectors and more).
  • Added more user settings (e.g. mouse look sensitivity and camera FOV).
  • UI tweaks.
  • Rendering effects.
  • Unity upgrade.
  • Bug fixes.

Next week I plan on going back to the controls improvements, mustn’t procrastinate any longer!

Dev update

It’s been a while since the last update, so I thought I’d do a quick post on what I’ve been up to!  A couple of weeks were taken up with travelling back to the UK for a bit, and I was sick all last week which took me out of action unfortunately.  I have been working on the game though over the past several weeks…

First person controller

The current first person camera controller in the game is basically a prototype implementation.  It’s buggy and missing a lot of features, for example: camera smoothing, crouching, head bob, and so on.  My plan was to switch over to the excellent UFPS from Opsive (available on the Unity asset store: http://u3d.as/2Jc) which has all these features and more.  Unfortunately that didn’t work out, mainly because I couldn’t bring across only the code I wanted from UFPS (character and camera controller) without either modifying it or also including a lot of other stuff I don’t need (e.g. inventory, weapons, damage etc.)

I think UFPS is great as a starting point for a first person game, but trying to integrate it in at this late stage of a project probably isn’t practical.  So now my plan now is to keep what I have and gradually improve it, probably stealing code from UFPS as necessary!

Deprecated networking API

I have a rudimentary networked multiplayer mode for GearBlocks, and in fact even the single player mode runs through the same code paths.  I want to keep this working so that I have a good starting point should I wish to revisit multiplayer in the future.  Right now I’m using the old Unity networking API, which was causing a bunch of annoying “obsolete API” compiler warnings, because it’s recently been deprecated in favour of their new system, UNET.

I looked into what it would take to upgrade to UNET, using their high level API (HLAPI).  Unfortunately there were all sorts of awkward problems with this (like needing to derive from NetworkBehaviour, which didn’t play nicely with my generic singleton implementation for some reason).  The whole thing was turning into a massive change that would break the entire game until I completed it.  Not to mention it’s still fairly early days for UNET and it’s changing quite a bit as Unity continues to develop it.

Besides, ultimately I might be better off using their low level networking API, but that would obviously take even longer to implement.  Or, perhaps using a third party system like Photon Bolt would be a better way to go.  I’d need to spend a lot more time on this to figure out the best thing to do, so I’m leaving it for now.  Instead, I um…disabled those pesky deprecated API warnings, there you go, job done!

What’s next

So, it’s generally been a frustrating few weeks, hopefully I can get back to being more productive now!  I’ve been prototyping something for the game, not sure if it’ll work out yet, but I’ll be continuing with that.

Also, I’m going to work on improving the construction controls, in particular to help new players pick up the game and get started.  Well, that’s the plan anyway!

GearBlocks Demo 0.4.6095

GearBlocks Demo 0.4.6095

First pass of new “Desert proving ground” map for GearBlocks, this (and other maps too eventually) will replace the old procedurally generated maps.

I’ll be adding more details to this map as I go, but for right now it has a variety of terrain types (sand dunes, rocks, large and small bumps), as well as (most importantly) a large flat area to build on!

GearBlocks Demo 0.4.6034

GearBlocks Demo 0.4.6034

Unity 5 physics issues finally sorted

At long last, I have resolved all the remaining physics problems I was having with Unity 5!  As I mentioned in my previous blog post, I had solutions that I was working on for most of these issues, but the one thing I wasn’t sure about was how to fix the joint velocity drives.

Configurable joint drives

One of the things that changed from PhysX 2.X and 3.X, is the way that joint drives are configured.  They no longer have a mode flag to specify whether they are position or velocity drives.  Instead, if you want a “position drive” you set the drive’s spring value to be non-zero, if you want a “velocity drive” you set its damping to be non-zero (and if you set both to non-zero the drive behaves as a damped spring).

The question is, what non-zero value to actually use?  Nothing in the Unity or PhysX documentation seems to help much here.  I use both position and velocity drives in the game, and I want them to be constrained only by the maximum force that the drive is set to use (in other words, fully “stiff” as if the spring or damping values were effectively infinite).

So I tried setting them to float.MaxValue, but this caused some odd behaviour.  Drives configured to be “velocity drives” would not work if the rigidbody’s mass was below some threshold, and those configured as “position drives” would sometimes cause Unity to crash completely without any warning.  In the end, after some experimentation, I simply used a smaller (but still very large) value for the spring / damping settings.  This seems to work alright, although I’m somewhat concerned it could still fail in some unforeseen situations!

Simulation update rate

As I mentioned in the last post, swapping joint rigidbody ordering (i.e. owner vs. connected) helped a lot to improve simulation stability at high angular velocities.  Unfortunately it was still not quite enough to get back to Unity 4 / PhysX 2.8 levels of stability.  The simulation update rate also needed to be increased a bit (by reducing Time.fixedDeltaTime), at the expense of performance.  So, as a compromise, I will be exposing a setting in the game to allow the sim update rate to be adjusted.  Advanced users can change it based on the construction that they’re building, and how fast their computer is.

Last few bugs

With these issues taken care of, there’s now nothing to prevent the upgrade to Unity 5.  I’m still working on migrating away from some deprecated APIs and fixing a few remaining (non physics related) bugs, once this is done I’ll be able to put out another demo release.

Unity 5 physics update (again)

Over the past few weeks I have been working on resolving the physics issues that are preventing me from upgrading to Unity 5.  For those that don’t know, Unity 4 uses PhysX 2.8, whereas Unity 5 uses PhysX 3.3, the new version being a major re-architecture of the PhysX implementation as I understand it.  The resulting differences in physics behaviour have caused me a fair few problems.

A while back I outlined these problems, but I’ll run through the remaining ones again here, along with the current state of play for each of them.

Collision contact tolerance
The collision contact tolerance is important to set up so that adjacent parts in a construction have enough leeway to slide past each other without jamming up, while also not allowing parts to sink too far into each other.  In order to replicate the same contact behaviour in Unity 5 as in Unity 4, it turns out you have to set the collider’s contactOffset to the same value you had Physics.minPenetrationForPenalty set to in Unity 4, and then also shrink the colliders by this same amount in all directions.  This shrinking was a bit annoying to have to do, as I use the collider dimensions for other stuff, but at least it seems to have done the trick.

Instability at high angular velocities
Physics engines, given that they integrate at discrete time intervals (rather than being continuous like IRL physics), often struggle with objects with high velocities, the only way around this really is to update the simulation more often with a smaller time step.  So in order to allow for rapidly spinning parts like gears, axles, etc. in GearBlocks I have to use a small time step (Time.fixedDeltaTime), otherwise things would become unstable and start wobbling all over the place.  However in Unity 5, I had to set it to be even smaller in order to get the same level of stability, unfortunately offsetting much of the physics performance gains over Unity 4!

Each joint connects two rigidbodies, one being the owner of the joint, the other the connected rigidbody.  One thing I discovered that helps with stability is to set up the owner / connected relationship in a particular order.  The PhysX documentation recommends having the rigidbody with the higher mass of the pair be the owner.  I found that it was even more effective to have low velocity parts (e.g. blocks, motors, etc.) be the owner, and those with high angular velocities (e.g. axles) be the connected.  Setting joints up in this way meant I could get stable behaviour in Unity 5 without having to reduce Time.fixedDeltaTime by quite so much.  Unity 5 / PhysX 3.3 seems super sensitive to this ordering, whereas Unity 4 / PhysX 2.8 doesn’t seem to care.  It’s tricky to set up though because I don’t know ahead of time which parts of a construction are going to be the fast spinning ones (and I can’t change the ordering once the construction is unfrozen and moving without causing other problems which I won’t get into here).  So right now I’m working on something that’ll use an educated guess and hopefully get it right in most cases.

Unstable collision behaviour
In Unity 5, for some constructions when contacting flat ground, their collision response with the ground isn’t very stable and they can keep bouncing around for ages after the initial collision.  What’s more, this gets worse the smaller the simulation time step.  Setting up the joint rigidbody ordering as I discussed above seems to reduce this instability though.  Also setting the rigidbody’s maxDepenetrationVelocity to a smallish value helps too.

Joint drives (used for motors)
I was finding that the same force numbers for joint drives were giving different results between Unity 4 and 5.  I discovered that in Unity 4 the JointDrive’s maximumForce value should be multiplied by Time.fixedDeltaTime (which is what I was doing), whereas in Unity 5 it should not.  In other words, Unity 4 expects an impulse value, but Unity 5 wants a force value!

Configurable joint velocity drives
Once I grasped the differences in the way the settings behave, I was able to get these working, sort of.  I found that they still don’t work if the rigidbody’s mass is below some threshold, and there also seems to be a dependency on Time.fixedDeltaTime.  Not really sure what’s going on here, I need to do some more investigation on this one.

Getting there, but more to do

Well, if anyone out there is still in the process of upgrading to Unity 5, I hope my findings might be useful to you!  I’m hopeful I can resolve all this stuff soon, after which I still have to migrate away from some deprecated APIs, and work around a bunch of other bugs and issues I’m having in Unity 5.  Anyway, I can’t wait to put this upgrade to bed so I can get back to actually making the game!