1. I'm using Version, 2.28.0 currently.
2. Windows, 64 bit, happens on both 7 and 8, I've got two PCs that produces the same results.
3. MappedInput is registered here:
auto mappedInput = script.RegisterReferenceType("MappedInput", script::REF_NOCOUNT);
mappedInput.RegisterMethod("bool HasAction(uint) const", asMETHOD(MappedInput, HasAction));
mappedInput.RegisterMethod("bool HasState(uint) const", asMETHOD(MappedInput, HasState));
mappedInput.RegisterMethod("bool HasRange(uint, float& out) const", asMETHOD(MappedInput, HasRange));
mappedInput.RegisterMethod("bool HasValue(uint, float& out) const", asMETHOD(MappedInput, HasValue));
I'm using a custom light wrapper, I hope you still see how the registration is eventually happening.
4. They are part of the class, as I mentioned in one of the final paragraphs. Just in case, here is the full script:
enum InputState
{
PLAYER_MOVE_FORWARD,
PLAYER_MOVE_BACKWARD,
PLAYER_MOVE_LEFT,
PLAYER_MOVE_RIGHT
};
enum InputRanges
{
PLAYER_ZOOM,
PLAYER_LOOK_X,
PLAYER_LOOK_Y,
};
const float ZOOM_SPEED = 2.5f;
const float MIN_ZOOM = 6.0f;
const float MAX_ZOOM = 30.0f;
// the larger, the less zoom with each wheel turn
const float ZOOM_FACTOR = 75.0f;
const float LOOK_SPEED = 0.1f;
const float CAP_Y_ANGLE = 66.0f;
const float MOVE_SPEED = 20.0f;
class PlayerController : IGameScript
{
PlayerController(const Entity& in ent)
{
entity = ent;
currentZoom = 5.0f;
toZoom = 0.0f;
angleX = 0.0f;
angleY = 0.0f;
toLookX = 0.0f;
toLookY = 0.0f;
moveStraight = 0.0f;
moveSide = 0.0f;
}
void OnUpdate(double dt)
{
Body@ body = GetBody(entity);
UpdateCameraValues(dt);
// lock camera to entity
Position@ position = GetPosition(entity);
const Vector3 vLookAt = position.GetVec() + Vector3(0.0f, pivot, 0.0f);
Cam@ camera = GetCamera(entity);
camera.camera.SetLookAt(vLookAt);
// calculate camera position offset
Vector3 vLook = Vector3(1.0f, 0.0f, 0.0f);
// horizontal rotation
const Matrix mLookX = MatRotationY(degToRad(angleX));
vLook = mLookX.TransformNormal(vLook);
vLook.Normalize();
// vertical rotation
const Vector3 vUp = Vector3(0.0f, 1.0f, 0.0f);
const Vector3 vRight = vUp.Cross(vLook).normal();
const Matrix mLookY = MatRotationAxis(vRight, degToRad(angleY));
vLook = mLookY.TransformNormal(vLook);
vLook.Normalize();
camera.camera.SetPosition(vLookAt + vLook * currentZoom);
// TODO: optimize this, only set when camera really changed, includes caching of body position
camera.dirty = true;
// apply look to entity
Direction@ dir = GetDirection(entity);
const Vector3 vLookXZ = Vector3(vLook.x, 0.0f, vLook.z).normal();
// TODO: this is a hackfix to fix this one model, undo at times
dir.SetVec(Vector3(vLookXZ.z, 0.0f, -vLookXZ.x));
body.body.StopMovement();
if(moveStraight != 0.0f || moveSide != 0.0f)
{
const Vector3 vMoveRight = vUp.Cross(vLookXZ);
body.body.SetLinearVelocity(-vLookXZ * moveStraight + vMoveRight * moveSide);
moveStraight = 0.0f;
moveSide = 0.0f;
}
}
bool UpdateCameraValues(double dt)
{
bool hasChanged = false;
// update zoom
if(toZoom != 0.0f)
{
const float zoomNow = toZoom * dt * ZOOM_SPEED;
toZoom -= zoomNow;
if((zoomNow > 0.0f && toZoom < 0.0f) ||
(zoomNow < 0.0f && toZoom > 0.0f))
toZoom = 0.0f;
currentZoom += zoomNow;
// cap zoom at min/max distance
if(currentZoom >= MAX_ZOOM)
{
currentZoom = MAX_ZOOM;
toZoom = 0.0f;
}
else if(currentZoom <= MIN_ZOOM)
{
currentZoom = MIN_ZOOM;
toZoom = 0.0f;
}
hasChanged = true;
}
// update look on x-axis
if(toLookX != 0.0f)
{
const float lookNow = toLookX * LOOK_SPEED;
toLookX = 0.0f;
angleX -= lookNow;
if(angleX >= 360.0f)
angleX -= 360.0f;
else if(angleX <= 0.0f)
angleX += 360.0f;
hasChanged = true;
}
// update look on x-axis
if(toLookY != 0.0f)
{
const float lookNow = toLookY * LOOK_SPEED;
toLookY = 0.0f;
angleY -= lookNow;
if(angleY >= CAP_Y_ANGLE)
angleY = CAP_Y_ANGLE;
else if(angleY <= -CAP_Y_ANGLE)
angleY = -CAP_Y_ANGLE;
hasChanged = true;
}
return hasChanged;
}
void OnProcessInput(const MappedInput@ input)
{
// movement
if(input.HasState(PLAYER_MOVE_FORWARD))
moveStraight += MOVE_SPEED;
if(input.HasState(PLAYER_MOVE_BACKWARD))
moveStraight -= MOVE_SPEED;
if(input.HasState(PLAYER_MOVE_LEFT))
moveSide += MOVE_SPEED;
if(input.HasState(PLAYER_MOVE_RIGHT))
moveSide -= MOVE_SPEED;
// zoom
float zoom = 0.0f;
if(input.HasRange(PLAYER_ZOOM, zoom))
toZoom += zoom / ZOOM_FACTOR;
// camera rotation
input.HasRange(PLAYER_LOOK_Y, toLookY);
input.HasRange(PLAYER_LOOK_X, toLookX);
}
Entity entity;
float pivot;
private float moveStraight, moveSide;
private float currentZoom, toZoom;
private float angleX, angleY, toLookX, toLookY;
}
Hope this helps.