I just thought I'd post up my findings, just to hopefully help a few other people who might be a bit confused. I found the character controller a little bit weird to start with, but I think it all makes sense now. I'm implementing it into my game as we speak and after some initial confusion, it's working great.
What first got me is there is only one movement command - essentially move forwards. So what about staffing/side stepping? Or what about jumping, or what if your character has a jetpack?
I've used the following method for my character. Hopefully Mike or someone else will suggest a demo to look at etc. if there is a better solution, but this works for me.
I found the best way to approach the character controller and give yourself plenty of freedom is using vectors to store the speed of your character. So model its speed using X,Y,Z speed vectors and store the angle the character is facing. Here's how I am modelling my X,Z speeds (I've missed out yspd to keep it a bit simpler for now):
`xspd# and zspd# are my players speeds on the x and z axis
`ang# is the angle my player is MOVING (not facing)
`accel# is the speed at which my player accelerates
`friction# is a number such as 0.9 which ensures a top speed and deceleration
xspd# = (xspd# + sin(ang#)*accel#) * friction#
zspd# = (zspd# + cos(ang#)*accel#) * friction#
As you have to tell the character controller the actual speed of your character (rather than force) you must model acceleration and friction yourself. This is a nice simple way of doing it.
ang# is the direction the player is
MOVING so if you're straffing left, ang# should be
object angle y(playerObject) - 90, for example. If you're staffing right, it should be
object angle y(playerObject) + 90
You can also modify accel# and make it smaller when straffing and running backwards, meaning the player moves faster forwards than in other directions.
Now to actually get your character to move about you would do the following. Firstly, you need to know how fast you're going to move your character. This is simply retrieved from the xspd# and zspd# variables you calculated above. I used vectors as they're a bit faster than pythag:
`Vector 1 was previously created
set vector3 1,xspd#,0,zspd#
totalspeed# = length vector3(1)
Now your rotate your character to the direction you want it to move in. This is also derived from the xspd# and zspd# values:
moveAngle# = atanfull(xspd#,zspd#)
yrotate object playerObject, moveAngle#
Now you move your character using the physics command:
phy move character controller playerObject,totalSpeed#
Then you return it to the angle it should be facing:
yrotate object playerObject,faceAngle#
My whole process for an 8 directional movement system (staffing, running etc. using the chracter controller) looks a bit like this:
`WORK OUT THE DIRECTION PLAYER IS PRESSING WITH DIRECTION KEYS
direc = 0
`FORWARDS
if upkey()
direc = 1
else
`BACKWARDS
if downkey()
direc = 2
endif
endif
`LEFT
if leftkey()
direc = direc + 4
else
`RIGHT
if rightkey()
direc = direc + 8
endif
endif
`*************************************
`********* SIMPLE MOVEMENT ***********
`*************************************
`DIRECTION OF FACING TURNED WITH THE MOUSE
facingAngle# = wrapvalue(facingAngle#+mousemovex())
`WORK OUT DIRECTION OF MOVEMENT
select direc
case 1
`--RUNNING FORWARD--
ang# = facingAngle#
accel# = 10
endcase
case 2
`--RUNNING BACKWARD--
ang# = facingAngle# + 180
accel# = 5
endcase
case 4
`--STEP LEFT--
ang# = facingAngle# - 90
accel# = 5
endcase
case 8
`--STEP RIGHT--
ang# = facingAngle# + 90
accel# = 5
endcase
case 5
`--FORWARD LEFT--
ang# = facingAngle# - 45
accel# = 8
endcase
case 9
`--FORWARD RIGHT--
ang# = facingAngle# + 45
accel# = 8
endcase
case 6
`--BACKWARD LEFT--
ang# = facingAngle# - 135
accel# = 5
endcase
case 10
`--BACKWARD RIGHT--
ang# = facingAngle# + 135
accel# = 5
endcase
case default
`--NO MOVEMENT--
ang# = 0
accel# = 0
endcase
endselect
`Now we have the direction the character is moving, we can add
`some speed in that direction, and model friction at the same time
xspd# = (xspd# + sin(ang#)*accel#) * friction#
zspd# = (zspd# + cos(ang#)*accel#) * friction#
`Now we can work out the total speed of the character for use
`with the phy move character controller commands
set vector3 1,xspd#,0,zspd#
totalSpeed# = length vector3(1)
`And we can work out the angle this movement is in
moveAngle# = atanfull(xspd#,zspd#)
`Now we do the physics bit and move the character
yrotate object playerObject,moveAngle#
phy move character controller playerObject,totalSpeed#
`Now we return the character to face in the correct direction
yrotate object playerObject,facingAngle#
You'll need to tweak that a bit but hopefully that'll help a few people out. I think you can think of the character controller like an object in DB, but with only the MOVE OBJECT command available to do anything with it.
Btw, I used this process to setup my character controller in the first place:
phy make capsule character controller playerObject,x#,y#,z#,object size x(playerObject,1)/2.0,object size y(playerObject)*0.8,1,10,45
Make sure the centre of your character object is not its feet. If it is, the capsule will be centred on this spot and half of the capsule area will be below your character, making it levitate. If the object centre spot is at its feet use this:
offset limb playerObject,0,0,object size y(playerObject)/-2.0,0
That should help it stand on the ground.
Hope that helps a few people. It's not that complicated, but just requires you to go back to basics a bit.