Spankied Posted June 19, 2018 Share Posted June 19, 2018 Implementing click navigation. Trying to get skeleton animations & path navigation to work nicely together. I start the player walkAnim and then begin animating player.position along a path. The walkAnim is promptly interrupted and the player glides along the path, after which he continues walkAnim for a short time. I considered moveWithCollisions, but It navigates to a point, not an array of points, I would have to loop over the path array and check whether or not Ive reached a point, then moveWithCollisions to next point in path. Starting to feel out of my league so decided to share my woes with all you. The bablyon-nav-mesh file require()'s alot of dependencies and I was unable to import the library into a playground ( https://www.babylonjs-playground.com/#EZSYWY#1), so I'm just gonna post some code here. BABYLON.SceneLoader.ImportMesh("","https://rawgit.com/Spankyed/sched-proto/master/src/assets/player/","dummy3.babylon",scene,(meshes,particleSystems,skeletons)=>{ var skeleton = skeletons[0]; skeleton.enableBlending(0.2); player = meshes[0]; player.skeleton = skeleton; player.position = new BABYLON.Vector3(-2.7426157086231813, 0.32968033243017736, -5.410392414960055); player.checkCollisions = true; canvas.addEventListener('click', function(event) { var pickingInfo = scene.pick(scene.pointerX, scene.pointerY); if (!pickingInfo.hit) return; var walkRange = skeleton.getAnimationRange("YBot_Walk"); var walkAnim = scene.beginAnimation(skeleton, walkRange.from, walkRange.to, true); var path = navigation.findPath(player.position, pickingInfo.pickedPoint, 'level', navigation.getGroup('level', player.position)) || []; console.log('path', path) /*if path is defined, create path animation frames and beginAnimation on player*/ if (path && path.length > 0) { var length = 0; var direction = [{ frame: 0, value: player.position }]; for (var i = 0; i < path.length; i++) { length += BABYLON.Vector3.Distance(direction[i].value, path[i]); direction.push({ frame: length*100, value: path[i] }); } for (var i = 0; i < direction.length; i++) { direction[i].frame /= length; } var move = new BABYLON.Animation("CameraMove", "position", 180/length+10, BABYLON.Animation.ANIMATIONTYPE_VECTOR3, BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT); move.setKeys(direction); player.animations.push(move); scene.beginAnimation(player, 0, 100); } }) engine.runRenderLoop(function(){ scene.render(); }); }); While I'm here wanna throw out two other questions I have yet to conceive an answer for. How to smoothly adjust the player to lookAt points along its path? How would key controls(wasd) be implemented in conjunction with a click navigation system? Create small incremental paths? Quote Link to comment Share on other sites More sharing options...
Sebavan Posted June 19, 2018 Share Posted June 19, 2018 lookAt will usually be lerping with over bit of time to not have a "snappy" feeling. it would also most of the time have a bit of epsilon to not look "shaky". About the path system @MackeyK24 who is using it in the toolkit might be well placed to help. Quote Link to comment Share on other sites More sharing options...
Sebavan Posted June 19, 2018 Share Posted June 19, 2018 This is also a nice tuto about it: https://www.wanadev.fr/43-tuto-creer-et-utiliser-un-maillage-de-navigation-avec-babylon-js/ (Google Trad might help here) Quote Link to comment Share on other sites More sharing options...
Spankied Posted June 19, 2018 Author Share Posted June 19, 2018 @Sebavan The tutorial and github repo got me here. Not sure what you mean when you say lookAt will need some epsilon to not look shaky. My question with lookAt is how would you implement it? Would you look at path points, or subdivide between points, and look at subdivisions? And how would u know when to look at a point, would u constantly check if the player has reached certain points? Quote Link to comment Share on other sites More sharing options...
Sebavan Posted June 19, 2018 Share Posted June 19, 2018 About the shakiness, I mean to not reorient every frame if the direction point did almost not move. I kind of like the path points idea but I would try both and see which one fits best with your expectation. You could look at a point until you get close enough to see the one after. This is all only suggestions and usually heavily depends on the feeling you want to provide in the experience. Quote Link to comment Share on other sites More sharing options...
Spankied Posted June 20, 2018 Author Share Posted June 20, 2018 @Sebavan I want to provide the most natural looking experience. My biggest concern for now is getting the skeleton animations to play along with the position animations/transform. Quote Link to comment Share on other sites More sharing options...
MackeyK24 Posted June 21, 2018 Share Posted June 21, 2018 Yo @Spankied ... Here is my 2 cents on how I do things, Babylon Toolkit Style Game Mechanics First off, Using my style of BJS Game Development... THE COLLIDER IS KING. The babylon toolkit allow you to create 'Collision Meshes'. Basically simple primitives to act as the MAIN PLAYER/CHARACTER... For humanoids, I Use a simple Capsule. The Capsule (Invisible but with things like Check Collision or Physics State on it). This is what you actually move around and interact with. The simple primitive. The character mesh you put inside the capsule as a child is PURE EYE CANDY. You should NEVER (or try not to) directly manipulate the character mesh, he is just along for the ride. If you took the YBot (still in tpose) and no animations, He would just go along the capsule in the TPOSE. Remember the Capsule is the object with all the components and logic on it. NOT THE MESH. So moving the Capsule around it pretty strait forward, you code use Physics , but MoveWithCollisions would probably be a little LESS resource intensive especially for Non-Player Characters. Once you get the regular capsule moving around like you want (WITH OR WITHOUT the player mesh). Then you use the Toolkit Animation State Machine to setup all your animation logic on the Unity Animation Controller. This way you can have extremely complex or simple animation sequences that are controlled via State Machine Properties. So you might have a value on your state machine called Forward.... You update the 'Forward' value on your state machine and plays whatever animation (OR BLENDS AND LAYERS OF ANIMATIONS) its supposed to. BTW... when say LOOK AT... Do you mean have the actual player mesh TURN HIS HEAD, if so you would have to use 'Direct Blend Animation' and turn his head, very much like Blendshapes for Facial Blending. And you need a separate head mesh so you can rotate independently of the body. OR do you simply mean to rotate the player object (rotate the Y-Axis) to TURN THE WHOLE Capsule Parent Mesh Towards the Path point. I dont think you want to use LookAt unless you always use (0, Point, 0) to rotate or turn your guy that way... The lookAt will rotate the entire object... That may NOT be what you want... Say the next point is on second floor or something if you simply LOOK AT the position you may get UNWANTED rotation in the the whole object... And also if your doing any kind of gradient with rotations... you should SLERP (Spherical Interpolation) not LERP (Linear Interpolation). I am putting together material to make a Udemy Course that will focus on: 1... Babylon Toolkit Primer - Going over ALL the ins and outs of the Toolkit. How to really get the most out of ALL its features (from custom shaders to complex character animation state machines) 2... Babylon Toolkit Game Mechanics - Taking advantage of the Babylon Toolkit Scene Manager to provide that UNITY-LIKE game dev experience and game mechanics. 3... Mobile Game Development - Using the various tools to OPTIMIZE your game Mobile. 4... Xbox Live Services - Builds-in support for create Native HTML5 UWP (Internally Packaged Or Hosted) console games that have ALL of the features you get with Native C++ Xbox Live Services... Except all built-in the toolkit using TypeScript and newer type TypeScript features like Async/Await for XBOX LIVE API promises. 5... Plus we will go thru a PORT a few Unity games. Just to get familiar with using the toolkit to be able to produced the same kind of Games and Mechanics you would use to make a native Unity Game... We just do it Babylon Toolkit Style Plus Tons of other stuff that you can now do with the Babylon Toolkit. BUT... I hit a road block in my animation state machine... You cant do any type 2D Blend Trees Yet (2D Simple Directional, 2D Freeform Directional and 2D Freeform Cartesian) I only support 1D and Direct Blending for now... I still dont understand the POLAR SPACE math need to calculate the Input weight of each blend tree child for 2D. But I will keep hacking away at it after I finish some refactoring of the SceneManager API so now can run ALL your Unity-Like Functionality Right win the playground... OR ANY javascript environment like your own custom AngularJS or whatever App you want... I also create a new Project Referencing Architecture I call project.js (Modeled after Cordova.js plugins) so you can now reference and use your Unit-Like projects in ANY javascript environment, even the playground. the entire Babylon Toolkit Project can now be referenced like so: <script type="text/javascsript" src="project.js"></script> and document.addEventListener("projectload", onprojectload, false); even in the playground like so: var createScene = function () { // Disable manifest loading engine.enableOfflineSupport = false; // This creates a basic Babylon Scene object (non-mesh) var scene = BABYLON.SceneManager.CreateScene(engine); // Only here to keep playground from giving no camera warning var dummy = new BABYLON.FreeCamera("dummy", BABYLON.Vector3.Zero(), scene); // Toolkit demo playground root url var root = "https://www.babylontoolkit.com/playground/"; function onprojectload() { // Load default playground scene with skybox and hdr reflections BABYLON.SceneManager.AppendScene(root + "scenes/", "default.babylon", scene, function() { // Get main camera and remove dummy camera var camera = scene.manager.getMainCamera(); if (camera) dummy.dispose(); // Our built-in 'box' shape. Params: name, size, scene var box = BABYLON.Mesh.CreateBox("box1", 1, scene); // Move the box upward 2 units in height box.position.y = 2; // Our built-in 'ground' shape. Params: name, width, depth, subdivs, scene var ground = BABYLON.Mesh.CreateGround("ground1", 10, 10, 2, scene); }); } // Load project references if (!navigator.project) { document.addEventListener("projectload", function() { onprojectload(); }); BABYLON.Tools.LoadScript(root + "project.js"); } else { onprojectload(); } // Console debug reference window.scene = scene; return scene; }; Anyways... The 3.3 Beta Will have all this stuff... Workin on it now Spankied 1 Quote Link to comment Share on other sites More sharing options...
Spankied Posted June 21, 2018 Author Share Posted June 21, 2018 @MackeyK24 the issue with the toolkit are the docs. The getting started video link is broken, and I remember just seeing " please refer to unity docs" everywhere. I think there were a few examples, but some felt incomplete or were just api references. I havent watched a udemy course in like a year, but If u released one on the toolkit I would definately get it. Any video u release on the toolkit I'll watch, especially those in regards to navigation and animation. Idk why collision meshes or impostors never crossed my mind. Makes so much sense after reading ur post. I want to incorporate both lookAt functionalities u mentioned, but for now, just the second one, turning the capsule to face the movement direction. Is there another function other than lookAt u would use? If i moveWithCollisions to a point I can just look at that point before moving, but how would I do this for a player.position animation over an array of points? To elaborate on last question, moveWithCollisions only moves to one point, that's why I began an animation on the player.position value and made some frames for each point along the path, then play all frames. How would a moveWithCollisions refactor look? Does project.js also import the navigation-mesh library? If so how are u able to load it in the playground, I checked the navmesh library file and it tries to require a bunch of dependencies which the playground didn't like. Thanks for ur response Mackey Quote Link to comment Share on other sites More sharing options...
Guest Posted June 21, 2018 Share Posted June 21, 2018 yeah the video link has to be fixed Quote Link to comment Share on other sites More sharing options...
MackeyK24 Posted June 21, 2018 Share Posted June 21, 2018 First the video, well I haven’t made yet. I’m still cleaning up a few things to make projects easy to use anywhere, like the playground. I am also trying to find something good to make as a getting started project. Like the roller bal or some kind of basket shooter. Something good but not to complicated as your first toolkit project. The many refer to unity links. I made the toolkit work off the native unity workflows and properties... They get serialized as metadata. So you use a toolkit editor feature EXACTLY like you would if making a native unity game, except for Components. We don’t support unity components but we have a growing set of Babylon components for our projects. So for example, animation controllers. You would setup an animation controller in unity editor, nothing different you do for a Babylon project as far as the setup. You have to be familiar with unity mechanim to really get most out it. Whatever you setup, the toolkit parse out and that metadata to re-implement that functionality in the BabylonJS client side code. So everywhere it says refer to unity docs for that feature, well you gotta go look how unity does it. Once you get unity doing it and you export the toolkit takes over serializing detailed export content. Anyways, my point being, you gotta get to know the unity editor a bit. For the toolkit, that’s you life blood, your main game development environment. I do EVERYTHING in the toolkit (or via a toolkit VSCode project. I even use the toolkit to make the toolkit. Talk about the chicken and the egg ? The toolkit in one screen and a VSCode toolkit project in another screen are my main game development workflow tools Quote Link to comment Share on other sites More sharing options...
MackeyK24 Posted June 21, 2018 Share Posted June 21, 2018 The navmesh. Yes project.js will bring in all required libs NOT already loaded, including navmesh. Unfortunatly the navmesh is acting funny on the playground so I can’t show you any examples on the playground yet. @Deltakosh and I are working on it. Hopefully we can get that issue fixed soon. So for now, you gotta use a full toolkit project to play with navigation Quote Link to comment Share on other sites More sharing options...
Spankied Posted June 22, 2018 Author Share Posted June 22, 2018 moveWithCollisions takes a velocity. The nav-mesh library outputs an array of positions. My question is how do I move a player using this array of positions. Using begin animation, I can set which position player should be at, at certain frames. This works well except I can't animate position and skeleton at same time. Halppp!1 Quote Link to comment Share on other sites More sharing options...
satguru Posted June 22, 2018 Share Posted June 22, 2018 @Spankied, moveWithCollisions takes a displacement not velocity Quote Link to comment Share on other sites More sharing options...
Spankied Posted June 22, 2018 Author Share Posted June 22, 2018 @satguru https://imgur.com/a/sPDz9nm Quote Link to comment Share on other sites More sharing options...
MackeyK24 Posted June 22, 2018 Share Posted June 22, 2018 1 hour ago, Spankied said: moveWithCollisions takes a velocity. The nav-mesh library outputs an array of positions. My question is how do I move a player using this array of positions. Using begin animation, I can set which position player should be at, at certain frames. This works well except I can't animate position and skeleton at same time. Halppp!1 Using the pattern COLLIDER IS KING ... The mesh containing the skeleton has NOTHING to do with the actual position of the PARENT COLLIDER that you should moving between nav points. Make a BoxMesh. Set: collisionMesh.checkCollision = true; collisionMesh.visibility = 0.0; dude.parent = collisionMesh; /// MOVE THE COLLISION MESH BETWEEN WAYS POINTS Normalize the position to get direction vector. collisionMesh.moveWithCollision(directionVector.scale(movementSpeed)) Now for the CHILD DUDE MESH... HE NEVER MOVES HIS POSITION... HE JUST ALONG FOR THE RIDE... While riding he can play (IN-PLACE) animations... Now I dont really use beginAnimation to play skeletal animations... I need full control over bones, layers, blending etc... So I use my BABYLON.AnimationState component to set the state of what I want my guy to do... So while moving in between animations... If always MOVING.... Before I start the guy on the waypoints... I would do something like in a Scene Component: let animator = this.getComponent("BABYLON.AnimationState"); if (animator) animator.play("Walk"); But you could always us beginAnimation for simple skeleton animation. scene.beginAnimation(...) on your dude skeleton and he just play his walk animation while the parent collision mesh is actually moving around... One has nothing to do with the other (as far as not being able to move the parent with an animation and play a walk animation on the child dude mesh at the same time) Spankied 1 Quote Link to comment Share on other sites More sharing options...
satguru Posted June 22, 2018 Share Posted June 22, 2018 @Spankied, It used to be called velocity but it was always displacement. Eventually the document was updated to avoid the confusion. see http://doc.babylonjs.com/api/classes/babylon.mesh#movewithcollisions You are supposed to give the amount and direction by which you want to displace the mesh. If you search the forum you might find a discussion on that Quote Link to comment Share on other sites More sharing options...
Spankied Posted June 22, 2018 Author Share Posted June 22, 2018 @MackeyK24 saves the day. Will be looking out for those unity videos. Quote Link to comment Share on other sites More sharing options...
MackeyK24 Posted June 22, 2018 Share Posted June 22, 2018 No problem, glad to help ? Quote Link to comment Share on other sites More sharing options...
MackeyK24 Posted June 22, 2018 Share Posted June 22, 2018 Yo @Spankied ... I dont think you need to use LookAt... Again that does rotation on all Axis... I think you you can just rotate (turn) with the rotation alpha from direction. Try something like this: let navpoint:BABYLON.Vector3 = GetCurrentNavPointFromPaths(); let navposition:BABYLON.Vector3 = navpoint.subtract(collisionMesh.position); let navdirection:BABYLON.Vector3 = navposition.normalize(); let navrotation:number = Math.atan2(navdirection.x, navdirection.z); collisionMesh.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(navrotation, 0, 0); collisionMesh.moveWithCollisions(navdirection.scale(movementSpeed)); You can optimize of course using the "ToRef" versions of the API functions. UPDATE I tested this with nav points in front, behind and above the collisionMesh... Keeps the collisionMesh from Pitching and Rolling... And it does rotate toward then moves with collisions to the nav point. Seems to work for me Spankied 1 Quote Link to comment Share on other sites More sharing options...
MackeyK24 Posted June 22, 2018 Share Posted June 22, 2018 Yo @Spankied .. BTW... If your guy is facing the wrong way... Try -Math.atan2 Hope the updated code above works for ya Spankied 1 Quote Link to comment Share on other sites More sharing options...
Spankied Posted June 22, 2018 Author Share Posted June 22, 2018 5 hours ago, MackeyK24 said: Yo @Spankied .. BTW... If your guy is facing the wrong way... Try -Math.atan2 Hope the updated code above works for ya Lol good looks mate. I'll have to check all this out when I get home. Much appreciated. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.