About Store Forum Documentation Contact



Post Reply 
player object on kinematic elevator
Author Message
yvanvds Offline
Member

Post: #1
player object on kinematic elevator
Hi again.

I thought this would have been asked before, but i can't find anything about this.

I've made a simple platform, added it as a kinematic object, and made a route for it that moves it in a vertical direction (Just a waypoint system with a low and high position in ping-pong mode). Up and down, like an elevator.

Now there are two issues with this. The first is that most of the time, when my player is standing on top of the platform, he doesn't get "picked up" when the platform starts going up. It can't be a problem with the physx mesh because sometimes it does work and my character stays on the platform while it is moving up.

Another issue is when the platform is going down again. The player's gravity seems to catch up a bit too slowly. So he's constantly bouncing down bit by bit. I could alter the player mass perhaps, but that would also have an impact on movement in the rest of the world.

Am I thinking the wrong way about this? If anyone has successfully implemented an elevator system, I'd like to know how it should be done.

This is the code i used for now (overriding Kinematic create & update)

PHP Code:
void cKinematic::create(Game::ObjParams &obj) {
  
__super::create(obj);

  if (
Param obj.findParam("type")) {
    
type p->asText();
    if (
Equal(type"elevator")) {
      
elevator true;
      
Vec p this->pos();
      if (
Param obj.findParam("lowpos")) {
        
lowPos p->asFlt();
      }
      if (
Param obj.findParam("highpos")) {
        
highPos p->asFlt();
      }
      
p.lowPos;
      
route.New(p);
      
p.highPos;
      
route.New(p);
      
route.loop_mode Game::Waypoint::PING_PONG;
      
currentPos 0.0;

      
// adjust low and high pos for position checking now
      
lowPos += 0.1;
      
highPos -= 0.1;
      
halt false;
      
lastHaltWasUp false;
    }
  }
}

