foumfo Posted March 15, 2018 Share Posted March 15, 2018 I'm developing a game that will have grid based maps - levels and the player will be moving through it one block per keystroke. I'll be using the keyboard as input just for the start, I'll add others later on. Every level is generated from a double array filled with 1 & 0. So I want to do here is for example: if I press W the player will move one block forward. if I press Q the player will rotate anticlockwise by 45 degrees. Quote Link to comment Share on other sites More sharing options...
Guest Posted March 15, 2018 Share Posted March 15, 2018 Hey sorry but what is the question? Quote Link to comment Share on other sites More sharing options...
foumfo Posted March 15, 2018 Author Share Posted March 15, 2018 9 minutes ago, Deltakosh said: Hey sorry but what is the question? The question is how to alter a universal camera's controls in order to move on a grid block by block Quote Link to comment Share on other sites More sharing options...
Guest Posted March 15, 2018 Share Posted March 15, 2018 You may want to read this first: http://doc.babylonjs.com/how_to/customizing_camera_inputs based on that you can either create your own input or hijack the keyboard one Quote Link to comment Share on other sites More sharing options...
foumfo Posted March 15, 2018 Author Share Posted March 15, 2018 3 minutes ago, Deltakosh said: You may want to read this first: http://doc.babylonjs.com/how_to/customizing_camera_inputs based on that you can either create your own input or hijack the keyboard one I've read that already but its a bit difficult for me to follow. What I actually need is a small and simple example just for one control, pressing W and moving forward a specific amount of space Quote Link to comment Share on other sites More sharing options...
foumfo Posted March 15, 2018 Author Share Posted March 15, 2018 I think I've had it all wrong from the start. Would it be possible to create my own function for controlling the camera without actually attaching it to the camera object? After I've detached the default keyboard controls ofcourse Quote Link to comment Share on other sites More sharing options...
Wingnut Posted March 16, 2018 Share Posted March 16, 2018 Hi guys. Hey forumfo... here's a goofy playground that somebody once made. https://www.babylonjs-playground.com/#23PDP1#4 It uses WASD keys to trigger 90-degree rotations of the box. Kind of fun. The code size could be massively reduced. The rotations were done with "parenting to an invisible gizmo"... before I knew about setPivotPoint() for mesh. AND... this thing uses old DOM-like keypress-checking... when really... we should use BabylonJS ActionManager instead. Sooo... https://www.babylonjs-playground.com/#1MK1Y4#3 A little more modern... with WASDQE keys all working... but... the box is not moving in "steps". This is because the translation and rotation anims... is done in the render loop area (lines 70-75). Really, we need a few little "animation functions"... and remove stuff from the render loop. See lines 26, 29, 32, 35, 38, 41? We could replace those lines... with... moveMesh(whichmesh axis, amount); [amount could be positive or negative]) We would MAKE our own 'custom' mesh-mover function. Same with rotate. rotateMesh(whichmesh, axis, amount) (amount can be negative or positive). Custom mesh rotater func... by Captain Foumfo! Alright! What would go inside these 2 mover and rotater funcs? Well, let's go check out another playground. https://www.babylonjs-playground.com/#HH1U5#72 See the stuff at the top? Mainly, notice the spinTo, and moveTo functions. Inside those... is an amazing one-liner super-animator call... BABYLON.Animation.CreateAndStartAnimation(). It's amazing. I really like it. Anyway, steal some animation code from there... for your functions. Use the entire spinTo and moveTo functions... for your thing. With a little hacking and playing... I think you now have the tools to take over the world. Our Animation docs might be helpful. Ohhhh... you REALLY wanted to talk about moving a CAMERA, step by step? Just parent the camera to the box. Easy. You might want to remove camera.inputs, if you want to disable cursor keys and mouse... moving the camera. AND, finally, yes, as Deltakosh states... you could write a custom camera input... that moves the camera in grid-steps. I'm not sure that anyone has ever done that, yet. You would need to wear a hard-hat and safety goggles, for sure. My "parent to the invisible box" method... might be easier... safer... less tumor-causing. Did you know that cameras... can have animations directly upon them, too? hmm. BABYLON.Animation.CreateAndStartAnimation() can animate the camera, instead of a mesh. hmm. A little note: pay attention to camera.setTarget, .target, and .lockedTarget properties. Changing THOSE values... often setting them == box.position... CAN be handy for basic 'followCamera'. AND, even camera.target or .lockedTarget can be animated, with easing. hmm. Talk soon, be well. Quote Link to comment Share on other sites More sharing options...
JohnK Posted March 16, 2018 Share Posted March 16, 2018 Not quite the same (I did use one key to move forward and other keys to rotate, you could change the code (from line 460) so that it works with one key to rotate and change the angle) and it may be useful to you https://www.babylonjs-playground.com/#1PWKRP#10 Wingnut 1 Quote Link to comment Share on other sites More sharing options...
foumfo Posted March 16, 2018 Author Share Posted March 16, 2018 9 hours ago, Wingnut said: Hi guys. Hey forumfo... here's a goofy playground that somebody once made. ............... Thanks for the answer, I should have stated from the start that I'm talking about a First Person Camera game. If I understand correctly, you're talking about adding an invisible mesh as the player and have a FollowCamera attached to it, right? Quote Link to comment Share on other sites More sharing options...
Wingnut Posted March 16, 2018 Share Posted March 16, 2018 Yeah. Maybe not a followCam, though. Maybe just parent the cam to the invisible box. Notice John's demo also uses a 'cambox'. With FPS... there's no player mesh, right? (I'm not much of a shoot-em-up player. Too old and slow.) Yeah, you would want to use parenting, not .target/setTarget()/.lockedTarget (those are all 'follow-ish' things). Universal or free cam... clear its camera.input so the camera has no controls of its own. Then just drive-around the tiny/invisible cam-parent box... should work fine. Cam 'gizmo' or 'handle' thing. Step one... make code to drive-around a box with wasdqe. Make it act just like you want your camera to act... later... when you parent it to the box. Goof around, see what you like or don't... have good fun. Perhaps, a fun thing... familiarize yourself with BabylonJS GUI "simpleButton". Then maybe... create two buttons onscreen and two cameras. One is parentedToBoxFreeCam... the other is wideViewCam. Make your buttons choose which camera to view-from. *shrug*. A nice testing feature, eh? WideViewCam keeps normal .inputs (possibly use an ArcRotateCam)... and the parentedToBoxFreeCam has its .inputs cleared. *shrug* Quote Link to comment Share on other sites More sharing options...
foumfo Posted March 16, 2018 Author Share Posted March 16, 2018 4 hours ago, Wingnut said: Yeah. Maybe not a followCam, though. Maybe just parent the cam to the invisible box. Notice John's demo also uses a 'cambox'. With FPS... there's no player mesh, right? (I'm not much of a shoot-em-up player. Too old and slow.) Yeah, you would want to use parenting, not .target/setTarget()/.lockedTarget (those are all 'follow-ish' things). Universal or free cam... clear its camera.input so the camera has no controls of its own. Then just drive-around the tiny/invisible cam-parent box... should work fine. Cam 'gizmo' or 'handle' thing. Step one... make code to drive a box with wasdqe. Make it act just like you want your camera to act... later... when you parent it to the box. Goof around, see what you like or don't... have good fun. Ok then I'll create a box with my controls and then see how to make it a parent to a camera. I didn't know I could do that. The game I'm developing will be like the old school rpgs that players roam in dungeons step by step using a FPS cam Quote Link to comment Share on other sites More sharing options...
Wingnut Posted March 16, 2018 Share Posted March 16, 2018 Hi Foumfo. I want to remind you... that just because Wingnut has an idea, doesn't mean it's good or right. It's simply one way to do it. After some tests, you might find better ways. More comments may come, too. I'm certainly no expert in game programming. Here's another demo... with 'spin' and 'move' functions installed/used. https://www.babylonjs-playground.com/#1MK1Y4#7 Issues: - After Q/E 45-degree turns, cambox still wants to WASD-move in WORLDSPACE directions, but cambox SHOULD move in cambox's LOCALSPACE directions. (if box is turned 45 degrees, all cam/cambox WASD moves should be rotated 45 degrees, too.) - Held-down keys do not repeat. Probably should. - Hemispheric light's .groundColor (line 36) might not be working. Sides of cones SHOULD be lit/colored, and not black, I think. ------------------------------ Lines 109-111 parent the camera to the box and remove any old positions or far targets. Even though I did not set cambox.visibility = 0, you can't see it... even if you tilt the camera downward with the mouse. By setting camera.minZ to something like .01... you might be able to see it again. I did NOT clear the .input of this camera. I wanted to keep being able to look around... with mouse or cursors, for now. Also, animations are not required. We could "snap" the camera to new positions and rotations... instantly. I think the keys would repeat when held, that way, automatically. There might be ways to tell the animations to do LOCAL SPACE animating instead of WORLD SPACE, but I'm not sure how to do that. Maybe others will help with that. Anyway, now you have an example... of what a camera... parented to a box... looks-like/acts-like. Not too bad, eh? Something to play-with. Talk soon. Quote Link to comment Share on other sites More sharing options...
foumfo Posted March 16, 2018 Author Share Posted March 16, 2018 //player window.player = BABYLON.MeshBuilder.CreateBox("player", {size: 1}, scene); var playerMovement = function(key) { console.log(key); switch(key.charCode) { //up case 119: case 87: player.position.z += 1; break; //down case 115: case 83: player.position.z -= 1; break; //left case 97: case 65: player.position.x -= 1; break; //right case 100: case 68: player.position.x += 1; break; //rotate anticlockwise case 113: player.rotation.y -= Math.PI / 2; break; //rotate clockwise case 101: player.rotation.y += Math.PI / 2; break; } } document.addEventListener('keypress', playerMovement, false); I just created this small piece of code, but all the transforms are instant. How can I animate them? Quote Link to comment Share on other sites More sharing options...
Wingnut Posted March 17, 2018 Share Posted March 17, 2018 https://www.babylonjs-playground.com/#1MK1Y4#10 There ya go. Your code is lines 102-146. Spin() and move() animation funcs are lines 2-11. I can't get the keypress repeating (held keypress) to work, yet. And I am seeing a move on keypress UP, too. Not sure why. Still thinking/studying. My tumbler demo https://www.babylonjs-playground.com/#23PDP1#4 performs/allows held keypresses, but it uses different animation methods (not using spin() or move() or CreateAndStartAnimation(). hmm. Perhaps you or others can help me find my mistakes. Quote Link to comment Share on other sites More sharing options...
foumfo Posted March 17, 2018 Author Share Posted March 17, 2018 38 minutes ago, Wingnut said: https://www.babylonjs-playground.com/#1MK1Y4#9 There ya go. Your code is lines 102-146. Spin() and move() animation funcs are lines 2-11. I can't get the keypress repeating (held keypress) to work, yet. And I am seeing a move on keypress UP, too. Not sure why. Still thinking/studying. My tumbler demo https://www.babylonjs-playground.com/#23PDP1#4 performs/allows held keypresses, but it uses a different animation methods (not using spin() or move() or CreateAndStartAnimation(). hmm. Perhaps you or others can help me find my mistakes. Your first example works but only if add window.addEventListener("keypress", playerMovement, false); instead of keydown. By the way, your first lines are awesome! BABYLON.AbstractMesh.prototype is how we add properties to the mesh class correct? Wingnut 1 Quote Link to comment Share on other sites More sharing options...
foumfo Posted March 17, 2018 Author Share Posted March 17, 2018 Is it possible to rotate a meshes pivot axis when we rotate the mesh? For example, when we rotate the mesh clockwise, rotate the X axis clockwise also. So when you move the mesh forward, it will move rightwards compared to the global axis Quote Link to comment Share on other sites More sharing options...
Wingnut Posted March 17, 2018 Share Posted March 17, 2018 Yeah, that's possible. Remember when I talked about LOCALspace and WORLDspace... and I wasn't sure how to use animation to move an object in along localspace axes? That's what I was talking about. And I still don't know how. I'm not very helpful. Let's make sure you and I are understanding each other. Visit here, please. http://playground.babylonjs.com/#6FHKHC#9 This is a playground where we activated the mousewheel... on a freeCamera (normally, not activated). Pretend that the mousewheel == YOUR W and S keys. Notice that... no matter WHICH WAY the camera (box) is rotated/aimed, the mousewheel (W/S keys)... moves the camera along cam's LOCAL z-axis... and not along the WORLD z-axis. I think that is what you want. (verify, if you wish) I think you want translations to move along the box's LOCALspace z-axis. (sometimes called the box's "forwardVector", I believe... but I could be wrong on that.) I don't think mesh.setPivotPoint() will work for this. I don't know how to move a mesh along its "forwardVector" (its localSpace z-axis)... with animation. Not yet, anyway. Still thinking. Although it is a weekend (sleepy forum)... let's wait for more comments/help. Quote Link to comment Share on other sites More sharing options...
foumfo Posted March 17, 2018 Author Share Posted March 17, 2018 Even though I didn't understand much of your example, I do want the camera box's movement to be based on its locaspacel axis and not the globalspace. I could do it programmatically I suppose but it would take a lot of lines of code. I asked this in case there was a built-in way / method to handle local translations Quote Link to comment Share on other sites More sharing options...
Wingnut Posted March 17, 2018 Share Posted March 17, 2018 *nod*. https://www.babylonjs-playground.com/#1MK1Y4#12 Quite a bit of change in lines 2-13. Using .rotate() and .translate() funcs... instead of .rotation and .position properties... gives us the localSpace stuff we want. But I still don't know how to apply animation to it. Help welcome, from anyone. Note: When we used the .rotate() function in line 3, that is called a Quaternion rotation. The mesh sort-of turns-off the .rotation property, and instead uses .rotationQuaternion to store it's rotation values. We'll talk more about that, someday. Main thing is... after a rotate() happens on a mesh, mesh.rotation property is no longer used, and mesh.rotationQuaternion property is added to the mesh, and used instead. Okay, how about it, fellow forumers? Anyone know how to use animations like those seen in line 4-6 and 10-12... but with localSpace animations instead of worldSpace? Help! Stay tuned, foumfo. SOMEBODY will know how to animate these localSpace moves/turns. (Wingnut crosses his fingers). Quote Link to comment Share on other sites More sharing options...
foumfo Posted March 18, 2018 Author Share Posted March 18, 2018 18 hours ago, Wingnut said: *nod*. https://www.babylonjs-playground.com/#1MK1Y4#12 Quite a bit of change in lines 2-13. Using .rotate() and .translate() funcs... instead of .rotation and .position properties... gives us the localSpace stuff we want. But I still don't know how to apply animation to it. Help welcome, from anyone. Note: When we used the .rotate() function in line 3, that is called a Quaternion rotation. The mesh sort-of turns-off the .rotation property, and instead uses .rotationQuaternion to store it's rotation values. We'll talk more about that, someday. Main thing is... after a rotate() happens on a mesh, mesh.rotation property is no longer used, and mesh.rotationQuaternion property is added to the mesh, and used instead. Okay, how about it, fellow forumers? Anyone know how to use animations like those seen in line 4-6 and 10-12... but with localSpace animations instead of worldSpace? Help! Stay tuned, foumfo. SOMEBODY will know how to animate these localSpace moves/turns. (Wingnut crosses his fingers). What If we did this animation using another framework, like jquery for example. Would it be too taxing performance-wise? Quote Link to comment Share on other sites More sharing options...
Wingnut Posted March 18, 2018 Share Posted March 18, 2018 Yeah, you're sort-of on the right track. We can use BJS built-in 'LERP'. Goofy term, eh? "linear interpolation". You can think of it as a "derived" (math-generated) array of vector3 positions... just like an animation might be. It is pre-"grown" before the animation starts, and then this array is "delivered" to the 'animatable'... at a frame rate. https://github.com/BabylonJS/Babylon.js/search?utf8=✓&q=lerp&type= The BJS animation system and easings system... uses lerp now. So, yes, the power to make your own eased animations... is already built-into BJS. Do I know how to use it? Heck no. heh. Let's try a playground search for 'lerp'... http://doc.babylonjs.com/playground?code=lerp Plenty of examples. Is any of it easy? Maybe, but... MUCH smarter lerp-masters than I... are nearby. Hopefully, you, or one of them will wave their magic lerp-wand, and make it all better. important afterthought: I said that a lerp array might be an array of vector3 .positions. THAT... might not be true. Each value MIGHT BE... "amount of change to apply since last change". Not sure. For building your own animation (interpolation array) to apply-to mesh.translate() repeatedly... an "amount of change since last change" array... would be better for you. Conversely, an array of vector3 positions... would be better for using mesh.position... instead of mesh.translate(). I think EITHER METHOD would work for you. Maybe. *shrug* I think you can "grow" lerps... using either method. Scary. I really have no idea what I am talking about, though. Mostly speculation. MAYBE... the move() function could be made "smarter"... able to recognize WHEN/IF a box has been rotated, and change its animation methods... to compensate for that (such as running two animations at the same time). Hmm. It would be good to know WHY animations like these ... do keypress-held repeating, but no hold/repeat for our BABYLON.Animation.CreateAndStartAnimation(). Might be something about the CreateAndStartAnimation's onFinished callback (or lack-of callback?), or something. I need more learning. Notice the 'itEnded' callback in line 192 of that playground. It calls the itEnded() function... upon ending. OUR style of animating (CreateAndStartAnimation)... doesn't use that, as best I can tell. *shrug* Perhaps THAT is why one kind of animation/keypress-events allow held/repeating keys, and the other doesn't. Not sure. Quote Link to comment Share on other sites More sharing options...
foumfo Posted March 19, 2018 Author Share Posted March 19, 2018 Wingnut check this out: https://www.babylonjs-playground.com/#1MK1Y4#15 you only have to use this.translate(axis, amt, BABYLON.Space.LOCAL); When you use BABYLON.Animation.CreateAndStartAnimation('at4', this, 'rotation.' + axis, speed, 120, this.rotation[axis], this.rotation[axis]+rads, 0, ease); and then translate, the mesh moves along the local axis that has been rotated by the above rotation Wingnut 1 Quote Link to comment Share on other sites More sharing options...
Snouto Posted March 20, 2018 Share Posted March 20, 2018 For simple movement try adding this code: BABYLON.AbstractMesh.prototype.moveTo = function (targetPos, fps, frames, done) { var ease = new BABYLON.QuadraticEase(); ease.setEasingMode(BABYLON.EasingFunction.EASINGMODE_EASEINOUT); this.activeAnimation = BABYLON.Animation.CreateAndStartAnimation('at5', this, 'position', fps, frames, this.position, targetPos, 0, ease, done); }; This will attach a moveTo method to every mesh in your scene, and then you can simply call the function like so: myMesh.moveTo(new BABYLON.Vector3(x,y,z),24,96,function(){ console.log("Movement complete!"); }); You can extend the function to accept the easing type in the method call if you intend to have different ease effects according to situation. For rotation you may wish to look in to Quaternions, as they in general provide much smoother and more reliable results. The following is an example implementation for slerping between two quaternions, however there are probably other methods you can use for this. // set up the initial Quaternion on your mesh, as they are not created automatically myMesh.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll( myMesh.rotation.y, myMesh.rotation.x, myMesh.rotation.z ); // add an "indicator" mesh to your main mesh. This will be used to look at the target location, and the different between its quaternion and your mesh's quaternion then slerped to match var indicatorMesh=BABYLON.Mesh.CreateBox("meshIndicator", 0.1, scene); // add quaternion for this new mesh too indicatorMesh.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll( indicatorMesh.rotation.y, indicatorMesh.rotation.x, indicatorMesh.rotation.z ); // parent the indicator mesh to your main mesh indicatorMesh.parent = myMesh; // now, in a registerAfterRender function (called automatically), adjust the two quaternions. change the world/local space to suit. targetPosition it the Vector3 you want to look at scene.registerAfterRender(function () { if(myMesh.isRotating=true){ // make the indicator mesh look to the target position. This will update its quaternion. indicatorMesh.lookAt(targetPosition,0,0,0,BABYLON.Space.WORLD); // now get an integer value representing the difference between the main mesh quaternion value and the indicator mesh's quaternion value. var diff = myMesh.rotationQuaternion.subtract(indicatorMesh.rotationQuaternion).length(); // registerAfterRender fires after ever frame render, so here we can check the difference between the two quaternions and decide to do something once we meet a certain threshold. if(diff > 0.05){ // if we are still above the threshold, adjust the mesh quaternion a little. You can adjust the amount to suit. The higher the number the quicker the rotation and the faster the rotation will pass the threshold. We use Slerp here because this will spherically interpolate a value in directional vectors myMesh.rotationQuaternion = BABYLON.Quaternion.Slerp( myMesh.rotationQuaternion, indicatorMesh.rotationQuaternion, 0.035 ); else { // set the rotating flag to false to stop this loop for firing again myMesh.isRotating=false; // optionally call a function to continue processing done && done(); } } }); // somewhere in your code, start the process away targetObject=new BABYLON.Vector3(x,y,z); myMesh.isRotating=true; var done = function(){ console.log("done rotating"); }; Wingnut 1 Quote Link to comment Share on other sites More sharing options...
foumfo Posted March 20, 2018 Author Share Posted March 20, 2018 @Snouto your moveTo function is based on the GLOBAL axis correct? If that's true then I cant really use it for local movement. Quote Link to comment Share on other sites More sharing options...
Snouto Posted March 20, 2018 Share Posted March 20, 2018 Oh you wanted locale movement? Sorry, I didn't read the full thread closely enough. Maybe this will help ? p.s. check this out if you need to convert from world to local 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.