Category Archives: Game jam

Even more animation with PlayCanvas

This dev blog is proving to be far more time consuming than I expected. And I don’t even get paid to write it. 🙁

Avatar movement broadly breaks into three parts:
 1. Motion (forward, back, turn, fast slow, etc.)
 2. Animations (walk, run, turn, etc.)
 3. Collision
At first glance, this looks ripe for a separation of concerns. Indeed, initial experimentation was promising. Movement and an appropriate animation were displayed on key press events/triggers in completely separate sections of code, while collision response was handled independently by the physics engine. However, with more motions and animations (e.g. jumping) it becomes necessary for the different parts of the system to interact. For instance, while the avatar is jumping all key presses are ignored, so the movement code needs to know when the jump animation has stopped.

Animation Control
It turns out that Finite State Machines aren’t suitable for animation control. I tried state-machine.js, which is a fine tool, but FSMs only work when there only a few animations to wrangle. Even with only four or five animations, I faced a combinatorial explosion, plus much repetition and fiddly edge cases.

I’d prefer to use an existing, built-in animation manager (such as Unity’s) but PlayCanvas doesn’t provide one, yet. Although, Mike Talbot has done some work on Root Motion and Animation Blend Trees.

For now, I’m using a “tabular” method, it’s wasteful, but fairly easy to understand and maintain, It’s not the best method by any means but it’ll have to do for now.

AnimationBlending.animations = {
 stand: { default: 'idle.json',        forward: 'idle.json',        left: 'idle_left.json',   right: 'idle_right.json',  back: 'idle.json',        jump: 'jump.json', },
 walk:  { default: 'walk_back.json',   forward: 'walk_back.json',   left: 'walk_back.json',   right: 'walk_back.json',   back: 'walk_back.json',   jump: 'jump.json', },
 run:   { default: 'run_forward.json', forward: 'run_forward.json', left: 'run_forward.json', right: 'run_forward.json', back: 'run_forward.json', jump: 'running_jump.json', },
};

Extending animations/behaviour is difficult. Adding a relatively simple jump action was awkward, requiring an additional pause, to accommodate a squat down before the jump proper.

I’m now at bit of a loss as to where to go from here. I can have broken animation or incomplete movement (i.e. no jumping) or spaghetti code to paper over the cracks. Back to the drawing board?

Summary
Animation is easy. Animation management is hard

Animations are specific to a given model and can’t be shared/re-used, and it can be a pain to find the animation that does just what you want.

PlayCanvas’s animation system lacks maturity. In particular
 ● there are no animation related events
    (e.g. to alert when an animation has ended)
 ● there is no mechanism for mixing animations
    (using parts from different animations, rather than just blending between whole animations)

Consequently, in PlayCanvas, animations need to be kept simple or even avoided all together, say, by writing an FPS and having static characters (as in “Thomas Was Alone“).

“Thomas Was Alone” uses simple shapes to reduce animation

Collision fun

The project can be found here.

So, another week, another problem to solve.

After working through the wrinkles of importing FBX files (with moderate success), my attention turned to animation and moving my avatar (Pearl) around a scene.

Quite quickly it be apparent that there was one section of the map where she fell straight through apparently solid ground. Oh joy! Time for another fluffing diversion!

Oh noes! And you don’t get the full flicker effect here!

My first impulse was to just plug the gap with some box colliders, but that was the too fiddly and inaccurate, and not a scalable solution.

After some experimentation, the faces of making up the gap seemed to be inverted – if turned over through 180° the collider worked. Perhaps the normals were inverted or the winding order of some of the faces were wrong. After further experimentation, this proved to be no practical use and didn’t lead to any practical solution.

Will Eastcott of PlayCanvas suggested subdivision. Clara.io doesn’t do subdivision automatically, but manually subdividing the faces fixed the problem. Again, manual subdivision is not a practical solution and is only of value in small, limited situations.

A search to do automatically subdivide lead to Blender.

The new model looked like pants as parts were too dark.

Original

Looking shady.

The exported subdivided mesh seemed to work fine when tested, but not when added back into the original model as a collider. It turned out that the subdivided mesh was scaled and translated.

Back to our scheduled programme

I simplified the collision by using only the base mesh and using cylinders for trees. This also stops Pearl from bouncing off leaves, and allows her to paddle through water.

I added an animated pulsing effect to random shapes for some visual interest.

Summary

If a collision mesh isn’t working properly:

  1. Subdivide in Blender (Clara.io won’t do it automatically, Maya and Max cost money).
  2. Test that the subdivided mesh actually works.
  3. If it looks good use it.
  4. If it looks like pants, add it to the original as a collision mesh but watch out for changes is scale and position.

Comments

There was a proliferation of PlayCanvas projects to preserve existing work and separate oh, so very many new experiments to test out ideas and such.

I’m having to pick up more than a passing acquaintance with a varied group of tools whether I want to or not. I’m not a fan of Blender, but it looks like the best option in many cases. I’d much prefer Clara.io, but it just doesn’t have all the features I need.

More FBX — this time with Mixamo and Babylon.js

Ah, yes! FBX, the sodding nightmare that just keeps on giving. I just want to get on and do some programming! Is that too much to ask?!?

Model source Mixamo’s Pearl.fbx (other formats supported: DAE and BVH).

Babylon.js has no built-in support for FBX  , requiring conversion with their

Unity3D ➔ Babylon exporter

It looks like normals are inverted, clipping is set incorrectly or something similar.

