Character Controller

General discussion around Urho3D.

Character Controller

PostPosted by JamesK89 » 02 Nov 2015, 23:41

The character demo is nice and all but as most of us may know dynamic force based character controllers are highly unpredictable and don't feel natural unless that is what you are going for.

That being said I'm just wondering if anyone has come up with a kinematic character controller that uses custom movement and collision logic for that traditional FPS feel and control (à la Quake, Half-Life, Unreal, etc..)?

I've been tinkering with Urho3D seeing if I can come up with something using ConvexCast but I am inexperienced with the library thus far so if someone has already written something and wants to share I'd appreciate it.
User avatar
JamesK89
New user
New user
 
Posts: 15
Joined: 03 Feb 2015, 05:50
Location: North Carolina, USA

Re: Character Controller

PostPosted by Enhex » 03 Nov 2015, 14:31

JamesK89 wrote:The character demo is nice and all but as most of us may know dynamic force based character controllers are highly unpredictable and don't feel natural unless that is what you are going for.

That being said I'm just wondering if anyone has come up with a kinematic character controller that uses custom movement and collision logic for that traditional FPS feel and control (à la Quake, Half-Life, Unreal, etc..)?

I've been tinkering with Urho3D seeing if I can come up with something using ConvexCast but I am inexperienced with the library thus far so if someone has already written something and wants to share I'd appreciate it.


The problem with dynamic controllers is that you can't implement advanced features for them like stair stepping.
Other than that you can make them control and move just like quake/hl ones. (I did myself)

I'm working on a hybrid controller now - rigid body with kinematic movement to let the physics engine handle pushing and getting pushed by stuff.
Stair stepping is difficult to implement in Bullet Physics because Bullet relies on collision margins(tons of features break without it, including sweeps & raycasts), and they make everything round.
So combining features like auto stair stepping with maximum walkable ground slope angle creates a problem: if you step on a rounded corner (which all stairs will be) you'll get a steep slope and the traditional quake-style stepping doesn't handle such a thing, so you'll bump into the stair and perhaps some other undesired behaviors.

I'm almost done solving all the problems with my controller, so it should be possible to handle the roundness from the collision margins.

Other than that the quake games and doom 3 are open source on github and u can try to see what they do.
Valve's Source SDK is also open source on Github.

Oh an last time I checked the bullet kinematic char controller demo wasn't good and it had flawed manual recovery from penetration algorithm.
I made a post asking for a better method on the Bullet forums and got a good answer: http://www.bulletphysics.org/Bullet/php ... =9&t=10843
User avatar
Enhex
Most active user
Most active user
 
Posts: 325
Joined: 31 Dec 2014, 12:23

Re: Character Controller

PostPosted by JamesK89 » 03 Nov 2015, 18:41

It's been while since I looked at the SDK code but if I'm not mistaken Valve's character controller in Half-Life basically does manual collision detection against the world with a kinematic body attached for interaction with dynamic objects. I'm thinking it may be the only way to get the best of both worlds if Bullet is that terrible at this.
User avatar
JamesK89
New user
New user
 
Posts: 15
Joined: 03 Feb 2015, 05:50
Location: North Carolina, USA

Re: Character Controller

PostPosted by Enhex » 03 Nov 2015, 18:53

JamesK89 wrote:It's been while since I looked at the SDK code but if I'm not mistaken Valve's character controller in Half-Life basically does manual collision detection against the world with a kinematic body attached for interaction with dynamic objects. I'm thinking it may be the only way to get the best of both worlds if Bullet is that terrible at this.


Not sure what you mean by "at this" but using a kinematic body won't change any of the problems I mentioned.
The kinematic control can be the same with no problem, and so is interaction with dynamic objects. The problem is that everything is round.
In case you don't know what collision margins are or how they behave, you have to watch this video because it's very important for working with Bullet:
User avatar
Enhex
Most active user
Most active user
 
Posts: 325
Joined: 31 Dec 2014, 12:23

Re: Character Controller

