The idea behind the update pattern is to make each object in the scene responsible for updating itself. It’s described in detail in gameprogrammingpatterns, but here’s the short version:
function update() {
const delta = clock.getDelta();
scene.traverse(child => {
if(typeof child.update === 'function') child.update(delta);
})
}
renderer.setAnimationLoop(() => {
update();
render();
});
Rather than one huge and complicated update method, there are several simple update methods encapsulated at their point of use.
To avoid traversing the entire scene and using typeof
, you can store only the objects that need to be updated in a separate list and traverse that.
This pattern is very handy for attaching a mixer to an object, for example:
GLTFLoader.load(url, (gltf) => {
const object = gltf.scene.children[0];
const mixer = new AnimationMixer(object);
const action = mixer.clipAction(gltf.animations[0]);
action.play();
object.update = (delta) => {
mixer.update(delta);
}
});
This is wonderfully simple and easy to explain. However, I’ve added a custom property to Object3D
:
object.update = ...
This is generally considered bad practice and I don’t feel entirely happy about this, especially if I put it in my book.
Another possibility is to add the property to .userData
:
object.userData.update = ...
However, the docs explicitly state that userData should not hold references to functions (neither method works with copy or clone, for that matter).
I’ve been trying to think of a simple way of doing this without adding a custom property to Object3D
, and so far I haven’t come up with anything .
Does anybody have any ideas?
Otherwise, @mrdoob, @Mugen87 what do you guys think of reserving the Object3D.update
method to facilitate this pattern? Quite a few people are already doing this, for example Matt DesLauriers: