Player controlled character I can set the velocity of?

Post Reply
DrenDran
Posts: 6
Joined: Thu Aug 31, 2017 10:08 pm

Player controlled character I can set the velocity of?

Post by DrenDran » Sat Oct 07, 2017 5:50 pm

So I stopped using kinematic character controller a while ago because it wasn't really what I wanted.
So now I have my own character controller that works alright. It's just a dynamic body with a cube collision shape with angular factor set to 0, high friction, and functions written to handle stepping up onto things and jumping.
That said, I'm having the character move by setting it's linear velocity. That works well, but I also want to be able to set the characters velocity on top of that. I've tried a few things already, but I was wondering if anyone else had good ideas.

avithohol
Posts: 18
Joined: Sun Feb 12, 2017 10:22 am

Re: Player controlled character I can set the velocity of?

Post by avithohol » Sun Oct 08, 2017 9:34 am

DrenDran wrote:So I stopped using kinematic character controller a while ago because it wasn't really what I wanted.
So now I have my own character controller that works alright. It's just a dynamic body with a cube collision shape with angular factor set to 0, high friction, and functions written to handle stepping up onto things and jumping.
That said, I'm having the character move by setting it's linear velocity. That works well, but I also want to be able to set the characters velocity on top of that. I've tried a few things already, but I was wondering if anyone else had good ideas.
I experiment with the same:

Why not use capsule for better step-up on small bumps?

I apply central impulse on the body in my "frame tick", then i setup a "on physics tick" callback, and limit the character velocity in there, exactly like written here in the last example:
http://www.bulletphysics.org/mediawiki- ... e_Snippets

This way the character will not speed up too much.

As the example say it's a good frame independent solution, but still confusing if apply forces should happen in "pre-physics-tick" callback function, our outside in the "frame-tick" function.

DrenDran
Posts: 6
Joined: Thu Aug 31, 2017 10:08 pm

Re: Player controlled character I can set the velocity of?

Post by DrenDran » Sun Oct 08, 2017 7:26 pm

But capping the velocity of the character isn't what I have in mind.
I want to cap the velocity of the control-initiated velocity, sure. But velocities set via a script should be unlimited and separate.

User avatar
drleviathan
Posts: 372
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Player controlled character I can set the velocity of?

Post by drleviathan » Mon Oct 09, 2017 4:32 pm

I think maybe I know how to do what you want but I'm not sure I really understand your description. It isn't clear to me which of these scenarios you want:

(1) Set a base velocity on the character but allow an additive second velocity on top of that. In this scenario: if both velocities were in the same direction at 1m/s then the character would move in that direction at 2m/s, and were they to oppose each other the character would move at 0m/s.

This isn't too hard. You would store each velocity contribution as data members of your CharacterController and sum them together in its applyAction() implementation and slam the velocity only once.

(2) Blend two independent velocities together in an attempt to satisfy, but not exceed, both. In this scenario: if both velocities were in the same direction at 1m/s then the character would move at 1m/s since both "intentions" are satisfied, but if they to oppose each other the character would move at 0m/s.

This is trickier but I've done it using "weighted averages". If you need an outline of this method let me know.

DrenDran
Posts: 6
Joined: Thu Aug 31, 2017 10:08 pm

Re: Player controlled character I can set the velocity of?

Post by DrenDran » Thu Oct 12, 2017 11:31 pm

drleviathan wrote:I think maybe I know how to do what you want but I'm not sure I really understand your description. It isn't clear to me which of these scenarios you want:

(1) Set a base velocity on the character but allow an additive second velocity on top of that. In this scenario: if both velocities were in the same direction at 1m/s then the character would move in that direction at 2m/s, and were they to oppose each other the character would move at 0m/s.

This isn't too hard. You would store each velocity contribution as data members of your CharacterController and sum them together in its applyAction() implementation and slam the velocity only once.

(2) Blend two independent velocities together in an attempt to satisfy, but not exceed, both. In this scenario: if both velocities were in the same direction at 1m/s then the character would move at 1m/s since both "intentions" are satisfied, but if they to oppose each other the character would move at 0m/s.

This is trickier but I've done it using "weighted averages". If you need an outline of this method let me know.
That's not the issue.
The issue is that character movement is done setting the velocity *every tick*. So every single frame the velocity is set to x = sin(yaw) z = cos(yaw). As soon as the player stops pressing the WSAD keys, the x and z velocity go right back to 0 and the character stops 'walking.' This means if I set the velocity to something else it will have no effect whatsoever, as it's instantly overwritten, so to speak. Trying to make character movement "add" velocity instead of just set it results in the characters acting like they're on ice, and sliding all over. This in turn can't be fixed just by giving the characters friction or linear dampening, as that just makes them seem like they're on very slow ice.

User avatar
drleviathan
Posts: 372
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Player controlled character I can set the velocity of?

Post by drleviathan » Fri Oct 13, 2017 4:14 pm

It is possible to add the character's target velocity to its current velocity without the character feeling too unresponsive or slippery on ice, however it requires some tuning and also a bit of state management.

When it comes to blending speeds I usually do it like this (in pseudo code):

Code: Select all

blend = timeStep / BLEND_TIMESCALE;
if (blend > 1.0) {
    // this clamp for stability
    blend = 1.0;
}
velocity = (1.0 - blend) * velocity + blend * targetVelocity;
The trick is to pick the right BLEND_TIMESCALE. If you want the character to be responsive then use a short timescale. If you want the character to be slow to respond then use a longer timescale. That said, you can't chose an arbitrarily short timescale. The shortest timescale that makes sense would be about 2X the timeStep. If your game is running at 30Hz then the shortest timescale you should use is 1/15th of a second. Since this method will get very close to targetVelocity within three timescales it is pretty easy to tune, and it is probably ok for game feel if your character ramps up to speed in 3 * 1/15 = 1/5 of a second.

The blending can be used to stop the character too. Just set targetVelocity to zero and give it the right timescale and the math will work: your character will come to a screeching halt. However, if you continue to blend toward zero velocity after the character has achieved rest then your character will be stuck fast and collisions will not budge it.

What you can do is use a dynamic timescale. Use a short timescale when character is walking and a similarly short timescale when character is braking to a stop. Then once the character is at rest you either stop blending altogether or use a very long timescale (several seconds) --> bumps and pushes will be able to move the character (modulo friction) until you bring the timescale back down at which point the character's intended movement will assert itself.

DrenDran
Posts: 6
Joined: Thu Aug 31, 2017 10:08 pm

Re: Player controlled character I can set the velocity of?

Post by DrenDran » Sun Oct 15, 2017 12:42 am

[quote="drleviathan"][/quote]
Honestly that seems like a pretty good idea. I've implemented it and it'll probably take a lot of tweaking to get right, but it works okay.

Post Reply