W1lly Posted July 9, 2015 Share Posted July 9, 2015 Hello babylonians, This is my first post here, don’t eat me please . So I have been experiencing with babylon.js for a few weeks now, and I would like to share with you an issue that I can ’t seem to be able to solve. Let’s say I have a character in my game, and I want to move this character using moveWithCollisions. How would you go about handling the case when the character is standing idle on a slope ? Assuming I also have gravity, unless the player is trying to compensate the gravity by moving up the slope, it will inexorably glide. Here is an example of what I mean: http://www.babylonjs-playground.com/#18FYXX#2. You can see the ball is first falling on the slope and then glides (which makes perfect sense since its a ball…). But now imagine the ball is not a ball anymore but a character: you probably don’t want the character to keep falling once it reached the slope (unless it’s a actually a slide…), right ? What I tried so far was to detect when the character intersects with the slope using intersectsMesh. The problem of this is that I have to separate every slope of my game from the rest of the map so that they get their own precise bounding box (I tried to use mesh.subdivide but unfortunately the bounding boxes of the sub-meshes don’t seem to be used, even with precision set to true for intersectsMesh…). Anyway I doubt this is the right way to do it. Any idea on how to prevent meshes from gliding on inclines ? Quote Link to comment Share on other sites More sharing options...
jahow Posted July 10, 2015 Share Posted July 10, 2015 One theoretical solution would be to switch to the complete physics engine and set the sphere's friction to 1, but I'm really not familiar with this part of the engine to help you more... Also there's a working example right here (made by iiceman, another fine folk from these premises): http://p215008.mittwaldserver.info/moveWithCollisions/ Edit: speak of the devil... Quote Link to comment Share on other sites More sharing options...
iiceman Posted July 10, 2015 Share Posted July 10, 2015 Hey Willy, welcome to the forum. I remember playing around with moveWithCollisions and I noticed this behaviors, too. I dug a bit trough old content and questions that I asked about moveWithCollisions. I found this playground: http://playground.babylonjs.com/#1NQTNE#9 where it doesn't seem to happen. But I don't know why without going trough the code again. But shouldn't be too hard to figure out. Maybe that helps? Edit: jahows link is the result I created after playing with the playground that I mentioned. Finding the solution might be easier in the playground code without all that fancy stuff around Quote Link to comment Share on other sites More sharing options...
adam Posted July 10, 2015 Share Posted July 10, 2015 You should start by getting a character to move to a destination on a flat surface. Once you figure that out, move onto inclines. I'm thinking that a combination of friction and a force being applied to the character to get to a certain point will solve your issue. Quote Link to comment Share on other sites More sharing options...
Wingnut Posted July 10, 2015 Share Posted July 10, 2015 Hi guys! Unfortunately, Adam, there is no friction setting unless a physics engine is used. The BJS built-in gravity, intersect, moveWithCollisions... does not use friction. But, hmm, maybe a person could write a function that would simulate friction for our built-in system. hmm. But, I have another strange idea (for non-physics engine). (When don't I?) Put a function on your mesh... mesh.maintainer = function() {} Call mesh.maintainer() inside the render loop. It is ALWAYS being called. At the start of a moveWithCollisions... set mesh.maintainer = function() {} (empty function) (turn it off) As soon as .moveWithCollisions completes its move (when mesh.position == moveTarget)... set... mesh.maintainer = function() { mesh.position = moveTarget; // or something similar. Don't let the mesh move from its previous moveWithCollisions target} Before all future moveWithCollisions... turn-off the maintainer again... mesh.maintainer = function() {} Essentially, whenever .moveWithCollisions is not active, the maintainer is active. You would probably need to 'monitor' for when mesh.position == moveTarget... inside the render loop, too. I'm not sure if .moveWithCollisions can be told to trigger a callback function when the moving has completed (such as mesh.onEndMovingWithCollisions()). *shrug* Maybe. I hope you don't want to add an inertia feature in a custom moveWithCollisions, later. That could be trouble. (Not really. We'd just overshoot the MWC target a bit, and put an EaseOut algorithm on the overshoot. Ouch! But MWC target and mesh.position would never match, so there's the problem. So, we don't overshoot. Just put EaseOut on the final steps of the MWC move. Bigger OUCH!) Quote Link to comment Share on other sites More sharing options...
W1lly Posted July 10, 2015 Author Share Posted July 10, 2015 Wow thank you all for your answers, it seems like a very active community! So yeah the idea was to avoid using physics. Since I don't really need it for anything else I could save on calculation cost. Wingnut, if I understand correctly what your are proposing, the problem is that in my case moveWithCollisions is called inside the render loop. This is because I also need to handle cases where my character should fall. Something I tried earlier was to treat the "falling case" as a special case when my character is not intersecting with anything else. This way I can avoid calling moveWithCollisions on each frame, but this is a somehow unreliable due to the approximated bounding boxes that are used... Well, I could split my complex meshes into basic shaped meshes before exporting them for babylon, but once again I have a feeling that there should be a better solution . Thanks a lot for your example iiceman ! That's actually exactly what I was looking for. Event though I don't understand how that work yet, there is no reason I couldn't apply this to my case Quote Link to comment Share on other sites More sharing options...
Wingnut Posted July 11, 2015 Share Posted July 11, 2015 Ahh, you have moveWIthCollisions inside the render loop? nod. Pickin/clickin instead of keypresses. *nod* See, when you use keypresses... they automatically go into repeat mode... so its easy to do repeated little moveWithCollisions WITHOUT needing the MWC inside the render loop. Instead, it does one little MWC per keypress, and holding a key... does continuous moving (WASD steering). So, yes, with moveWithCollisions happening constantly (often with no target change)... yeah, a "maintainer()" func would not get much of a chance to run. But still... the goal is to hold the mesh in .position ... when mwc isn't trying to move it. maintainer() is a mesh lock. Hold me here... unless MWC wants me to move. IF MWC wants me to move, disable the maintainer func, let MWC complete its move, and then turn on maintainer() again (lock the mesh, no gravity-caused ramp-sliding allowed). Dunno. Sorry that I am not being of more help. I'm thinkin'. Anti-grav. Quote Link to comment Share on other sites More sharing options...
iiceman Posted July 11, 2015 Share Posted July 11, 2015 Well, that "not inside the render loop" might be the main point. I think in my demo the move with collision is only executed, if a target is set. So you click somewhere and the object moves until the target is reached and then stops the moveWithCollisons. (if I remember right that is of course, still didn't look into the code again ) Quote Link to comment Share on other sites More sharing options...
W1lly Posted July 11, 2015 Author Share Posted July 11, 2015 Yes iiceman, but event though it's only executed if a target is set, the main idea still works for me . I just have to use pickWithRay to find the distance from the character's position to the ground/mesh and use that to determine if I have to apply gravity or not.Here is an example I made inspired from yours : http://www.babylonjs-playground.com/#1OLJNU#2 iiceman 1 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.