PostPosted by JamesK89 » 03 Nov 2015, 20:54

Enhex wrote:using a kinematic body won't change any of the problems I mentioned.


What I meant was doing the majority of collision detections yourself outside of Bullet but using either a kinematic body that shadows your player object to interact with dynamic objects or otherwise applying forces upon collision with dynamic objects yourself.

As much work as it is that seems to be the best way to get the best of both worlds and it seems to be what Valve has done.
Of course every project has its own requirements so I imagine such an approach would be overblown in some cases.
User avatar
JamesK89
New user
New user
 
Posts: 15
Joined: 03 Feb 2015, 05:50
Location: North Carolina, USA

Re: Character Controller

PostPosted by Dave82 » 03 Nov 2015, 23:41

JamesK89 wrote:The character demo is nice and all but as most of us may know dynamic force based character controllers are highly unpredictable and don't feel natural unless that is what you are going for.

That being said I'm just wondering if anyone has come up with a kinematic character controller that uses custom movement and collision logic for that traditional FPS feel and control (à la Quake, Half-Life, Unreal, etc..)?

I've been tinkering with Urho3D seeing if I can come up with something using ConvexCast but I am inexperienced with the library thus far so if someone has already written something and wants to share I'd appreciate it.


Hi James ! I saw your private message so i decided to write here so other might find it useful too.

Kinematic Controller : It's a bad idea , since the interaction withe the physics world won't work properly and you will need workarounds which is a bad thing i think.
ConvexCast : Thats a bad idea either beacuse this way the character controller tries to solve collision detection externally , and you will need hell of a lot work to get things working (manual force calculations , contact manual manifold sorting etc) and still you will have problems.

Here's how i did it in Infested :

I modified Urho's existing character controller :

1. Set Friction to 0.0f ! This will disable the ice-skate simulator :D
Code: Select all
characterBody->SetFriction(0.0f);


2.You need to modify the MOVE_FORCE , JUMP_FORCE etc variables to your game world and character size (this will take some time to have good results and sync the movement with walk and run animations)

3.The meat and potato.I rewrote the onGround_ check. Urho uses simple intersection test (handled in HandleNodeCollision) i handle it in FixedUpdate like this :

Code: Select all
void INFCharacterController::FixedUpdate(float timeStep)
{
       
      // Reset grounded and falling flag for next frame
      onGround_ = false;
      falling = false;
     
      Vector3 planeVelocity(velocity.x_, 0.0f, velocity.z_);
      Vector3 brakeForce = -planeVelocity * BRAKE_FORCE;

      if (controls_.IsDown(CTRL_FORWARD)) moveDir -= Vector3::FORWARD;
      if (controls_.IsDown(CTRL_BACK)) moveDir -= Vector3::BACK * 2.0f;
      if (controls_.IsDown(CTRL_LEFT)) moveDir -= Vector3::LEFT;
      if (controls_.IsDown(CTRL_RIGHT)) moveDir -= Vector3::RIGHT;
   
      // Normalize move vector so that diagonal strafing is not faster
      if (moveDir.LengthSquared() > 0.0f) moveDir.Normalize();

      Urho3D::Vector3 inairMoveForce = rot * moveDir * INAIR_MOVE_FORCE;  // if the player jumps or falling this extra force is applied to allow slight movement
     
      // Temporarily set collision flag to 0 to avoid self collisiojn check
      unsigned int flag = body->GetCollisionMask();
      body->SetCollisionMask(0);

     // raycast from the center of the player downwards and see if we hit something in certain distance
     Urho3D::PhysicsRaycastResult prr;
   
     pw->SphereCast(prr,Urho3D::Ray(characterCenter , Urho3D::Vector3(0,-1,0)),radius , 1000.0f);
     
     if (prr.distance_ <= distTreshold)
     {
          // this means we are hitting the floor now set the onGround and fall flag to
          onGround_ = true;
          falling = false;
       
          inairMoveForce = Urho3D::Vector3::ZERO; // if we are moving no inair force
          if (!jumping) moveForce = rot * moveDir * (controls_.IsDown(CTRL_BACK) ? MOVE_FORCE * 0.5f : MOVE_FORCE); // Moving slower backwards...
   
    }
   else
   {
          onGround_ = false;
          falling = true;
    }
   
   // Reset collision flag back :
   body->SetCollisionMask(flag);
   
   
   // This is part of the jump code : If we are in jump mode we start counting and reset our "jumping" flag to false only if some time passed and linear velocity is smaller thatn 0 (e.g the character is falling !)
   if (jumping)
   {
        jumpTimer += timeStep;
        if (jumpTimer >= 0.5f && body->GetLinearVelocity().y_ <= 0.0f)
        {
   jumping = false;
   jumpTimer = 0.0f;
        }
   }
      // and finally apply the necessary forces calculated this frame : (the scaleForce is a normalized value and is used to slow down or speed up the player.
     // For an example : if the player walks in water the scaleForce changes. The deeper that water is the smaller the scaleForce value is...

     body->ApplyImpulse(moveForce * scaleForce);   // The general move force
     body->ApplyImpulse(inairMoveForce); // Move force applied if the player is jumping (its 0 if not jumping)
     body->ApplyImpulse(brakeForce);  // and apply some brake force to avoid the character to accelerate to infinity.
}


