public void PhysicsMove(float delta, ref Vector3 velocity, Vector2 moveVec, Basis moveBasis, bool sprinting = false, bool jump = false) { var moveVelocity = Vector3.Zero; moveVelocity += moveBasis.x.Normalized() * moveVec.x; moveVelocity += moveBasis.z.Normalized() * moveVec.y; moveVelocity.y = 0; moveVelocity = moveVelocity.Normalized() * (sprinting ? SPRINT_SPEED : MOVE_SPEED); var hVelocity = velocity; hVelocity.y = 0; var accel = (moveVelocity.Dot(hVelocity) > 0) ? (body.IsOnWall() ? ACCELERATION_WALL : ACCELERATION) : DECELERATION; hVelocity = hVelocity.LinearInterpolate(moveVelocity, accel * delta); if (body.IsOnFloor() && jump) { velocity.y = JUMP_SPEED; } velocity.y += GRAVITY * delta; velocity.x = hVelocity.x; velocity.z = hVelocity.z; velocity = body.MoveAndSlide(velocity, Vector3.Up, 0.05f, 4, Mathf.Deg2Rad(20)); }
public void Move(float delta, Vector3 horizontalHeading, bool isJumping, bool isSneaking, bool airJumpAllowed) { // TODO: Add acceleration curves; integrate positions to avoid FPS based de-syncs horizontalHeading.y = 0; var velocityHorizontal = Velocity.MoveToward( horizontalHeading.Normalized() * (isSneaking ? SneakSpeed : FullSpeed), FullSpeed / (Body.IsOnFloor() ? AccelTimeGround : AccelTimeAir) * delta); Velocity.x = velocityHorizontal.x; Velocity.z = velocityHorizontal.z; Velocity.y -= Gravity * delta; Velocity = Body.MoveAndSlide(Velocity, Vector3.Up); // ReSharper disable once InvertIf if (Body.IsOnFloor()) { Velocity.y = 0; } if ((Body.IsOnFloor() || airJumpAllowed) && isJumping) { Velocity.y = JumpMagnitude; } }
// Super basic test public void ProcessMovement(FPSInput input, float delta) { debugSb.Clear(); ApplyRotations(); //Console.WriteLine($"Buttons {input.buttons} delta {delta}"); Vector3 inputDir = new Vector3(); if (input.isBitOn(FPSInput.BitMoveForward)) { inputDir.z -= 1; } if (input.isBitOn(FPSInput.BitMoveBackward)) { inputDir.z += 1; } if (input.isBitOn(FPSInput.BitMoveLeft)) { inputDir.x -= 1; } if (input.isBitOn(FPSInput.BitMoveRight)) { inputDir.x += 1; } float mouseMoveX = 0; // horizontal turn float mouseMoveY = 0; // verticla turn if (input.isBitOn(FPSInput.BitLookLeft)) { mouseMoveX += KEYBOARD_TURN_DEGREES_PER_SECOND; } if (input.isBitOn(FPSInput.BitLookRight)) { mouseMoveX -= KEYBOARD_TURN_DEGREES_PER_SECOND; } if (input.isBitOn(FPSInput.BitLookUp)) { mouseMoveY += KEYBOARD_TURN_DEGREES_PER_SECOND; } if (input.isBitOn(FPSInput.BitLookDown)) { mouseMoveY -= KEYBOARD_TURN_DEGREES_PER_SECOND; } yaw += mouseMoveX * delta; pitch += mouseMoveY * delta; // convert desired move to world axes Transform t = _body.GlobalTransform; Vector3 forward = t.basis.z; Vector3 left = t.basis.x; Vector3 runPush = Vector3.Zero; runPush.x += forward.x * inputDir.z; runPush.z += forward.z * inputDir.z; runPush.x += left.x * inputDir.x; runPush.z += left.z * inputDir.x; runPush = runPush.Normalized(); // calculate horizontal move independently. Vector3 horizontal = CalcVelocityQuakeStyle( velocity, runPush, MOVE_SPEED, delta, true); velocity.x = horizontal.x; velocity.z = horizontal.z; // Apply external push Vector3 prevPosition = t.origin; // Move! Vector3 moveResult = _body.MoveAndSlide(velocity); // record move info for next frame lastMove = _body.GlobalTransform.origin - prevPosition; lastDelta = delta; debugSb.Append($"Pitch {pitch}\nyaw {yaw}\n"); debugSb.Append($"Prev delta {lastDelta}\n"); debugSb.Append($"Prev move {lastMove}\n"); debugSb.Append($"Velocity {velocity}\n"); debugSb.Append($"Run push {runPush}\n"); debugSb.Append($"Move spd {MOVE_SPEED} accel {MOVE_ACCELERATION}\n"); }
public override void Process(float delta) { //This sort of initialisation needs a refactor, but suffices for now. if (frameNum == 2) { // Initialise things that need to wait for emitting signals here. // To give other components a chance to set up and fire. // get all objects that start in range which could not fire the signals Array bodies = area.GetOverlappingBodies(); foreach (PhysicsBody body in bodies) { if (IsWatching(body)) { parent.SendMessage("objectInRange", body); } } frameNum++; } else if (frameNum == 1) { // Initialise things that rely on emitting custom signals here. frameNum++; } else if (frameNum == 0) { frameNum++; } velocity.x = direction.x * speed * delta; velocity.z = direction.y * speed * delta; velocity.y -= gravity * delta; if (velocity.y < -terminal) { velocity.y = -terminal; } Vector3 newVelocity = body.MoveAndSlide(velocity, new Vector3(0.0f, 1.0f, 0.0f)); float xDif = Math.Abs(velocity.x - newVelocity.x); float zDif = Math.Abs(velocity.z - newVelocity.z); if (xDif > terrainInterferenceEpsilon || zDif > terrainInterferenceEpsilon) { parent.SendMessage("terrainInterference"); } int numCollisions = body.GetSlideCount(); for (int i = 0; i < numCollisions; i++) { parent.SendMessage("collided", body.GetSlideCollision(i)); } if (tojump) { velocity.y = jumpMagnitude; tojump = false; } else { velocity.y = newVelocity.y; } }