Simple yet important python script problem

Greetings fellas. I come to you once again for assistance.
Early in my learning curve I came with a seemingly simple problem, and yet the results are not good!

Problem:
The player needs to use a moving platform and be able to move with it (moving platforms, elevators, moving vehicles).

Solutions:

Normally, the base position for the avatar is it’s world position. So I though of getting the relative position and add it to the object’s position, so I end up with something like that:


import bge
cont= bge.logic.getCurrentController()
obj= bge.logic.getCurrentScene().objects

player= obj['player']
base= obj['base']
relpos=base.position - player.position
player.position= base.position+relpos
relori= base.orientation-player.orientation
player.orientation= player.orientation+relori

The problem is that the relative position is calculated before the position is set therefore, the avatar wont be able to move.
Besides, a simplistic script like this wont cut it!
Maybe I need to add movement instead…
Right now I use parenting, and could also use reference in the servo motion actuator. But I still want to know if anyone has any idea on how to get this to work?

You can simply increase the friction of the ground.

If you stay on an ice block you would slip off it too, don’t you ;)?

Attachments

PlatformDemo.blend (69.4 KB)

Wouldn’t it be managable as well by just parentin’ the Player to the Platform?
(I haven’t tried it out by now, but the Thought always comes into my Head on that Topic.)

If You use a motion actuator with servo control You can set a reference object - I’m not sure but I assume You can change that reference object in python.

A collision sensor on the player looking for property platform - When sensor goes active, set the hit object (the platform) as reference object - when the sensor goes inactive - unset it (or make the ground a platform to and Just let that override it).

If the base is set to be the parent of the player, then relative movements of the player are obtained with .localOrientation and .localPosition, i.e.:


# to move the platform <b>and the player with it</b>, use:
base.worldPosition = [x, y, z]

# to rotate the platform <b>and the player with it</b>, use:
base.worldOrientation = [phi, tet, psi] # angles must be in radians

#to move the player <b><i>with respect to the platform</i></b> use:
player.localPosition = [x, y, z]

# to rotate the player <b><i>with respect to the platform</i></b>:
player.localOrientation = [phi, tet, psi] # angles must be in radians

# to convert angles from degrees to radians use:
from math import radians
angle_in_radians = radians(angle_in_degrees)

Finally this depends if you use physics or not.

Without Physics:

  • you can use parenting
  • you move by setting a new position

With physics:

  • you can not use parenting as it would immediately stop your motion
  • you should not set positions as this is teleporting not motion
  • you move by applying forces or velocities

Exception:

  • the character enters a vehicle => remove the character, replace it with a dummy in the car, activate the car’s controls

Thanks guys!
@ Monster: In fact friction works very nicely! I’ll use that for platforms! Now I’ll need another option for fast moving/rotating objects, like ships. I think that multiplying the avatar’s position by the rotation angle. I’ll test it more extensively.

@C.A.ligàri: Currently this is how I handle it, but there’s the problem of freely moving on the platform.

@ LaH: Hmm, yes that is possible, but has the same problem as the parenting.

@mb10: I see your point, but I don’t see how to change the positions. Besides, in 2.6 there’s no distinction between local and worldPositions… or there is? I thought there was a bug there…

Yes, I know of that, and indeed, it’s only applicable when an object has a parent, sorry for my stupidity! I still have the problem of moving the object I can’t just apply velocity or force to it if it’s parented it wont move. And of the object is not dynamic, then the avatar would go through the ship’s haul, into oblivion… But that’s the simplest way to do it, I got to admit.
I tried once to copy velocity, that seems to work, but not very well, since there’s a delay in the calculation, causing the avatar to fall behind, and it still wouldn’t move.
It would be nice if there’s an offset, that reduces with the distance to the floor or object. Now I think that a general gravity script is required.

Is that for your space ship game?

Well, yes!
One of the “greatest feature” is the ability to walk inside a moving vehicle. I’d normally parent the object to the ship and set it as static and find a way to limit the movement to empty spaces. The thing is that the ships go at extremely high speeds (very blender scenes per second [n*(200 000) BU] and certain methods don’t work. So far parenting was the safest way!

I was working on such a system because you inspired me.

My solution is quite simple, but complex to implement:

  • the inside of a ship/space station is in one scene
  • the outside in another

With that it does not matter how fast the ship is travelling, or the space station is orbiting.
You can look at seemless transition.

As you remember we were discussing a similar solution for travelling from space sector to space sector. This approach fits perfectly into such concept.

Unfortunately my framework runs in 2.49 only. This is due to the incompatibilities of Mathutils and mathutils.
[edit: removed fragment]

OK, that would add another physics enabled scene. Also it would be a lot of work to set it up! But it is indeed the safest way to have it working without problems. I’ll contemplate this model as well! Thanks Monster!

The servo reference trick should solve some problem, the player still got it’s own physics and can collide with the platform/ship, the same movement controls work - Just relative to the platform/ship instead of the world.

I don’t know how well the servo motion logic handles extreme speed tho - or worse, extreme acceleration.

I already tested the reference in servo. The first problem I found was that the object cannot move on it’s own, when using the ref., besides that it handles speeds and accelerations fine…

When using ref it moves in relation to the ref (is not that what You want?), to move independent of the ref the ref need to be unset.

But friction + scripted force movements should work. But the ship’s acceleration will cause effects - but should it not? During heavy acceleration the character should be strapped in a G-chair? (rigid body constraint?)

Well during accelerations, the player is parented to the chair. That unfortunately prevents the player t acquire the ship’s velocity. So, later on, there can’t be an unparenting of the player, since it will be at velocity 0, and go through the ship into oblivion.
Apparently, only parenting can work without too much trouble, I think I’ll have to work in these terms, fake collision setups, like disable movement if facing a wall or obstacle.
I can still use friction for the platforms.

Rigid body constraint is an alternative to parenting that will give the character velocity.

Have a work in progress to make them easier to use:

http://bazaar.launchpad.net/~lahlab/flexicomp/flexicomp/view/head:/rbc.py