bool cKinematic::update() {
  
Bool r __super::update();
  if (
elevator) {
    if (!
halt) {
      
currentPos += 0.05;
      if (
currentPos route.length()) {
        
currentPos -= route.length();
      }
      
Vec p route.pos(currentPos);
      
this->pos(p);
      if ((
p.lowPos)&&(lastHaltWasUp)) {
        
halt true;
        
haltTime 5.0;
        
lastHaltWasUp false;
      }
      if ((
p.highPos)&&(!lastHaltWasUp)) {
        
halt true;
        
haltTime 5.0;
        
lastHaltWasUp true;
      }
    } else {
      if (
haltTime 0) {
        
haltTime -= Time.d();
      } else {
        
halt false;
      }
    }
  }
  return 
r;

12-19-2010 09:21 PM
Find all posts by this user Quote this message in a reply
yvanvds Offline
Member

Post: #2
RE: player object on kinematic elevator
Ok, got the first part right now. I forgot about KinematicMoveTo. So this works:

PHP Code:
Vec p route.pos(currentPos);
this->kinematicMoveTo(p); 

But the second problem is even more visible now: it also occurs when going up. The player object is bouncing on platform all the time.
12-19-2010 10:52 PM
Find all posts by this user Quote this message in a reply
Esenthel Offline
Administrator

Post: #3
RE: player object on kinematic elevator
How are you initializing Physics.create? do you set any CSS_* ?

Does the bouncing occur when you move around the player, or also when you don't move him?
12-20-2010 12:44 AM
Find all posts by this user Quote this message in a reply
yvanvds Offline
Member

Post: #4
RE: player object on kinematic elevator
Yes, physics are initialized. I don't know what CSS are though.

Edit: Seems i misread your first question. Physics are initialized this way:
Physics.create(CSS_FREEZE_XZ);
Physics.gravity(Vec(0,-5,0));

I've uploaded a small movie that shows the behaviour: http://www.sendspace.com/file/h4t8q4

It looks like the platform itself is shaking here, but that's because the camera follows the player. The bouncing happens if I move around the player on the platform too.

I don't think there's something wrong here. I probably have to adjust some physics setting on the character while i'm on the platform, but i don't know which one.
(This post was last modified: 12-20-2010 03:28 PM by yvanvds.)
12-20-2010 03:23 PM
Find all posts by this user Quote this message in a reply
Esenthel Offline
Administrator

Post: #5
RE: player object on kinematic elevator
Out of curiosity I tried testing this, but it works smooth:

Code:
/******************************************************************************/
#include "stdafx.h"
#include "../data/Enum/_enums.h"
/******************************************************************************/
struct Player : Game::Chr
{
   virtual Bool update();
};
struct Platform : Game::Kinematic
{
   virtual Bool update()
   {
      if(Kb.b(KB_Q))kinematicMoveTo(actor.pos()+Vec(0,3,0)*Time.d());
      if(Kb.b(KB_E))kinematicMoveTo(actor.pos()-Vec(0,3,0)*Time.d());
      return __super::update();
   }
};
/******************************************************************************/
Game::ObjMemx<Game::Static> Statics  ;
Game::ObjMemx<Platform    > Platforms;
Game::ObjMemx<Game::Item  > Items    ;
Game::ObjMemx<      Player> Players  ;
/******************************************************************************/
Bool Player::update()
{
   // turn & move
   //input.anglei.x=Kb.b(KB_Q)-Kb.b(KB_E);
   input.anglei.y=Kb.b(KB_T)-Kb.b(KB_G);
   input.diri  .x=Kb.b(KB_D)-Kb.b(KB_A);
   input.diri  .z=Kb.b(KB_W)-Kb.b(KB_S);
   input.diri  .y=Kb.b(KB_SPACE)-Kb.b(KB_LSHIFT);

   // dodge, crouch, walk, jump
   input.dodge = Kb.bd(KB_D)-Kb.bd(KB_A);
   input.crouch= Kb.b (KB_LSHIFT);
   input.walk  = Kb.b (KB_LCTRL );
   input.jump  =(Kb.bp(KB_SPACE ) ? 3.5 : 0);

   // mouse turn
   if(!Ms.b(1))
   {
      Flt  max=DegToRad(900)*Time.d(),
           dx =Ms.dir_ds.x*1.7,
           dy =Ms.dir_ds.y*1.7*Ms.inv();
      angle.x-=Mid(dx,-max,max);
      angle.y+=Mid(dy,-max,max);
   }

   // ready stance change
   ctrl.flying(ctrl.flying()^Kb.bp(KB_F));

   return __super::update();
}
/******************************************************************************/
void InitPre()
{
   App.name("Game");
   App.flag=APP_FULL_TOGGLE;
   Cam.dist=3;
   //D.sync(true);
}
/******************************************************************************/
Bool Init()
{
   Physics.create(CSS_NONE,true,"../Installation/PhysX");
  //Physics.timestep(PHYS_TIMESTEP_VARIABLE);
   Sky    .atmospheric();
   Sun.image=Images("gfx/sky/sun.gfx");

   Clouds.layered.set(3,Images("clouds/layers/0.gfx"));

   // create the world
   Game::World.init()
              .setObjType(Statics  ,OBJ_STATIC   )
              .setObjType(Platforms,OBJ_KINEMATIC)
              .setObjType(Players  ,OBJ_PLAYER   )
              .setObjType(Items    ,OBJ_ITEM     )
              .New("world/platform.world");

   return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Update()
{
   if(Kb.bp(KB_ESC))return false;
   if(Kb.bp(KB_F2 ))Game::World.save("LocalData/save 0.sav");
   if(Kb.bp(KB_F3 ))Game::World.load("LocalData/save 0.sav");
   Game::World.update(Cam.at);
   Clouds.layered.update();

   // setup the camera
   if(Players.elms())
   {
      Cam.dist=Max(1.0f,Cam.dist*ScaleFactor(Ms.wheel()*-0.2));
      Cam.setSpherical(Players[0].pos(), Players[0].angle.x, Players[0].angle.y, 0, Cam.dist);
      Cam.updateVelocities().set();
   }
   else
   {
      CamHandle(0.1f,100,CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT));
   }

   return true;
}
/******************************************************************************/
void Render()
{
   Game::World.draw();
}
void Draw()
{
   Renderer(Render);
   if(Kb.b(KB_CAPS))Physics.draw();
   D.text(0,0.9,S+Time.fps());
}
/******************************************************************************/


Attached File(s)
.rar  platform.rar (Size: 725 bytes / Downloads: 8)
12-22-2010 05:50 PM
Find all posts by this user Quote this message in a reply
yvanvds Offline
Member

Post: #6
RE: player object on kinematic elevator
Sorry for the delay, I was making a new gameworld after a certain unfortunate event last week lol

I checked out your example, and it works ok. But! Almost nothing happens in that example. I tried to make it more like full blown world by adding a few hundred trees with lights between them. I also doubled the platform speed:

if(Kb.b(KB_Q))kinematicMoveTo(actor.pos()+Vec(0,6,0)*Time.d());
if(Kb.b(KB_E))kinematicMoveTo(actor.pos()-Vec(0,6,0)*Time.d());

Now the 'effect' is also happening your code. It might depend on how good your graphics card is, but i think you'll see it when you add enough trees and lights. (In my case, framerate was 500 at first, and 35 after adding the trees and lights, about the same framerate as in my game.)
12-27-2010 10:02 PM
Find all posts by this user Quote this message in a reply
Esenthel Offline
Administrator

Post: #7
RE: player object on kinematic elevator
Hi,

You can experiment with Physics.precision and timestep
12-28-2010 03:48 PM
Find all posts by this user Quote this message in a reply
yvanvds Offline
Member

Post: #8
RE: player object on kinematic elevator
Ok, with PHYS_TIMESTEP_ROUND it helps to set Physics.precision() below the actual framerate, but that makes me fall through the terrain when I jump, about one time out of three. I'll also don't know yet what the effect will on other game objects, but falling through the terrain is not really a workable option.

PHYS_TIMESTEP_VARIABLE doesn't really help, the bouncing is the same at every precision when I use it.
12-28-2010 09:24 PM
Find all posts by this user Quote this message in a reply
Esenthel Offline
Administrator

Post: #9
RE: player object on kinematic elevator
'precision' can be increased
also you can use Actor::ccd which should disable falling through objects
12-28-2010 09:26 PM
Find all posts by this user Quote this message in a reply
yvanvds Offline
Member

Post: #10
RE: player object on kinematic elevator
What exactly do you mean with 'precision can be increased'?

Is it a good idea to adjust the precision to the current framerate, or is it better not to touch it during the update cycle?
12-28-2010 10:37 PM
Find all posts by this user Quote this message in a reply
Esenthel Offline
Administrator

Post: #11
RE: player object on kinematic elevator
set it only once, like 'precision(120)' for example
12-29-2010 01:36 AM
Find all posts by this user Quote this message in a reply
yvanvds Offline
Member

Post: #12
RE: player object on kinematic elevator
That didn't help, but ok, I found a workaround. To wrap it up: the bumping on the platform happens when the framerate is less than twice the physics precision. Just lowering the physics precision is not an option because it makes object movement in general less smooth than it schould be.

The code below takes care of that, albeit in a bit of a crude way:

In the player update function (AG_ELEVATOR is a custom actor group):

PHP Code:
Vec dir;
dir.zero();
dir.= -1;
ball.set(0.2pos());
if(
Physics.sweep(ball,dir,&phys_hitIndexToFlag(AG_ELEVATOR))) {
  
onPlatform true;
} else {
  
onPlatform false;


And during game update:
PHP Code:
if (Players.elms()) {
  if ( (
Players[0].onPlatform) && (Time.fps() < 120) ) {
    
Physics.precision(Time.fps() / 1);
  } else if (
Physics.precision() != 60) {
    
Physics.precision(60);
  }

12-29-2010 11:13 AM
Find all posts by this user Quote this message in a reply
Post Reply