Tweaking Character controller [partially solved]

gbisocoli

04-04-2014 00:39:56

Hi, I'm using Character Controller directly copied from 1201.h from NxOgre 1.7 and it works very well except when changing direction on the same axis, this is: if I'm pressing A (left) and I change direction to D (right) BEFORE releasing A then it stops movement, I managed to make it move on 8 directions by removing mCharacterInputHelper.reset(); from keyPressed so when I press a new key maintaining other it moves diagonally, but I can't figure out how to make it move on the other direction I'm going when I don't release the key on time (and this is on milliseconds, when you play you don't always release on time one key before pressing the other, so I can't expect that the player would do it)

this is the code for keyPressed and keyReleased:

bool HumanFieldPlayer::keyPressed(const OIS::KeyEvent &evt)
{
// Reset to zero all movement
// mCharacterInputHelper.reset(); // removed so I can move diagonally

// Forward or backwards
if ( evt.key == OIS::KC_W ) mCharacterInputHelper.forward(127);
else if ( evt.key == OIS::KC_S ) {
mCharacterInputHelper.backward(127);
}
// Left or right
if ( evt.key == OIS::KC_A ) {
mCharacterInputHelper.input.is_turning = false;
mCharacterInputHelper.left(127);
}
else if ( evt.key == OIS::KC_D ) {
mCharacterInputHelper.input.is_turning = false;
mCharacterInputHelper.right(127);
}
// Turning left or right
if ( evt.key == OIS::KC_Q ) {
mCharacterInputHelper.input.is_turning = true;
mCharacterInputHelper.left();
}
else if ( evt.key == OIS::KC_E ) {
mCharacterInputHelper.input.is_turning = true;
mCharacterInputHelper.right();
}
// Jump
if ( evt.key == OIS::KC_SPACE ) {
mCharacterInputHelper.up(true);
}

// Give the input to the character, to make him move in your requested direction.
mCharacter->setInput(mCharacterInputHelper);
return true;
}

//-------------------------------------------------------------------------------------
bool HumanFieldPlayer::keyReleased(const OIS::KeyEvent &evt)
{
if ( evt.key == OIS::KC_W ) mCharacterInputHelper.forward(0);
else if ( evt.key == OIS::KC_S ) mCharacterInputHelper.backward(0);

if ( evt.key == OIS::KC_A ) mCharacterInputHelper.left(0);
else if ( evt.key == OIS::KC_D ) mCharacterInputHelper.right(0);

if ( evt.key == OIS::KC_Q ) {
mCharacterInputHelper.input.is_turning = false;
mCharacterInputHelper.left(0);
}
else if ( evt.key == OIS::KC_E ) {
mCharacterInputHelper.input.is_turning = false;
mCharacterInputHelper.right(0);
}

if ( evt.key == OIS::KC_SPACE ) mCharacterInputHelper.reset();

mCharacter->setInput(mCharacterInputHelper);
return true;
}


Any ideas?

::EDIT::

I added this enum:
enum XAxisDirection { Left, None, Right };
XAxisDirection mXAxisDirection;

(which is self explanatory) and changed the methods keyPressed and keyReleased:

bool HumanFieldPlayer::keyPressed(const OIS::KeyEvent &evt)
{
// Forward or backwards
if ( evt.key == OIS::KC_W ) mCharacterInputHelper.forward(127);
else if ( evt.key == OIS::KC_S ) {
mCharacterInputHelper.backward(127);
}
// Left or right
if ( evt.key == OIS::KC_A ) {
mXAxisDirection = XAxisDirection::Left;
mCharacterInputHelper.input.is_turning = false;
mCharacterInputHelper.right(127); // ??? If I use .left(127) it goes right
}
else if ( evt.key == OIS::KC_D ) {
mXAxisDirection = XAxisDirection::Right;
mCharacterInputHelper.input.is_turning = false;
mCharacterInputHelper.left(127); // ??? same
}
// Turning left or right
if ( evt.key == OIS::KC_Q ) {
mCharacterInputHelper.input.is_turning = true;
mCharacterInputHelper.right(); // ??? same
}
else if ( evt.key == OIS::KC_E ) {
mCharacterInputHelper.input.is_turning = true;
mCharacterInputHelper.left(); // ??? same
}
// Jump
if ( evt.key == OIS::KC_SPACE ) {
mCharacterInputHelper.up(true);
}

mCharacter->setInput(mCharacterInputHelper);
return true;
}

bool HumanFieldPlayer::keyReleased(const OIS::KeyEvent &evt)
{
if ( evt.key == OIS::KC_W ) mCharacterInputHelper.forward(0);
else if ( evt.key == OIS::KC_S ) mCharacterInputHelper.backward(0);

if ( evt.key == OIS::KC_A ) {
if (mXAxisDirection == XAxisDirection::Left) { // I have to check if on keyPressed I pressed A before releasing D or not
mXAxisDirection = XAxisDirection::None;
mCharacterInputHelper.right( 0 ); // ??? same
}
}
else if ( evt.key == OIS::KC_D ) {
if (mXAxisDirection == XAxisDirection::Right) {
mXAxisDirection = XAxisDirection::None;
mCharacterInputHelper.left(0); // ??? same
}
}

if ( evt.key == OIS::KC_Q ) {
mCharacterInputHelper.input.is_turning = false;
mCharacterInputHelper.right(0); // ??? same
}
else if ( evt.key == OIS::KC_E ) {
mCharacterInputHelper.input.is_turning = false;
mCharacterInputHelper.left(0); // ??? same
}

if ( evt.key == OIS::KC_SPACE ) mCharacterInputHelper.up(false);

mCharacter->setInput(mCharacterInputHelper);
return true;
}


And this is working ok the only problem is I have to use .left() to go right and .right() to go left (??) This is not a problem of camera position or something similar, it seems to be a problem on the default implementation of Character Controller, I'm going to do my implementation of it.