Reputation: 148
I am using 3D (Three.js) and physics (Rapier), and I want to control the box movement like a car, with arrow keys, but I have difficulty fixing the movement in the right direction with physics.
Here is a code example https://codesandbox.io/s/q-stackoverflow-9j4sf1
What do I need to insert inside useFrame
?
useFrame
:
useFrame((state, delta) => {
if (ref.current) {
const box = ref.current;
/// what i should insert in this area
// w/ArrpUP click
if (controllers.forward.isPress) {
// What do I need to insert so that the box moves forward
}
// s/ArrpDown click
if (controllers.backward.isPress) {
// What do I need to insert so that the box moves backward
}
// L/ArrpLeft click
if (controllers.left.isPress) {
// What do I need to insert so that the box rotate left
}
// R/ArrpRight click
if (controllers.right.isPress) {
// What do I need to insert so that the box rotate right
}
}});
Upvotes: 2
Views: 345
Reputation: 883
The Kinematic Character Controller is a higher-level tool that will emit the proper ray-casts and shape-casts to adjust the user-defined trajectory based on obstacles. Character controller guide
Use the DynamicRayCastVehicleController class for a more realistic vehicle simulation: DynamicRayCastVehicleController
Here is a basic JS example of the Character Controller using your useFrame
loop function. You may want to replace the Cuboid
with a Capsule
for smoother results.
// Create a basic world with all your obstacles
let world = new RAPIER.World({ x: 0.0, y: -9.81, z: 0.0 });
// Initialize your character rigid body and collider
let rigidBodyDesc = new RAPIER.RigidBodyDesc(RAPIER.RigidBodyType['KinematicPositionBased']);
let rigidBody = world.createRigidBody(rigidBodyDesc);
let colliderDesc = new RAPIER.ColliderDesc(RAPIER.Cuboid(0.5, 0.5, 0.5));
let collider = world.createCollider(colliderDesc, rigidBody);
// Initialize your character controller and conditions
let characterController = world.createCharacterController(0.01);
let velocity = new THREE.Vector3();
let movement = new THREE.Vector3();
let nextTranslation = new THREE.Vector3();
let speed = 5;
// Define your loop function
useFrame((state, delta) => {
if (ref.current) {
// Simulate gravity
velocity.y -= delta;
// Simulate movement damping
velocity.z *= 0.5;
velocity.x *= 0.5;
// Update velocity from keyboard input
if (controllers.forward.isPress) velocity.z -= delta * speed;
if (controllers.backward.isPress) velocity.z += delta * speed;
if (controllers.left.isPress) velocity.x -= delta * speed;
if (controllers.right.isPress) velocity.x += delta * speed;
// Calculate collider movement
controller.computeColliderMovement(collider, velocity);
// (optional) Check collisions
for (var i = 0; i < controller.numComputedCollisions(); i++) {
let collision = controller.computedCollision(i);
}
// Calculate next translation from computed movement
movement.copy(controller.computedMovement());
nextTranslation.copy(rigidBody.translation());
nextTranslation.add(movement);
rigidBody.setNextKinematicTranslation(nextTranslation);
}});
Upvotes: 1