Platformer issues

I was wondering on how to do this for a long time ago, the main question is, How do I make a character stick to a moving platform without it sliding under the character. Any Ideas?

Friction… add a material to your platform, hit the “DYN” button, and add friction.

TheSambassador
I don’t think that friction is the way to go with the solutions currently available.
I have found the reference object field (Motion Actuaror -> Servo Control) to be a far better solution.

Note : not trying to make your argument ridiculous, or being sarcastic at all. Just trying to explain in plain english, but it’s not that easy.
If the floor is slippy in a train, and if you fall, you don’t fall at the speed of 300km/h : the way you move is related to the object you are standing on.
“Reference object for velocity calculation, leave empty for world reference”.
Please check the attached .blend.

Friction is playing (example of the train) a relatively little part of it if we take the floor and the shoes friction properties into account. The train company doesn’t put 50cm of sand in the train so people don’t slide at 300km/h when they try to stand up.
That’s hard to explain in english(…).

You’ve been using Blender for a long time and I don’t, but I found that tweaking the friction settings was a solution used by a lot of “old” members, I started using Blender few months ago and I think that it’s not the most relevant way to do now.

Anyway, the reference object’s solution is not perfect yet (platform moving on the Z axis) but it’s getting closer to the expected result, I guess. What do you think?

Now the best thing would be to :

  1. have access to servo control with python (available through a custom class, see quote below)
  2. be able to dynamically change the reference field (on event) (not possible without actuator yet)

I remember you helped me on a .blend where I was asking for a python access to servo control.
Here is a brief resume of the situation, that i gavein another thread :

Hi,
your question is a good one and being able to set the linear velocity through python is not enough to simulate servo motions.
I have asked the same thing in another thread : obj.pid, obj.ForceLimitX, obj.reference : can we have it?.

‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’’

Quick answer

‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’’

The quick answer is : with the actual API, there is no way to access servo motions through python without actuator.

[quote]cyborg_ar
that kind of things would be better implemented using python subclassing in 2.5, i don’t really see the need to bloat KX_GameObject with a servo controller.
(…)
It’s not hard to do the way you suggest, but the code doesn’t work like that, the servo controller is extra code that forms part of the Servo actuator class (KX_ObjectActuator), setLinearVelocity() is a call to KX_IPhysicsController::SetLinearVelocity() and every KX_GameObject already include an KX_IPhysicsController as the memeber m_pPhysicsController1, so adding the function was just about exposing the call. To make the servo be part of KX_GameObject would mean to relocate or… eww… copypaste the code to KX_GameObject or KX_IPhysicsController, and the interface you suggest is confusing and would allow only ONE servo per object. for thins kind of aditional stuff i’d prefer a “plug-in” architecture, something logic bricks do reasonably well, or using a class like the one i implemented in python. Or maybe just remove the servo option from the motion actuator and make it a physics constraint implemented in bullet.

After I took time to explain what I was looking for and why my question was not completely idiot, I got help from theSambassador and cyborg_ar who provided useful methods.

Here is the one I use, created “for me” by cyborg_ar :

‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’’

Temporary solution

‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’’

PIDServo(own, [0,0,1], True, [0, 0, 50])

‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’’

Documentation

‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’’

CLASS PIDServo

Constructor PIDServo(owner, target, local, pid, min_=[None,None,None], max_=[None,None,None])

Parameters:

  • owner (KX_GameObject): Object the servo class will be moving.
  • target ([X, Y, Z] List): Target speed for the servo
  • local (Boolean): Use local coordinates
  • pid ([P, I, D] List): Gains for the Proportional Integral and Derivative components
  • min_ ([X, Y, Z] List): Minimum bound for the action force, set a certain axis to None to turn it off (eg: [None, None, 1.54] would only limit the Z axis)
  • max_ ([X, Y, Z] List): Maximum bound for the action force, set a certain axis to None to turn it off (eg: [None, None, 1.54] would only limit the Z axis)

‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’’

# Example blend

‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’’

servo.blend

‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’’

Note : still needed to be done

# ‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’‘’’
the ability to add a reference object is still missing.
And this is an important feature.
I have asked cyborg_ar and he said he would do it in his spare time. I don’t want to bother him by sending a reminder though.
[/quote]I would be happy to have other member’s opinion about that.
Is there a better solution?

Attachments

ref_platform.blend (128 KB)

yeah, thanks cray, I’ve read that post a long time ago, (the one about the train). And I really thought that adding a fake gravity would suffice, but no. (i’ll post the offending blend that made me think so later when I change computers) I’ll check on the blend.

also, changing the friction doesn’t work since the character seems to “bounce” a bit after landing (I’ll upload blend in my next post.)

is it possible that i’ll just constrain the character to the ground, and just add dynamics if the character is in the air?

(the Cube game that won the logic brick contest had a moving platform that works perfectly. i think. I don’t know how that worked)

Thanks in advance

