Jump to content

Recommended way to get time between last frames in Observables? (i.e. deltaTime)


ShiftedClock
 Share

Recommended Posts

I'm new to Babylon, and am trying to determine how to use Observables for game logic in a frame rate independent way. I may be approaching this incorrectly, because there are many parts of Babylon that I'm unfamiliar with, such as Behaviours and Animations (so it may be an XY problem). Help would be much appreciated.

In most game engines there's some deltaTime object, but I haven't been able to find anything similar to deltaTime in Babylons docs.

In this example an observer is created that increments a global var alpha by 0.01 each frame. Ideally that would be alphaChange * deltaTime. I'm just not sure where such a deltaTime object lives in Babylon.

If I add a parameter to the observer's callback (i.e. function (parameter) {...}) I see that it actually passes the scene into the callback. So is there a way to get deltaTime from the scene object?

I've looked at the SceneInstrumentation object, but I'm not sure it's the right place to be looking. There's even references to deltaTime in Scene.useConstantAnimationDeltaTime.

Three.js has a built-in Clock that serves this purpose, so I implemented my own based on it. But when using it for animating properties in Babylon I get very noticeable stuttering.

Any insight would be much appreciated.

Link to comment
Share on other sites

Welcome to the forum!.  deltaTime is available on the engine:
http://doc.babylonjs.com/api/classes/babylon.engine#getdeltatime
http://doc.babylonjs.com/api/classes/babylon.scene#getengine

scene.getEngine().getDeltaTime()

I've never needed to go to this level for animations.  Can you share your animation code as a playground?  I have multiple smooth animations running simultaneously without any low level coding, but not sure what you are animating.

Link to comment
Share on other sites

Thank you so much. I'm just animating properties of objects, like so, in createSphere.js:

let sphere = new BABYLON.MeshBuilder.CreateSphere("sphere", {diameter: 2}, scene);
sphere.Behaviours = [];  // Shoehorning the Behaviours array onto the Mesh object.

sphere.Behaviours.push(function(deltaTime) {
    this.position.x += 0.001 * deltaTime;
}.bind(sphere));
// Insert more "Behaviours" here, from a central file.

sphere.Update = function (scene) {
    let deltaTime = engine.getDeltaTime();
    for (let i=0; i<sphere.Behaviours.length; i++) {
        sphere.Behaviours[i](deltaTime);
    }
}.bind(sphere);

Later in the scene's initialization, the gameObjects are loaded and their Behaviours registered:

let sphere = createSphere(scene);
scene.gameObjects.push(sphere);

for (let i=0; i<scene.gameObjects.length; i++) {
    let go = scene.gameObjects[i];
    scene.onBeforeRenderObservable.add(go.Update);
}

I'm trying to create something like an Entity Component System, so that I can compose GameObjects from Behaviours, and in turn compose scenes from those GameObjects.

This project has an emphasis on smooth animations, defined in code. I'm rendering everything in a shader using raymarching (i.e. meshes are for physics, not drawing), and just using the game engine to keep track of the game world. Every frame the game Updates, then sets shader variables using gl.uniform1f, etc.

I come from Unity (with some Phaser, CreateJS, and Love2D experience), so learning a new engine is always a process of "Out of the techniques I've learned over the years, which ones fit how this engine works? Do I have to define my own game loop? Is there a built-in Entity Component System? Or do they do things in a completely new way to me?"  I'm very open to learning new ways, but the initial learning can be cumbersome.

Does Babylon have a preferred way of creating GameObjects in an Entity Component style? Or even a place to store them in the scene objects? Or am I approaching things the wrong way for Babylon? I may be trying to fit the ECS pattern to an engine that doesn't want it, for instance.

Since I started using scene.getEngine().getDeltaTime() the stuttering has gone away. It's a joy to work with again, thanks Brian. :)

Link to comment
Share on other sites

There is definitely a learning curve with new engines - For me the best part is when something is new and there is a lot of learning!  There are some built-in animations and not sure how far along that will take you.  What kind of game are you building?
One thing about delta time only is that for Easing/(s)lerp the deltaTime is not enough - maybe you store your progress or have constant animations where that is obviously not an issue.

Here is a simple PG on position.x (like your behaviour) with built-in animations.
https://playground.babylonjs.com/#3BSUZB#1

There are some other tricks too - everything is well documented:
https://babylonjsguide.github.io/gamelets/Sequence.html
https://doc.babylonjs.com/features/animations

Link to comment
Share on other sites

Thanks for the links. I'll play around with BABYLON.Animation, it seems like the more engine-friendly way of achieving what I want.

So I'm going to make a base GameObject, and add components to it, such as the Mesh, and Animations. Although I'm not making a game right now, more of an animation study, but I still think in terms of GameObjects.

Here's a video of a short game I made for a game jam a few years ago, that used raymarching extensively (i.e. nothing on-screen was rendered with a mesh). It was made in Unity, but there are certain technical abilities that I need for my upcoming projects that Unity doesn't have (dynamic shader compilation), which *are* available in JS (via WebGLRenderingContext.CompileShader).

So I'm starting by replicating the principles of animation using raymarching. This isn't a game itself, but rather a project for discovering techniques that will bring more life to my raymarched games. The followup projects will then use the techniques I discover here in order to create appealing characters based on basic shapes (spheres/ellipsoids, boxes, cones, etc.).

I'm evaluating Babylon and Three based on which would work better for these projects, but I'm leaning heavily towards Babylon right now. The documentation, the physics support, this forum (!), and the playground are all hugely appealing. There's also the fact that Babylon's CubicBezier constructor works with cubic-bezier.com's output, while Three's CubicBezierCurve doesn't. That may seem like a small thing, but this whole project is about defining animations, so I anticipate tinkering with cubic-bezier.com a lot.

I'm curious about Babylon's Editor as well, and Spector. So many cool toys! Thanks again for pointing me in the right direction.

Link to comment
Share on other sites

7 hours ago, Steven Vass said:

Does Babylon have a preferred way of creating GameObjects in an Entity Component style?

Unlike some other platforms - BabylonJS is very UNopinionated.  The Entity Component System of Unity follows a common design pattern of "has a" - instead of "is a" of traditional object oriented design, which is really nice for avoiding complex inheritance hierarchies.  Composition over inheritance has a lot of benefits in many situations.

BabylonJS Animations can attach to anything even a plain javascript object and animate any property. That's really the beauty of the dynamic languages and as you know also with dynamic shader compilation :)

There is one relatively new part of BabylonJS that does follow your idea of composing behaviours, so hopefully this provides some good ideas/code, too:
https://doc.babylonjs.com/features/behaviour

Attaching a gizmo to a mesh is one example.  You can attach() and detach() them on the fly even to cameras :)
https://github.com/BabylonJS/Babylon.js/blob/3d906d11a0b2449205daec660cf266f9f8294ff2/src/Behaviors/Cameras/babylon.autoRotationBehavior.ts
https://doc.babylonjs.com/how_to/camera_behaviors#autorotation-behavior

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...