So in nuthshell : Check wether the player stands or floor or not by doing a raycast from the center of the player downwards.If yes simply apply move force if not , apply inair move force.
When doing SphereCast you have 3 variables to set up properly the : characterCenter (the center of your shape) the radius and distTreshold.
1 the center of the character is given in world space. (bodyWorldPos.y_ += characterHeight / 2);
2 . radius is a bit smaller than your capsule's radius (eg if capsule radius is 10 then radius is 9 or 8)
3. distTreshold is the distance that shows what is smallest distance where the player is considered to standing on floor.This is usually a bit bigger number than your capsule's half height.
if the half height of your character is 15 this value should be 18 (you can calculate it simply distTreshold = capsuleHalgHeight * 1.2f);



4. jumping : Is done simply by checking if the player already jumping ? if not apply jumpForce , or do nothing

Code: Select all
void INFCharacterController::jump()
{
    if (!jumping && onGround_)
    {
   jumping = true;
   RigidBody* body = GetComponent<RigidBody>();
   float n = -(body->GetLinearVelocity().y_ * 0.5f);
   body->ApplyImpulse(Vector3::UP * (jumpForce + n));
    }
}


Also there is a bit of trick that should be mentioned : you have to take into account the current linear velocity when apply jumping , because the jump height while going downhill or uphill will be different due to physisc engine (To achieve the same jump height bigger force is needed when the character is going downwards and smaller if going upwards. Use the current linear velocity to calculate te required force).


PS : There's a lot of variables you have to tweak to have good result the forces , timers , dimensions , mass , etc. But i suggest to have one unique scalar variable that can change everything.
calculate everything for characterScale = 1.0f; if your set thin value to 2.0f everything will be recalculated (forces masses sizes etc).So you don't need additional code to handle different size enemies/players.

Stairs and slopes... the Phiscs Engines' worst enemies :D So instead of writing some code to handle these situations i suggest to use some hidden helper meshes as i did
Wrong Geometry : you have to plan your levels wisely ! No matter how professional your character controller is , if the level geometry is wrong it will stuck in walls , narrow streets , invalid polygons etc.

Don't hesitate to ask if you need further help
Regards
Infested : An old school puzzle solving survival horror game :
topic1430.html

Infested Facebook page
https://www.facebook.com/infestedgame
User avatar
Dave82
Active user
Active user
 
Posts: 136
Joined: 11 May 2015, 18:08

Re: Character Controller

PostPosted by Enhex » 04 Nov 2015, 06:21

JamesK89 wrote:What I meant was doing the majority of collision detections yourself outside of Bullet but using either a kinematic body that shadows your player object to interact with dynamic objects or otherwise applying forces upon collision with dynamic objects yourself.


