DanielChappuis / reactphysics3d

Open source C++ physics engine library in 3D
http://www.reactphysics3d.com
zlib License
1.52k stars 219 forks source link

About supporting players' action #288

Open zack-not-know-why-it-work opened 1 year ago

zack-not-know-why-it-work commented 1 year ago

Hi everyone, I am trying to use this engine in my game project, and I am not sure what is the correct way to support players' input. If anyone have any good advice, please tell me. Thank you.

In my game, players can control a Role (a Capsule in physic world). A joystick controller are used to control direction, and a button is used to do jump action.

Move

I tried 3 solutions, but seems none of them is a good way.

1) add a force to the player's capsule with input direction.

auto force = 5.0f;
role->applyWorldForceAtCenterOfMass(direction * force);

world->update(timeStep);

The problem is that if player input the same direction continually, the capsule's velocity will keep growing and will not stop even player input an empty direction. so I should change other setting to fix it? maybe inertia, I am not sure.

2) calculate move delta, and set position to role rigidbody

double playerVelocity = 8.0f
auto posDelta = direction * timeStep * playerVelocity;

auto trans = role->getTransform();
trans.setPosition(trans.getPosition() + posDelta);
role->setTransform(trans);

world->update(timeStep);

The problem is that CollisionDetection not works well. We can see two Rigidbodys are part of overlap to each other, but actually the second object should be pushed off without any overlap. Maybe playerVelocity is so big. I don't know why.

3) set Velocity

direction.normalize();
auto vel = direction * playerVelocity;
role->setLinearVelocity(vel);

world->update(timeStep);

This way can push other rigidbogy off. But the role not stop immediately when player input empty direction. If user keep input the same direction, the role will keep same velocity and glide into the air.

Jump

add force to up direction, I don't know if this ok.

 Vector3 playerJumpForce{0, 500, 0};
role->applyWorldForceAtCenterOfMass(playerJumpForce);

world->update(timeStep);

Turn around

Seem as move, I not sure which is the right way. 1) set origention

auto trans = role->getTransform();
trans.setOrientation(Quaternion{x,y,z,w});
role->setTransform(trans);

world->update(timeStep);

2) apply Torque

role->applyWorldTorque(Vector3{x,y,z});

world->update(timeStep);

3) set AngularVelocity

role->setAngularVelocity(Vector3{x,y,z});

world->update(timeStep);
DanielChappuis commented 1 year ago

Hello,

You should try to set the type of your rigid body to "kinematic" instead of "dynamic" (default).

On a dynamic body, you can apply forces on it and it's velocity and position will be computed by the physics engine. For a kinematic body, you can set the linear/angular velocity of the body but the position will be computed by the physics engine.

Note: However, kinematic bodies do not collide against other kinematic bodies or static bodies. This could be an issue.

I will try to create a true character controller in the future but this is not implemented for the moment.

kewldan commented 1 year ago

Until the author added support for this to the project. You might be best off using this method to move. If you just modify the position of the player (2nd code) - collisions are useless, you will just go through objects

You are right, you can use addforce to jump, but you need to check for a collision with the surface under the "legs" (Either Callback or Raycast (I'm not sure, but in my opinion none of these methods interact with Static bodies)). In essence, of course, you can make the ground dynamic (every frame just reset the position) to make them work, but then you can not use a mesh-based collider (They work strictly with static RigidBody)

To rotate, you should use

Quaternion::fromEulerAngles(Vector3(0, myRotationY, 0))

And then just "attach" the camera to the capsule, and rotate as you like (X and Y)

kewldan commented 1 year ago

If I'm not mistaken, then for the effect of gravity on an object, it must be Dynamic @DanielChappuis