I made that Cube game :). All I used was Friction. Poke around with the settings… I believe I used a pretty high friction value.

Cray: Servo can work, but it pretty much requires Python, or a separate servo control for each and every different moving platform. That’s why I suggested the “simple” solution.

Really, friction is all that’s at work on “real life” moving platforms. When a train moves, the force of friction acts upon your shoes and moves you. If you were to jump right before a train started accelerating, you wouldn’t start accelerating with the train until you landed. Moreso, if the floor of the train was 100% smooth ice with a friction coefficient of 0, when the train starts accelerating you will literally slide in place until you hit the back of a train, in which case the normal force of the train will begin to move you.

When you fall on a train going 300KPH, you absolutely are moving that fast… everything on the train is! However, relative to the train, you might only be going 1 or 2 KPH. When you jump on an already-moving train, you stay with the train because you’re already at that velocity. If you jump OFF of a train and hit the REAL “unmoving” ground, then obviously it’s going to hurt… you’re going 300KPH!!!

To use friction effectively, it’s a good idea to know the mathematical equations behind it:
Force of Friction = Friction Coefficient * Normal Force

And note that:
Normal Force is the force exerted back on an object (remember, “For every action there is an equal and opposite reaction.”). Normal force is really just that “reaction” force. In terms of the ground, that normal force would be Mass * Gravity.

One thing that I wonder about though…
In actual physics, you have a Coefficient of Static Friction in addition to a Coefficient of Kinetic Friction. Blender seems to use only 1… the kinetic one (somebody correct me if I’m wrong). Might there be a way to set the first one?

-Sam

Yes, what sambassador said was true, friction is what makes you move relative to the train, Anyway, I’ll just use the friction, I think, because I’ll only have a few platforms moving in one level. The game will mostly be a bop and jump platformer with a little puzzle element (note: LITTLE)

thanks for all the answers

anyway, speed IS relative according to the theory of relativity, so we wouldn’t be able to agree on how fast the guy on the train is *haha

Hi,
TheSambassador
I understand your explanations and you are surely right.
I might look a bit idiot but anyway I’ll try to push my argument (not against physics or you, but for the application of those theories to the Blender Game Engine).

The thing is, I always got bad results using friction and found the solution a lot complicated if the map uses several different friction settings :

  1. let’s say, first I put 0.5 for a platform.
    Another will have 45.
    And so for xx platforms moving at different speeds.

In level 2, I have to use friction settings again accordingly to the way I did it in the first map to achieve realistic results. (how many factors? moving speed + material spec + weather/wind… etc) That becomes harder, and more if we working with a team.
So first thing (please correct me if I’m wrong) it’s important to keep a record of friction settings and always refer to that one. That can bring a lot of errors.
And we talk about moving platforms with constant speeds.

  1. If I suddenly decide to change the speed of a platform or the speed of a whole level (to make it easier, in ex for debug), or if a platform is suddenly stopped by an event, the friction settings become a problem because they are set for one speed level only.
    As far as I know, it’s not possible to change the friction settings dynamically.
    The train stops : my player can’t move anymore. (Made tests with force, servo control are ok).
    Is that something that can be avoided?
    Please see attached .blend.

Those friction settings don’t allow a player to walk on the wing of a big plane, whose speed would change during the game.(speed 0 ->20 -> 0)

  1. Disabling the friction settings by pushing the “DYN” button on the platform material again doesn’t disable anything. Friction is still applied (?)
    This DYN button doesn’t seem to be a tab only, because we can use multiple buttons (ex : RGB + DYN, HSV + DYN).
    So, by pushing twice the DYN button, my understanding of the user interface is that it should deactivate the friction settings. And it doesn’t.

  2. When the player is moving on a moving platform, his velocity is still relative to the world.
    Please connect the Always sensor on the Platform and the controller to activate the platform’s movement.
    Also change the Cube motion actuator to servo control :
    http://www.aandria.com/wp-content/images/diary/servomotion_move_z.png
    For the people who don’t know about servo control :
    I took that screen from another of my threads, please set the linV for X, not Y.

Then push the right arrow to walk in the right direction.
Now you see that is not what would happen in a train.

  1. So i was a bit disappointed that my suggestion was not even taken in account : “Reference object for velocity calculation” for me there is no simpler solution than that.
    That option was made on purpose so I don’t see why it’s not used.
    That’s what takes us the closest to a platformer behavior (I mean, platformers tweak reality on the topic of moving platforms : possibility to stand on fast moving platforms, possibility to jump from a platform moving on Z axis, etc).

Only that setting would suffice to get a good behavior on the whole game. That’s not much.
No need to set xxx platforms, only few that would need a special behavior (sand, ice).
It just needs to be improved by the developers (Python access) and that’s all.

So, you are surely right on the whole thing.
But I really can’t see how it could be applied to the game engine without being a big pain.
Please take this as an argument, no offense.

Attachments

ref_platform.blend (129 KB)