Additionally, the normal map texture needs to be marked as such. Fixing that is only a slight improvement.

After a bit of research it turns out to be a transparency setting.

Now we’re cooking.

Babylon standalone converter

Nope! It looks inside out.

The import shows similar problems Unity. Unfortunately, despite messing around with normals, winding order and transparency in Babylon, I haven’t been able to rescue the model.

Blender3D ➔ Babylon exporter
The Blender exporter really choked on this model.
The import looks OK, apart from the missing textures.

Dude! Where’s my textures???

However, it complained about being unable to export due to an armature.

Oh noes!

Once the armature was removed, something was exported.

Lookin’ shady. Too shady.

I’m not a user of Blender (I’m not a fan of it’s idiosyncratic interface, and dammit! I’m a doctor… er, programmer not an artist) so I called time on this abortive effort.

Clara.io
Clara.io doesn’t quite make it. Which is a pity as I really like it.

Eye-balls around the ankles is not a good look

Alas, the foot ‘n’ balls issue persists in the export.

Summary
FBX is a complex and proprietary format, clearly not all APIs can handle all the variations. We should probably be grateful that we get any import functionality.

Ultimately, this is a win. I have at least one viable fall back should PlayCanvas fail. I’m also hoping that the Three.js FBX importer gets the kinks ironed out and comes on line soon.

There is further research to be done, e.g. with glTF and JSON formats.

FBX with PlayCanvas

I decided to use the “Pearl” model from Mixamo to experiment with animation and (as it turns out) importing FBX files.

Importing into PlayCanvas is straightforward, simply drag and drop the FBX into the assets area. PlayCanvas converts the file to JSON format with associated textures (in PNG format) and materials. You end up with two JSON files (not sure why) but it’s fairly obvious which is the one to use.

The model can now be added to the scene.

There were problems with the eyes, they were black and the eyelashes were solid black.

Dear god! No!

Frankly after a long day I was fed up and knocked off for the day, after leaving a request for help on the PlayCanvas forums.

After some very helpful suggestions by Steven Yau, I was able to tweak some settings to correct the model.

A black specular colour tint fixed the eyes.

Looking good

Setting the opacity blend type to alpha fixed the black eyelashes, but caused them to act as a stencil straight through the poor model’s head when viewed from below.

Will the horror never end!?!

Setting opacity “alpha to coverage” fixed the clipping eye syndrome.

Finally! Yay!!!

Maybe now I’ll be able to get on with coding… nah… ¯\_(ツ)_/¯

Down the rabbit hole with FBX

PlayCanvas

PlayCanvas does an admirable job of importing FBX models and animations, but animation control seems limited. In particular, there seem to be no events for animation start, end, etc.

Animated Sackboy

This immediately prompted me to stop and reassess all my requirements (and not just animation).

Workflow

  1. I felt that I would almost certainly need more control over animation events than PlayCanvas provides.
  2. PlayCanvas only has version control (very important) for legacy scripts.
  3. A fall back is needed if PlayCanvas fails for some reason (e.g. it’s cloud based, so poor internet or even just high contention would be problematic).

Using an API would immediately address issues 2 and 3. This leaves FBX support as the main issue.

It’s apparent that game creation requires a smooth workflow. Easily getting assets into the game is very important, regardless of their source. Be it pre-existing from a store or newly created by an on-site 3D artist, assets have to come from somewhere, and FBX is one of the more common formats particularly for animation. FBX support is very important.

Checking out the main alternatives:

Babylon.js

Babylon.js doesn’t support FBX directly. I was advised to use the Babylon exporter for Unity or Blender. Alas, the results were not impressive.

Source model (Pearl.fbx) as should be

Model after exporting to Babylon (from Unity and Blender)

Clara.io has an “export to Babylon” option, unfortunately its own FBX import is lacking, and I’m still trying to work out how to add animation to a model.

Model after import into Clara.io

Three.js

Three.js currently only supports ASCII FBX not binary (Takahiro is doing some sterling work to add binary FBX).

Current state of FBX import to Three.js (not released yet)

So, it may be a contender if support is available in time, but for now it’s back to PlayCanvas.

Conclusion (if you can call it that)

Converting 3D assets seems inevitable, to reduce file size and minimise load time (even PlayCanvas converts FBX to JSON).

I will look into FBX – glTF or JSON converters, but for now I’m returning to PlayCanvas (in fact, PlayCanvas engine is also available, so it’s its own fallback).

Choosing a framework/engine

Naturally, I want to work on a WebGL based game. This automatically makes it web based with all the attendant benefits and disadvantages.

My first choice is PlayCanvas (free version), which is like a (simplified) on-line Unity. The only alternative that I know of, GooCreate, sadly declared bankruptcy a few months ago.

Pros

  • on-line editor (drag ‘n’ drop)
  • six years old (so relatively mature and stable)
  • support is through forums for free accounts
  • FBX support
  • collaboration

Cons

  • no download for off line storage
  • no version control
  • limited animation control

Develop 2017 Game Jam Preparation

OK, so, the Develop 2017 game jam “looms” and this time around I thought I’d do some prep to give me a chance at finishing a game. (At past jams I’ve been up against some seriously talent jammers, while I try to not be competitive I do feel I should try harder.)

Past experience has shown me that using tools is enlightening – highlighting possible problems and their solutions ahead of time, so reducing friction development during the jam. Something that this exercise has reminded me of.

I want to work on a WebGL based game. This automatically makes it web based with all the attendant benefits and disadvantages.