The Snow Irbix Posted August 29, 2017 Share Posted August 29, 2017 Hi guys ! I did a playground with my FreeCamera jumping when pressing the spacebar, here it is : https://playground.babylonjs.com/#JRHZ1B To get a good result, I was forced to set the gravity to -0.2, and I want to know why setting the gravity to -0.9 doesn't give a realistic result. I already read the older topics on the forum on how to create a jumping animation, but they don't use gravity and causes the player's camera to go through the box (http://www.babylonjs-playground.com/#XN87O#41) Any idea to improve my jump animation with a gravity set to -0.9 ? Or can I set a different gravity for the camera and for the other objects ? Thanks Quote Link to comment Share on other sites More sharing options...
The Snow Irbix Posted August 31, 2017 Author Share Posted August 31, 2017 In fact, the gravity implementation is weird. Currently, the camera falls at a constant speed instead of gaining speed while falling (until the air resistance prevents the speed from increasing). How could I make my own implementation of the gravity while keeping the collision system ? Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted August 31, 2017 Share Posted August 31, 2017 you can set the camera.applyGravity = false and then manually compute it The Snow Irbix 1 Quote Link to comment Share on other sites More sharing options...
The Snow Irbix Posted September 13, 2017 Author Share Posted September 13, 2017 I managed to get a better gravity implementation by modifying the FreeCamera code directly. I share it with the forum if someone wanna make a realistic jump animation. Feel free to improve the code and share it with us. var BABYLON; (function (BABYLON) { var FreeCamera = (function (_super) { __extends(FreeCamera, _super); function FreeCamera(name, position, scene) { var _this = _super.call(this, name, position, scene) || this; _this.ellipsoid = new BABYLON.Vector3(0.5, 1, 0.5); _this.checkCollisions = false; _this.applyGravity = false; _this._impulsion = BABYLON.Vector3.Zero(); _this._jumpingFlag = false; _this._inertia = BABYLON.Vector3.Zero(); _this._needMoveForGravity = false; _this._oldPosition = BABYLON.Vector3.Zero(); _this._diffPosition = BABYLON.Vector3.Zero(); _this._newPosition = BABYLON.Vector3.Zero(); // Collisions _this._collisionMask = -1; _this._onCollisionPositionChange = function (collisionId, newPosition, collidedMesh) { if (collidedMesh === void 0) { collidedMesh = null; } //TODO move this to the collision coordinator! if (_this.getScene().workerCollisions) newPosition.multiplyInPlace(_this._collider.radius); var updatePosition = function (newPos) { _this._newPosition.copyFrom(newPos); _this._newPosition.subtractToRef(_this._oldPosition, _this._diffPosition); var oldPosition = _this.position.clone(); if (_this._diffPosition.length() > BABYLON.Engine.CollisionsEpsilon) { _this.position.addInPlace(_this._diffPosition); if(collidedMesh) { // when moving but collision with ground _this._inertia = BABYLON.Vector3.Zero(); _this._jumpingFlag = false; } if (_this.onCollide && collidedMesh) { _this.onCollide(collidedMesh); } } else { // when not moving but still near the ground _this._inertia = BABYLON.Vector3.Zero(); _this._jumpingFlag = false; } }; updatePosition(newPosition); }; _this.inputs = new BABYLON.FreeCameraInputsManager(_this); _this.inputs.addKeyboard().addMouse(); return _this; } Object.defineProperty(FreeCamera.prototype, "angularSensibility", { //-- begin properties for backward compatibility for inputs get: function () { var mouse = this.inputs.attached["mouse"]; if (mouse) return mouse.angularSensibility; }, set: function (value) { var mouse = this.inputs.attached["mouse"]; if (mouse) mouse.angularSensibility = value; }, enumerable: true, configurable: true }); Object.defineProperty(FreeCamera.prototype, "keysUp", { get: function () { var keyboard = this.inputs.attached["keyboard"]; if (keyboard) return keyboard.keysUp; }, set: function (value) { var keyboard = this.inputs.attached["keyboard"]; if (keyboard) keyboard.keysUp = value; }, enumerable: true, configurable: true }); Object.defineProperty(FreeCamera.prototype, "keysDown", { get: function () { var keyboard = this.inputs.attached["keyboard"]; if (keyboard) return keyboard.keysDown; }, set: function (value) { var keyboard = this.inputs.attached["keyboard"]; if (keyboard) keyboard.keysDown = value; }, enumerable: true, configurable: true }); Object.defineProperty(FreeCamera.prototype, "keysLeft", { get: function () { var keyboard = this.inputs.attached["keyboard"]; if (keyboard) return keyboard.keysLeft; }, set: function (value) { var keyboard = this.inputs.attached["keyboard"]; if (keyboard) keyboard.keysLeft = value; }, enumerable: true, configurable: true }); Object.defineProperty(FreeCamera.prototype, "keysRight", { get: function () { var keyboard = this.inputs.attached["keyboard"]; if (keyboard) return keyboard.keysRight; }, set: function (value) { var keyboard = this.inputs.attached["keyboard"]; if (keyboard) keyboard.keysRight = value; }, enumerable: true, configurable: true }); // Controls FreeCamera.prototype.attachControl = function (element, noPreventDefault) { this.inputs.attachElement(element, noPreventDefault); }; FreeCamera.prototype.detachControl = function (element) { this.inputs.detachElement(element); this.cameraDirection = new BABYLON.Vector3(0, 0, 0); this.cameraRotation = new BABYLON.Vector2(0, 0); }; Object.defineProperty(FreeCamera.prototype, "collisionMask", { get: function () { return this._collisionMask; }, set: function (mask) { this._collisionMask = !isNaN(mask) ? mask : -1; }, enumerable: true, configurable: true }); FreeCamera.prototype._collideWithWorld = function (velocity) { var globalPosition; if (this.parent) { globalPosition = BABYLON.Vector3.TransformCoordinates(this.position, this.parent.getWorldMatrix()); } else { globalPosition = this.position; } globalPosition.subtractFromFloatsToRef(0, this.ellipsoid.y, 0, this._oldPosition); if (!this._collider) { this._collider = new BABYLON.Collider(); } this._collider.radius = this.ellipsoid; this._collider.collisionMask = this._collisionMask; //no need for clone, as long as gravity is not on. var actualVelocity = velocity; //add gravity to the velocity to prevent the dual-collision checking if(this.applyGravity) { if(!this._impulsion.equals(BABYLON.Vector3.Zero())) // impulsion != 0 { if(this._jumpingFlag === false) // not already jumping { this._jumpingFlag = true; this._inertia.addInPlace(this._impulsion); } this._impulsion = BABYLON.Vector3.Zero(); } this._inertia.addInPlace(this.getScene().gravity.scale(1/60)); // 1/60 if we assume the 60 fps actualVelocity = velocity.add(this._inertia); } this.getScene().collisionCoordinator.getNewPosition(this._oldPosition, actualVelocity, this._collider, 3, null, this._onCollisionPositionChange, this.uniqueId); }; FreeCamera.prototype._checkInputs = function () { if (!this._localDirection) { this._localDirection = BABYLON.Vector3.Zero(); this._transformedDirection = BABYLON.Vector3.Zero(); } this.inputs.checkInputs(); _super.prototype._checkInputs.call(this); }; FreeCamera.prototype._decideIfNeedsToMove = function () { return this._needMoveForGravity || Math.abs(this.cameraDirection.x) > 0 || Math.abs(this.cameraDirection.y) > 0 || Math.abs(this.cameraDirection.z) > 0; }; FreeCamera.prototype._updatePosition = function () { if (this.checkCollisions && this.getScene().collisionsEnabled) { this._collideWithWorld(this.cameraDirection); } else { _super.prototype._updatePosition.call(this); } }; FreeCamera.prototype.dispose = function () { this.inputs.clear(); _super.prototype.dispose.call(this); }; FreeCamera.prototype.getClassName = function () { return "FreeCamera"; }; return FreeCamera; }(BABYLON.TargetCamera)); __decorate([ BABYLON.serializeAsVector3() ], FreeCamera.prototype, "ellipsoid", void 0); __decorate([ BABYLON.serialize() ], FreeCamera.prototype, "checkCollisions", void 0); __decorate([ BABYLON.serialize() ], FreeCamera.prototype, "applyGravity", void 0); BABYLON.FreeCamera = FreeCamera; })(BABYLON || (BABYLON = {})); The "inertia" variable is used to store the current velocity of the camera The "jumpingFlag" is used to prevent the player to jump several times without hitting the ground. And the "impulsion" is a velocity vector added to the current velocity of the camera. So now, jump is as easy as that : window.addEventListener('keydown', function(e) { if(e.key === ' ') { camera._impulsion.set(0, 0.25, 0); } }); Sadly I couldn't make a good implementation of the gravity with the camera's "onCollide" callback only, so I can't make a demo on the playground cause I modified the internal BABYLON code. Hope it will help another one ! EDIT : This works only if the "needMoveForGravity" flag is set to 'true'. camera._needMoveForGravity = true; GameMonetize 1 Quote Link to comment Share on other sites More sharing options...
The Snow Irbix Posted September 14, 2017 Author Share Posted September 14, 2017 Can't stop the progress @Deltakosh ! Quote I can't make a demo on the playground Actually I can. And I did Here it is ! http://playground.babylonjs.com/indexstable#0S38ZF 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.