BsFPSWalker.cpp 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #include "BsFPSWalker.h"
  2. #include "Math/BsVector3.h"
  3. #include "Math/BsMath.h"
  4. #include "Scene/BsSceneObject.h"
  5. #include "Components/BsCCamera.h"
  6. #include "Components/BsCCharacterController.h"
  7. #include "BsApplication.h"
  8. #include "Physics/BsPhysics.h"
  9. #include "Utility/BsTime.h"
  10. namespace bs
  11. {
  12. /** Initial movement speed. */
  13. constexpr float START_SPEED = 4.0f; // m/s
  14. /** Maximum movement speed. */
  15. constexpr float TOP_SPEED = 7.0f; // m/s
  16. /** Acceleration that determines how quickly to go from starting to top speed. */
  17. constexpr float ACCELERATION = 1.5f;
  18. /** Multiplier applied to the speed when the fast move button is held. */
  19. constexpr float FAST_MODE_MULTIPLIER = 2.0f;
  20. FPSWalker::FPSWalker(const HSceneObject& parent)
  21. :Component(parent)
  22. {
  23. // Set a name for the component, so we can find it later if needed
  24. setName("FPSWalker");
  25. // Find the CharacterController we'll be using for movement
  26. mController = SO()->getComponent<CCharacterController>();
  27. // Get handles for key bindings. Actual keys attached to these bindings will be registered during app start-up.
  28. mMoveForward = VirtualButton("Forward");
  29. mMoveBack = VirtualButton("Back");
  30. mMoveLeft = VirtualButton("Left");
  31. mMoveRight = VirtualButton("Right");
  32. mFastMove = VirtualButton("FastMove");
  33. }
  34. void FPSWalker::fixedUpdate()
  35. {
  36. // Check if any movement keys are being held
  37. bool goingForward = gVirtualInput().isButtonHeld(mMoveForward);
  38. bool goingBack = gVirtualInput().isButtonHeld(mMoveBack);
  39. bool goingLeft = gVirtualInput().isButtonHeld(mMoveLeft);
  40. bool goingRight = gVirtualInput().isButtonHeld(mMoveRight);
  41. bool fastMove = gVirtualInput().isButtonHeld(mFastMove);
  42. const Transform& tfrm = SO()->getTransform();
  43. // If the movement button is pressed, determine direction to move in
  44. Vector3 direction = Vector3::ZERO;
  45. if (goingForward) direction += tfrm.getForward();
  46. if (goingBack) direction -= tfrm.getForward();
  47. if (goingRight) direction += tfrm.getRight();
  48. if (goingLeft) direction -= tfrm.getRight();
  49. // Eliminate vertical movement
  50. direction.y = 0.0f;
  51. direction.normalize();
  52. const float frameDelta = gTime().getFixedFrameDelta();
  53. // If a direction is chosen, normalize it to determine final direction.
  54. if (direction.squaredLength() != 0)
  55. {
  56. direction.normalize();
  57. // Apply fast move multiplier if the fast move button is held.
  58. float multiplier = 1.0f;
  59. if (fastMove)
  60. multiplier = FAST_MODE_MULTIPLIER;
  61. // Calculate current speed of the camera
  62. mCurrentSpeed = Math::clamp(mCurrentSpeed + ACCELERATION * frameDelta, START_SPEED, TOP_SPEED);
  63. mCurrentSpeed *= multiplier;
  64. }
  65. else
  66. {
  67. mCurrentSpeed = 0.0f;
  68. }
  69. // If the current speed isn't too small, move the camera in the wanted direction
  70. Vector3 velocity(BsZero);
  71. float tooSmall = std::numeric_limits<float>::epsilon();
  72. if (mCurrentSpeed > tooSmall)
  73. velocity = direction * mCurrentSpeed;
  74. // Note: Gravity is acceleration, but since the walker doesn't support falling, just apply it as a velocity
  75. Vector3 gravity = gPhysics().getGravity();
  76. mController->move((velocity + gravity) * frameDelta);
  77. }
  78. }