Simple Drift-less Character Movement Setup V2.0 - 10/19/12 UPDATE

10/19/12 UPDATE: Version 2.0

Yo. It’s been awhile. I was looking at my old implementation of this, and well, it was pretty poor. So, I made a new version that’s a lot smoother, and integrates better with Bullet’s engine, so it should also solve the ‘launch problem’ where you can launch yourself forward quickly by moving into and object and then moving away. Check it out here.

— OLD VERSION —

Hey. So while I was in the process of making a game, I found a nice setup that moves objects easily via linear velocity, but avoids the drifting that frequently arises when moving by linear velocity. The method makes use of the obj.setLinearVelocity() function, which gives a nice, stable method to set movement - it works alright .Check it out here.

Yup. That works pretty good.

Two issues, but they’re issues with a lot of other methods too…
Diagonal movement will be faster than one directional movement. (can be fixed by checking for diagonal movement and multiplying by 0.7071)
On computers running at different frame rates, the acceleration will be different. (with how fast you have the acceleration set now, it probably wouldn’t be very noticeable)

Diagonal movement will be faster? How do you figure?
I fixed the framerate acceleration issue in the next script. Here it is.

A typical Controlling Problem that can occur with simple Movement.

If you accelerate towards an sidewards with a Speed of One, you will move your Character one full Unit diagonally…


\..|... 
.\.|... 
..\|...
---+...
.......

… which is more than the Distance the Character would move when moving in only one of both Directions. You must imagine a Bow drawn from the Y peak to the X peak, like a Quarter Circle around the Origin, and that the Caracter should only move as far as a Radius of that Circle could go, thus the approcimate Value 0.7something. :wink:


...|... 
.\.|... 
..\|...
---+...
.......

EDIT:
Would that Factor be meant to be 1.0-(π*0.1) ?
'cause that would actually be 0.685841…
Though roughly rounded, 0.700

Here’s another version. Better?

Good job. Looks correct to me.

Thanks. I should release another version for this one.

----- cut -----

certain that the “engine” of physics is just disgusting!

I think there are too many “add-ons”, which were added over time, each trying to solve a problem, but in the end, all create conflict between them.

and the result is crap!

I also noticed that there are options in materials that change
physics !!! O_O
I think the most useful thing would be to remove all the useless stuff, secondary (this is what makes mess)

cleanup!!cleanup!!

Attachments



@ MarcoIT:

You are just confused. ;]

The Material Physics can make Sense, though I personally think they should generally be deactivated.

Use Material Force can be highly useful for certain Circumstances – you should try it! You can apply a Force to a Material’s Physics and get that your Object will be pushed away from the Material – for Example if you want to have an Object hover above something! (I think of the Steampipes in McGee’s Alice.)

The Damping Options can make Sense, they control the Sensitivity of how much the Object moves and rotates (by itself) – that can function pretty well as some sort of mid-air-Friction.

No Sleeping is an important Option to HAVE! Not to USE, most of the Time, but to HAVE! It avoids your Object from physically fall asleep – so it will permanently be affected by Physics, instead of becomin’ static after some Time.

Rotate From Normal sounds totally useful, but never works for me. o_O

Anistrophic Friction is the one where I do, for the Moment, not really know what it does.

Anisotropic friction = separate friction coefficients along each axis of the object.

not see flag(maybe is this: “use material force field” in panel physics? )

The Damping Options can make Sense, they control the Sensitivity of how much the Object moves and rotates (by itself) – that can function pretty well as some sort of mid-air-Friction.

can! can make sense , but this is built really BAD!think this is the cause of almost all problem!

No Sleeping is an important Option to HAVE! Not to USE, most of the Time, but to HAVE! It avoids your Object from physically fall asleep – so it will permanently be affected by Physics, instead of becomin’ static after some Time.

this yes :wink:

Rotate From Normal sounds totally useful, but never works for me. o_O

also this is made bad!

Anistrophic Friction is the one where I do, for the Moment, not really know what it does.

seem too many!! too function for the same thing! no good!

just yesterday I tried to do a sort of car game …
the car mantain in the memory,
the rebound of the first 2 climbs !!!
(after a minute!)
impossible, really badly done!!!