I know, and I'm telling you it won't change anything because you'll still be colliding with collision margins, unless you plan to write your own physics engine.


Dave82 wrote:Kinematic Controller : It's a bad idea , since the interaction withe the physics world won't work properly and you will need workarounds which is a bad thing i think.
ConvexCast : Thats a bad idea either beacuse this way the character controller tries to solve collision detection externally , and you will need hell of a lot work to get things working (manual force calculations , contact manual manifold sorting etc) and still you will have problems.

That's bad advice. JamesK89 mentioned he wants something like quake-based controllers and those have auto stair stepping.
Just moving around a rigid body is trivial, but to implement something that can step over stairs is impossible using a rigid body because:
Image
Note that Bullet can't add time on individual bodies so you can't split up the movement.
The only way to achieve that is with sweeps (AKA convextCasts in urho).
The common "workaround" is using capsule shapes, but you'll still have a bump that will kill the player's velocity, it's far inferior solution.

Note that an alternative path is to make sure you don't have stairs in your game, usually by using ramps - either visible, or invisible over stairs.
With this limitation a simple character controller will be enough.
User avatar
Enhex
Most active user
Most active user
 
Posts: 325
Joined: 31 Dec 2014, 12:23

Re: Character Controller

PostPosted by Zaroio » 04 Nov 2015, 14:08

To cimb a stair user a Kinematic Body and and a leg (raycast downward). Use a Kinematic Body, it will give you more controll


Image
User avatar
Zaroio
New user
New user
 
Posts: 5
Joined: 12 Oct 2014, 16:10

Re: Character Controller

PostPosted by Dave82 » 04 Nov 2015, 14:48

That's bad advice. JamesK89 mentioned he wants something like quake-based controllers and those have auto stair stepping.


As i mentioned i used invisible helper meshes in my game for stairs.I found this approach a lot easier than adding extra calculations which need lots of testing and tweaking. But adding some extra polys in a level editor is a lot faster and easier.You can even add invisible walls to forbid movement on a steep terrain etc Rigid bodies give far the best result as character controller.

1. A lot easier to implement (i wrote my own 3d and 2d collsion detection and response library including quad/octrees , swept volumes (rectangle , circle/box sphere) and sliding vector calculation for practicing and learning purposes and it was a pain in the ass , and still missed some features and had some issues.It was really great and most of my linear algebra knowledge comes from these books and practicing , but i rather stick with a out of a box solution if a want to write a game)
2. Automatic interaction with dynamic world (Using kinematic controllers you need extra steps to push crates or be pushed by elevators etc)
3. Utomatic velocity calculation (with kinematic controllers you need extra step for that , e.g : character jumps and hit the ceiling with his head , bullet will automatically calculate the necessary "reversed" velocity)

It's up to James what he trying to do.If he want to learn how collision detection and response and character controllers work , then he can use kinematic bodies or convex cast , but if his plans are to write a game i would stick with built in features. (personal opinion)

I implemented a rigid body character controller in my game and i say you can have a decent (almost kinematic) character controller. I tried both kinematic bodies and swept test , and found both to be lot harder to implement and always had the stucking in walls problem
Infested : An old school puzzle solving survival horror game :
topic1430.html

Infested Facebook page
https://www.facebook.com/infestedgame
User avatar
Dave82
Active user
Active user
 
Posts: 136
Joined: 11 May 2015, 18:08

Re: Character Controller

PostPosted by Enhex » 04 Nov 2015, 15:51

Zaroio wrote:To cimb a stair user a Kinematic Body and and a leg (raycast downward). Use a Kinematic Body, it will give you more controll



Raycasting will fail to detect ground if the character stands above a gap, or when you don't stand directly above the higher platform. It has to be a sweep test or a ghost object.
User avatar
Enhex
Most active user
Most active user
 
Posts: 325
Joined: 31 Dec 2014, 12:23

Next

Return to General Discussion

Who is online

Users browsing this forum: No registered users and 1 guest

cron