Strange boost to velocity when applying upwards velocity to character controller while it is colliding on a "ramp"-like shape #1221
Answered
by
jrouwe
Mahmoud1205
asked this question in
Q&A
-
Here is a video of this problem to make the title clear https://github.com/user-attachments/assets/a8e26d5c-e9b5-4f59-a91a-db04342f117d
JPH::StaticCompoundShapeSettings meshSceneShapeSettings;
for (Mesh& mesh : model->meshes) {
JPH::TriangleList joltTriangles;
for (size_t i = 0; i + 2 < mesh.vertices.size(); i += 3) {
joltTriangles.emplace_back(
types::GlmToJph(mesh.vertices[i].Position),
types::GlmToJph(mesh.vertices[i + 1].Position),
types::GlmToJph(mesh.vertices[i + 2].Position)
);
}
meshSceneShapeSettings.AddShape(JPH::Vec3::sZero(), JPH::Quat::sIdentity(), new JPH::MeshShapeSettings(joltTriangles));
}
return JPH::BodyCreationSettings(
meshSceneShapeSettings.Create().Get(),
types::GlmToJph(position), JPH::Quat::sIdentity(),
JPH::EMotionType::Static, Layers::NON_MOVING
); // this return value is used by the application to add the body into the physics world For more context, below is the code used, 99% of it is from the character controller sample and the below code snippet is ran every frame before the physics system and character update calls. Character::EGroundState ground_state = pCharacter->GetGroundState();
if (ground_state == Character::EGroundState::OnSteepGround
|| ground_state == Character::EGroundState::NotSupported) {
Vec3 normal = pCharacter->GetGroundNormal();
normal.SetY(0.0f);
f32 dot = normal.Dot(movementDirection);
if (dot < 0.0f)
movementDirection -= (dot * normal) / normal.LengthSq();
}
if (pCharacter->IsSupported()) {
if (glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS) {
crouchingShape.AddRef();
pCharacter->SetShape(&crouchingShape, FLT_MAX);
standingShape.Release();
}
if (glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) == GLFW_RELEASE) {
standingShape.AddRef();
pCharacter->SetShape(&standingShape, FLT_MAX);
crouchingShape.Release();
}
Vec3 current_velocity = pCharacter->GetLinearVelocity();
Vec3 desired_velocity = 6.0f * movementDirection;
if (!desired_velocity.IsNearZero() || current_velocity.GetY() < 0.0f || !pCharacter->IsSupported())
desired_velocity.SetY(current_velocity.GetY());
Vec3 new_velocity = 0.75f * current_velocity + 0.25f * desired_velocity;
if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS && ground_state == Character::EGroundState::OnGround)
new_velocity += Vec3(0, 4.0f, 0);
new_velocity *= speedMultiplier;
pCharacter->SetLinearVelocity(new_velocity);
} Below is the code that sets up the character controller: CharacterSettings character_settings;
character_settings.mMaxSlopeAngle = DegreesToRadians(45.0f);
character_settings.mLayer = Layers::MOVING;
character_settings.mShape = &standingShape;
character_settings.mFriction = 0.5f;
character_settings.mSupportingVolume = Plane(Vec3::sAxisY(), 1.0f);
Character character(&character_settings, types::GlmToJph(camera.pos), Quat::sIdentity(), 0, pPhysicsSystem);
character.AddToPhysicsSystem(EActivation::Activate);
pCharacter = &character; |
Beta Was this translation helpful? Give feedback.
Answered by
jrouwe
Aug 17, 2024
Replies: 1 comment 1 reply
-
I would strongly suggest to use the CharacterVirtual class instead of the Character class for player character movement. |
Beta Was this translation helpful? Give feedback.
1 reply
Answer selected by
Mahmoud1205
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I would strongly suggest to use the CharacterVirtual class instead of the Character class for player character movement.