• Content Count

  • Joined

  • Last visited

Everything posted by ShiftedClock

  1. Thanks John, I was searching the docs for "text" and "font", but overlooked the GUI module.
  2. I'm trying to display a simple text message like "Click anywhere to start" in my game. What is the recommended way to do this? Is CastorGUI the best way? Or is there a part of the normal Babylon API that I'm missing? Thanks.
  3. Hi, how do I make a UniversalCamera rotate on mouse move without the user having to click and drag on the canvas? Sorry for such a noob question, I just can't figure it out. Thanks.
  4. Good to know, thanks. Hopefully if/when someone runs into the same situation, something is there to say "Observables are not registered when using a WebGLRenderingContext." Either in documentation, code comments, or console warnings. Anything but failing silently with no indication as to why the Observables aren't being set up.
  5. Alright, I figured out the problem. This has been one of the most intense multi-day debug sessions I've had in years. After littering babylon.max.js with console.log statements, I narrowed it down to the fact that Engine._onCanvasFocus wasn't firing, while manually adding an event listener to the canvas focus event worked fine. Then I noticed, that code was wrapped in a check for canvasOrContext.getContext. Ding ding ding. Winner winner, chicken dinner, as the kids say. The problem was with this part of my code: let canvas = <HTMLCanvasElement> document.getElementById("canvas2"); let gl = <WebGLRenderingContext> canvas.getContext("webgl"); let engine = new BABYLON.Engine(gl, true, {"preserveDrawingBuffer": true}); I had assumed that since the Engine's constructor took either a canvas or a context, that it would work fine with either. But WebGLRenderingContext doesn't have a .getContext property! I'm not sure if this is intended behavior, but the result is that the check for canvasOrContext.getContext silently fails (babylon.max.js line 11393, sorry, don't have the typescript line number). Since that fails, much of the following option and Observable setup fails. The else part of "if (canvasOrContext.getContext)" is simply missing all of the setup code. So, I think I discovered a bug in the engine? Or at least unintended behavior. I don't have the time or inclination to make the fixes and submit a pull request (this is my first week with Babylon afterall), but I hope someone can. For now I've switched back to passing canvas to the engine constructor, and everything works as expected. Side note: Having Scene.attachControl and Camera.attachControl have the same method name, while doing very different things, was a source of confusion for me. Edit: This may be intended behavior, just undocumented. It's very unintuitive that Observables aren't properly setup when passing a WeblGLRenderingContext to Engine, while HTMLCanvasElement works fine. The fact that you can't addEventListener on WebGL contexts is probably the source of that difference. A reasonable compromise would just be mentioning in the documentation that initializing Engine with a WebGlRenderingContext prevents (some?) Observables from being setup. Edit2: Apparently you can get the canvas from the context, so event listeners could still be setup, so long as the canvas is not null.
  6. Thanks for putting that Playground example together Wingnut. It's working for me, but my local Typescript implementation is still not working. Using window.addEventListener for the Action works fine: let yPress = new BABYLON.ExecuteCodeAction( { trigger: BABYLON.ActionManager.OnKeyDownTrigger, parameter: "y" }, () => { console.log("y pressed"); } ) window.addEventListener("keypress", (event) => { if (event.key === "y") { yPress.execute(); { }); That works. But doing this still does nothing: scene.actionManager = new BABYLON.ActionManager(scene); scene.actionManager.registerAction(yPress); Yet the actionManager calls ExecuteCodeActions for OnEveryFrameTrigger (the other Scene Trigger type), as expected. I'm totally at a loss for why this is happening. It must be something about my development environment. I cleared my cache, turned off all browser plugins, tried two browsers, restarted my computer. Next, I might try hopping around on one foot and reciting Monty Python, just to see if it helps. Using window event listeners will work, just a bit sad I can't get the ActionManager to work with keyboard events. Thanks again for the help. If anyone has any ideas about where the problem could be, it would be much appreciated.
  7. I initialize an ActionManager and register an Action with it, using the OnKeyDownTrigger, like so: scene.actionManager = new BABYLON.ActionManager(scene); scene.actionManager.registerAction( new BABYLON.ExecuteCodeAction( { trigger: BABYLON.ActionManager.OnKeyDownTrigger, parameter: "y" }, function () { console.log("y button pressed"); } )); But when I press the "y" key on my keyboard nothing is logged to the console. I've tried with many others keys, in both Firefox and Chrome, after turning off all plugins. Typescript is throwing no errors. Changing the trigger to BABYLON.ActionManager.OnEveryFrameTrigger works as expected, logging to console every frame. Changing it back to the "triggerOptions" object above makes it non-functioning again. I also tried setting up an actionManager on a Mesh in the scene, and registering the Action with that, which didn't work either. (Although OnPickTrigger on the mesh works fine.) Am I using the correct format for the triggerOptions object? Should I not be instantiating the ActionManager directly on to the scene.actionManager property? (Although it works with OnEveryFrameTrigger.) This code is nearly a copy-paste from the last code block under the Triggers section of "How to Use Actions". I can see the scene.actionManager object when I log it to console, with the action on it, it just isn't firing in response to pressing the y button. I'm learning a lot about using Actions in Babylon, I just can't get keyboard inputs/actions to work. Thank you for any help, this is really getting to me!
  8. 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'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 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.
  9. 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.
  10. 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.