Jump to content
  • Advertisement
Sign in to follow this  

[PhysX] Move controller + getting its velocity

This topic is 2060 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to use a PxController for my player character, but I'm having a bit of trouble.

This is how I'm creating the controller:

local mat = physx.CreateMaterial(0.5,0.5,0.1)
local controller = physx.CreateCapsuleController({
	height = 64,
	radius = 18,
	material = mat,
	contactOffset = 0.01
local actor = controller:GetActor()

The code snippets are in lua, but all these functions do internally is call the equivalent physx-functions.

After the controller has been created, it's being moved every time the world is simulated:

local dir = Vector(math.sin(CurTime()),0,math.cos(CurTime())) -- Move the controller in a circle; CurTime() is the time that has passed since the program start
dir = dir *10
local disp = dir *DeltaTime() -- DeltaTime() = time since last world simulation
local vel = actor:GetLinearVelocity()
local speed = vel:Length()
print(math.abs(speed -dir:Length())) -- Should be 0, but fluctuates quite a bit

The actual movement works as intended. If I compare the new position, after the whole PxScene was simulated, to the old position (before the "Move"-Call), the difference is exactly the displacement vector.

The velocity, however, is behaving strangely. The way I see it, getLinearVelocity should return the same as the displacement vector, but there's a small, random, deviation, but it's too large to be a precision error of some sort. What am I missing?


One more thing:

I can move the controller in any direction, even upwards from the ground. How would I actually restrict the movement so the controller actually sticks to the ground? And what exactly is the point of the 'setUpDirection'-function for PxControllers if it doesn't already do that?

Share this post

Link to post
Share on other sites

You can't rely on the actor's velocity in this case... The character controller framework does so much more under the hood. You should track the velocity manually. Using that "dir" in your code should be perfectly fine (e: unless the controller touches something - you have to check for these conditions).


One way to handle the gravity is to manually apply the acceleration. The cc framework provides the raycast result flags. If the bottom of the cc touches ground (or something else), just reset the velocity's z-component or modify it according to conservation laws. The up direction is used to do these raycasts and to determine the orientation of the cc shape.

Edited by fanwars

Share this post

Link to post
Share on other sites

Thanks for the response, it's hard to get help with anything PhysX related.


Anyway, I'm unsure how I'm supposed to track the velocity myself accurately. As you've said, as long as there's no collisions it would probably be fine, but if there is a collision that's a whole different story.

The flags I get from the 'Move'-Call only tell me whether there was a collision above / below / to one of the sides of the controller, I need more information about the collision than that. And even then I'd have to know exactly how physx does the collision response (e.g. sliding against a wall) to calculate the new exact velocity.


Also, if the difference between the new position and the old position is exactly my displacement vector, how is it possible that getLinearVelocity returns something else? I mean, even if the controller framework does some additional calculations, the velocity should be exactly the vector by which it has moved, should it not?

Share this post

Link to post
Share on other sites

Internally the controller framework uses setKinematicTarget() so one can only guess what PhysX does beyond that point. I don't know if it's even valid to use getLinearVelocity with kinematic actors...


However, since the displacement is accurate, why not use it to calculate the velocity yourself? Just keep the previous and current position between updates and divide the displacement with your timestep.

Share this post

Link to post
Share on other sites

It just seems to me more like a workaround than an actual solution, but I guess it will do, thanks. The only problem I see is that I can't differentiate whether the actor has been forcibly teleported to a specific position, or moved there regularly, but I guess I'll have to live with that. Thanks again!

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!