
I haven't made a dedicated test application for it, but you can try it out in the game I'm working on: http://www.transmogrifier.de/wo2/files/walkover2_setup.exe
- Code: Select all
Controls
ESC Return to Main Menu
WASD walking
Space jump
Shift run
Tab Switch between construction and weapons mode
F turn on/off free flight
Q & Y fly up/fly down in free flight and swim up/down while swimming
B spawn heavy box
Construction Mode
1 activate Pickaxe to remove Block
2 activate Sculpting Tool to raise and lower Corners
3-9, R & T activate Materials to Place. r & t cycle through them. There are more materials then directly accessible through 3-9.
Weapon Mode
1 activate Minigun
2 activate Shotgun
3 activate Rocketlauncher
It features (sry, I copied some formulations from physique):
+ Instant stair-stepping with no loss of speed.
+ Stand still on sloped ground, with a maximum slope angle.
+ jump
+ slide down illegal ramp
+ Push and be pushed by physics bodies.
+ Movement is fast and responsive!
+ character doesn't get airborne after running up a hill or while running down stairs
It can't crouch yet. I think it's easy portable to newton 3xx, but physique mentioned there is some issue with
the convex cast in newton 3xx right now and since this character controller relies on it, I haven't even tried.
It uses newton 2xx right now.
I release the source code as it is now. It's not a clean drop in for everybody since it needs to handle shapeids in the collision callback
and depending on how you handle those, you have to adjust code manually. I don't know if it's possible to make this easy usable without enforcing
something like this to the user. Also, there is the force and torque callback which basically just sets the force calculated before.
But since you might have a hierarchie of classes you point to with the userdata value of the bodies, I can't set it to the class of
the charactercontroller itself. It has to fit in your hierarchie. You can see it in my code where I cast it to a CUZUnit which is
the logical representation of a character in my code which in turn uses the character controller for movement.
Apart from that, it uses my own MVector class, but this could be substituted with another one.
Current Version:
https://dl.dropbox.com/u/103286/temp/MNewtonCharacterController20120721.7z
Old versions:
https://dl.dropbox.com/u/103286/temp/MNewtonCharacterController20120708.7z
You initialize it like this:
- Code: Select all
mncc = new MNewtonCharacterController();
mncc->SetDefaultParameters();
mncc->materialgroup = windowregionwalkover->ngroupunits;
mncc->userdata = this;
mncc->Init(windowregionwalkover->newtonworld, windowregionwalkover->newtonworld);
SetDefaultParameters() sets some default parameters which you can change. If you change them too much, some other magic numbers inside the code might have to
be changed as well - I'm not sure. But for everything between the size of 1 and 3 meters they should be ok.
The default character has a hight of 1.9m. You can see that from charr which is the height of the character cylinder + hover, which is the
distance the cylinder hovers above the ground.
Note that you can set two different newtonworld. One is the world the physics are calculated and a 2nd where the collisionshapes are created in.
If you only have one newtonworld you can set the same world twice. I generally have one world where I create the collisions so I don't have to
recreate them when I destroy my physics world and create a new physics world. Julio told me to do that some time ago.
At the end you destroy it with
- Code: Select all
mncc->Destroy();
delete mncc;
In between, in your logic update step you do this before calling newtonupdate:
- Code: Select all
mncc->input_dir.Set(inputa.x, inputa.y, inputa.z);
mncc->input_jump = input_jump;
mncc->IteratePreNewtonUpdate();
inputa is a vector specifying the direction in which the character moves. depending on mncc->state you have to give slightly different values here.
for MNewtonCharacterControllerState_Floor, MNewtonCharacterControllerState_Fall, MNewtonCharacterControllerState_IllegalRamp you set
x,y to the direction in xy plane where the character should move to, z to 0. For the normal speed, the length should be 1.
However, you can adjust that and increase or decrease the length to make the character walk faster or slower.
For MNewtonCharacterControllerState_Fly, you have to additionally set the z value if the character should fly up or down. Note that flying is
equivalent to swimming from the perspective of this character controller. If you don't do either in your game, you can ignore this.
input_jump specifies if the character jumps right now.
After NewtonUpdate, you call
- Code: Select all
mncc->IteratePostNewtonUpdate()
Right now this only gets the position and velocity from the body and sets it accordingly to mncc->p and mncc->v so you can use it in your visualization and game logic.
I think there are some minor optimizations possible. For example: right now I use two cylinders. One for the feet and one for the upper part of the body.
I do it this way to differntiate if you collide with something small and push it or if I don't and can move over it so I can
hover over it in the next iteration and effectifly went up a stair. That's also why it needs a collisioncallback to differentiate
between these two cases. I'm not sure if this is the efficient way because it needs two cylinders and a compound. I could probably
replace it with only one cylinder and checking the height of the contacts in the collisioncallback.