Player movement and friction

Hi,

For several reasons I need a script that calculates movement depending on material properties, such as {‘ice’: 0.1, ‘grass’: 0.8, ‘sand’: 0.5, …}

I tried, but don’t seem to get it perfect. My general idea was to increase player.localLinearVelocity.y while pressing Up and Down Arrow Keys, else decrease player.worldLinearVelocity on x and y. The increase/decrease speed is determined by the material property. Turning with Left and Right Arrow Keys.

Is anyone interested in helping me with this? Uploaded a blend to start from if you like.

Attachments

Translation00.blend (76.7 KB)

While the API does give you access to the object’s material in the game engine, I don’t think you can access the friction property. You can just get around this by specifying the friction for each material yourself within your script.

For implementing friction in player movement, the two most common approaches to take are to reduce the player’s speed each frame linearly or to decrease their speed by a fraction of their current speed.

Here’s an example in sudo-code:

# Method 1
newSpeed = oldSpeed - Friction*someConstant
if newSpeed < 0:
newSpeed = 0

# Method 2
newSpeed = oldSpeed*(someConstant / Friction)
# 0 < Friction*someConstant < 1
# it is not necessary to make sure newSpeed > 0 with this method

Thanks for your answer, Mobious.

Yes, I will get the material with the KX_GameObject.rayCast() method with parameter poly set to 1 and with KX_PolyProxy.getMaterialName(). To the materialname I will add suffixes, such as ‘_ice’, ‘_sand’, …

Yes, I’ve been using these methods. But the problem occurs when turning, the velocity not only has to be determined locally on the Y-axis, but also on the X-axis worldly, when running, and when stopping, worldly on both axis. Because slipping on ice will have these properties. I’ll keep on searching.

You know that materials have physics properties too?
Such a friction, elasticity etc…

You can let the Physics engine let do all to work for you.

agree with Monster in this case :wink:

is already all done .

anyway i suggest to put a indentation on the ground (no ground = no control) :wink:

While what Monster said is true, letting the physics engine control friction simply isn’t an option if your character doesn’t use physics or if you simply want more control over how your character moves.

Since player velocity is actually a vector, you can reduce the player’s speed along the direction they’re traveling by simply reducing the magnitude of their velocity vector.

velocityVector.magnitude -= amountToReduceSpeedBy

use a logic for loop that applies a force based on the material you are touching, or just set the friction on each material, so you apply X force in your motion, and it changes based on what you are touching…

here is a for loop in logic,

you can have forces applied for half and then negitive for half (ping pong)

or trigger forces by number, like if count = 2 apply whatever force*

*(like at the point in a run cycle that is launching you forward)

Attachments

CodeItAll.blend (522 KB)

I agree too. Only problem is that there are also a lot of problems with that. I’ve tried it before, but just couldn’t get it right. If you are depending on material Physics this cannot be combined with localLinearVelocity. The player will always increase at the same rate whether Friction is 0.1 or 1.5. With applyForce you can but this gives the problem that on slopes you will go slower, even stop. I tried the Servo Motion but this will cause problems when crossing from one material to the other, so you get stuck. Another problem with all of these methods is that whenever you stand on a box that’s on ice, moving in a direction will also move the box beneath you. And Simple Motion is no good because you will walk through walls. I really hope it’s just me and that someone may have some experience with using the friction to a benefit for the Player movement, and tell how to do this.

@ BluePrintRandom:
When I look at your script I got a little confused. I’m sorry, but I don’t think this is what I’m looking for.

it is a system, that when trigger plays an action for any of X frames,

So I can do… for 5 frames move up, for 5 move back, when you get to ten do whatever,

it is a trigger-able for loop…

you can apply motion for x frames while playing an animation, or anything really,

you can only do something on the last frame (think timebomb…)

so when I press up arrow, trigger for loop “walk” and apply force, when I press right, apply micro bursts of torque etc, but these bursts can be dependent on the material you are standing on… sorry about all the posts, don’t always think in a line…

it also has the state check (if count = 0) so you can’t keep jumping if you are in air etc,

this means you are editing the method of movement, not the physics engine,

you can also change the rate of advancement of the count, or slow it (like haste)

in my opinion , need other factor , a character walk , a cube strip*.(EDIT: i mean <crawl> )
the friction high not make more slow the character , but instead the inverse.

i have thinked :

  • friction
  • consistency

where the friction give more “grip” , so better accelleration and better breaks.
while a low consistency instead decrease the max speed (as in the sand)

on a ICE you have very few friction , you cannot break, and even accellerate quikly , but the maxspeed can be very hight because
the ice is “rigid” (high consistency)

the aspalt have a lot of friction , but not have to make the character more slow.

i make a blend but i want remake with more correct calculation if possible .

what you think ?

well, this is the blend .
(see 2 post below)

but the code can contain some mistake.

Thanks, MarcoIT. I’ll see if this will solve the issue. It’s appreciated.

I think we both purpose a valid solution :slight_smile:

Logic = awesome
python = awesome
Logic+Python = Unstoppable