I don’t think that there are too many functions for the same thing, as I believe they’re all necessary. I would assume that this is at least some of the Bullet Physics API that has been exposed, and that professional games use all the features they can get a hold of. :wink:

there is the “bounce”, which is a problem (big) (problem of the climbs …)

though increasing, “Translation,” -> max
this problem is “solved”

but it creates a new problem,
in the air becomes very slow.

try to bend the mesh,
and make up a simple climb

solid object, or Dynamics, is equal

there is some secondary variable wrong that interferes with linearVelocity

EDIT:SOLVED :stuck_out_tongue:

The friction and elasticity values are also important, elasticity for example is important for simulating objects made of rubber or other elastic materials as it allows an object to bounce on collision instead of make a sudden stop.

Friction is also important, it allows a different amount of resistant to movement depending on what object your character or object is colliding with just like in the real world, it’s simply not something that can be easily done with the damping value.

Anisotropic friction can also be useful in a number of cases such as vehicles or any other case where you do not want the object to slide sideways when moving compared to sliding forward or backward.

The only thing that really could be improved right now is that the physics properties in the material settings are per-object (the object will only use the settings from the first material index), getting that to work on a per-material level has been needed for a long time now, especially since we’re well beyond the ‘tex-face’ days where the BGE only recognized one material per object.

I did the climbs, with applyMovement (the same of Motion-> loc)
and behaving in an absurd way. : D

using the speed is fine! very well!!

you were right, it is helpful to have some physical properties of materials, now I’m using friction. hehe;) very comfortable
is that when you do not know, seem useless things :wink:

Hey, I updated this to V2.0 to use Vectors and tie in with Bullet, rather than keeping my own speed values. It’s a lot better now, I think.

Hey SolarLune!

how would I use the setup to work in only one direction like the y


from bge import logic, events
import mathutils

cont = logic.getCurrentController()
obj = cont.owner
keyboard = logic.keyboard.events

#keys
kw = events.WKEY
ks = events.SKEY
ka = events.AKEY
kd = events.DKEY 

##################

if not 'moveinit' in obj:
    obj['moveinit'] = 0
    obj['mv'] = mathutils.Vector()  # Movement vector
    
    
    obj['friction'] = .5   # Friction amount; higher numbers = faster stops
    obj['accel'] =  10 + obj['friction']     # Acceleration
    obj['maxspd'] = 30 + obj['friction']   # Top speed
    obj['movelocal'] = 0    # If you're moving on the local axes or not



if not obj['movelocal']:                     
    
    obj['mv'].y = obj.localLinearVelocity.y
else:
    obj['mv'].y = obj.localLinearVelocity.y
 

obj['mv'].z = 0.0
  
# Friction
  
obj['mv'].y = obj['maxspd'] if obj['mv'].y > obj['maxspd'] else obj['mv'].y
  
# Taking input
   
if keyboard[kw]:
    obj['mv'].y = obj['accel']
elif keyboard[ks]:
    obj['mv'].y = obj['accel']
elif keyboard[ka]:
    obj['mv'].y = obj['accel']
elif keyboard[kd]:
    obj['mv'].y = obj['accel']
# Clamping

obj['mv'].y = obj['maxspd'] if obj['mv'].y > obj['maxspd'] else obj['mv'].y
    
if not obj['movelocal']:
    mvz = mathutils.Vector([0, 0, obj.localLinearVelocity.z])   #   (Add in gravity last)
    obj.localLinearVelocity = obj['mv'] + mvz             #   To move globally

I’ve got it work like this however the speed does not accelerate.
this was the original, which I didn’t understand how that worked.


if not obj['movelocal']:                        # Keeping the speed added from frame to frame allows Bullet to do stuff, like stop your character if you run into a wall
    obj['mv'].x = obj.worldLinearVelocity.x
    obj['mv'].y = obj.worldLinearVelocity.y
else:
    obj['mv'].x = obj.localLinearVelocity.x
    obj['mv'].y = obj.localLinearVelocity.y

obj['mv'].z = 0.0

Also, what would be a better why to set up wasd to equal one variable for the keys than having all four of them there.