This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
dragengine:modules:dragonscript:locomotion [2017/02/22 14:27] – [FPS Locomotion] dragonlord | dragengine:modules:dragonscript:locomotion [2024/03/14 16:43] (current) – dragonlord | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | {{tag> | ||
<WRAP youarehere> | <WRAP youarehere> | ||
[[: | [[: | ||
Line 4: | Line 5: | ||
====== Locomotion ====== | ====== Locomotion ====== | ||
- | Locomotion defines the movement, looking, turnging and stance states of actors. The DragonScript module provides basic locomotion implementation using the [[http:// | + | Locomotion defines the movement, looking, turnging and stance states of actors. The DragonScript module provides basic locomotion implementation using the # |
====== Parameters ====== | ====== Parameters ====== | ||
Line 64: | Line 65: | ||
|Can turn in-place|true| | |Can turn in-place|true| | ||
- | Drive Input Parameter Sets like this: | + | Drive //Input Parameter Sets// like this: |
^Parameter-Set^Goal value^ | ^Parameter-Set^Goal value^ | ||
|Analog moving direction|Calculate // | |Analog moving direction|Calculate // | ||
Line 89: | Line 90: | ||
|Turn left-right|Turning is used here to turn the body into the direction the actor is moving. Set value to Look left-right.Goal. Optionally you can set the value to 0 if the player presses no movement keys to stop the body moving.| | |Turn left-right|Turning is used here to turn the body into the direction the actor is moving. Set value to Look left-right.Goal. Optionally you can set the value to 0 if the player presses no movement keys to stop the body moving.| | ||
- | FPS locomotion is somewhat simpler to understand and is somewhat cheaper to calculate. There are two ways to handle the animation. The first solution is to use the same setup as in the natural locomotion case. Most of the time though an 8-way animation setup is used. In this case 8 animations of walking/ | + | FPS locomotion is somewhat simpler to understand and is somewhat cheaper to calculate. There are two ways to handle the animation. The first solution is to use the same setup as in the natural locomotion case. Most of the time though an 8-way animation setup is used. In this case 8 animations of walking/ |
====== Vehicle Locomotion ====== | ====== Vehicle Locomotion ====== | ||
Line 108: | Line 109: | ||
|Analog moving direction|0 if moving forward, 180 if moving backward.| | |Analog moving direction|0 if moving forward, 180 if moving backward.| | ||
|Turn left-right|CurrentValue +/- turnSpeed * elapsedFrameTime. Turning speed is in degrees per second. Use positive value to turn left and negative to turn right.| | |Turn left-right|CurrentValue +/- turnSpeed * elapsedFrameTime. Turning speed is in degrees per second. Use positive value to turn left and negative to turn right.| | ||
+ | |||
+ | Vehicle locomotion is the simplest locomotion type of the three and the cheapest. Disabling the turning adjustments and in-place turning is important to avoid the vehicle suddenly turning when the looking around approaches the border. | ||
====== Animator and collider control ====== | ====== Animator and collider control ====== | ||
- | Locomotion allows to set an [[http:// | + | Locomotion allows to set an # |
< | < | ||
Line 125: | Line 128: | ||
</ | </ | ||
- | ====== Body tilting ====== | + | The table below lists the available controllers and what they are best used for: |
- | Body tilting provides support to adjust | + | ^Attribute^Description^ |
+ | |Elapsed time|Increments controller using elapsed frame time. Use for all playback driven | ||
+ | |Look up-down|Value of //Look up-down// output parameter. Use for actor looking up-down without moving body.| | ||
+ | |Look left-right|Value of //Look left-right// output parameter. Use for actor looking left-right without moving body. With vehicles this could be used for example for rotating turrets.| | ||
+ | |Moving speed|Value of //Moving speed// output parameter. Use to blend between different movement animations like walking and running. The value can not be used for blending between moving forward and backward since moving speed is always positive.| | ||
+ | |Moving direction|Value of //Moving direction// output parameter. Use for actors using FPS type locomotion | ||
+ | |Relative moving speed|Value of //Moving speed// output parameter using the value of //Moving direction// to produce negative values if moving backwards. Use for actors using natural type locomotion | ||
+ | |Turning speed|Value of //Turning speed// output parameter. Use to blend with animations of the actor turning left or right. Turning speed is positive for turning left and negative for turning right.| | ||
+ | |Stance|Value of //Stance// output parameter. Use to blend between different stances of an actor. The meaning of the value is up to the script user. Only requirement is that values are between 0 and 1.| | ||
+ | |Displacement|Value of //Moving speed// output parameter multiplied by the elapsed time. Use for movement animations to match the playback to the actual distance travelled. For this to work set the animator controller upper limit to the two times the stride length of the actor (if you use an animation with one walk cycle). The actor will then always move with the correct speed avoid feet sliding. This attribute works best for vehicle type locomotion for example tanks.| | ||
+ | |Time turn in-place|Value | ||
+ | |Tilt offset|Value of //Tilt offset// output parameter. Use to offset actor root bone downwards due to tilting. The value is the required offset in meters. Using this attribute moves actors on titled surfaces into a favorable position for inverse kinematic rules.| | ||
+ | |Tilt up-down|Value of //Tilt up-down// output parameter. Use to blend with animation of actor in tilted position. Value is degrees of tilting. Positive values represent ground falling down to the left and negative falling down to the right.| | ||
+ | |Tilt left-right|Value of //Tilt left-right// | ||
- | < | + | ====== Body tilting ====== |
+ | <WRAP box right :en 350px> | ||
{{ : | {{ : | ||
<WRAP centeralign> | <WRAP centeralign> | ||
</ | </ | ||
+ | Body tilting provides support to adjust animations of actors to better fit them to uneven ground. Body tilting require # | ||
The results are weighted to get a best matching virtual ground plane. This mode is most expensive but the results are more stable and of higher quality. Once done the tilt result can be applied to animator instance controlls as any other locomotion state. | The results are weighted to get a best matching virtual ground plane. This mode is most expensive but the results are more stable and of higher quality. Once done the tilt result can be applied to animator instance controlls as any other locomotion state. | ||
< | < | ||
- | // set up locomotion body tilt for an actor using the weighted method | + | func void init() |
- | locomotion.setTiltMode( Locomotion.TILT_WEIGHTED ) | + | |
- | + | locomotion.setTiltMode( Locomotion.TILT_WEIGHTED ) | |
- | // create collision filter shared by all tests | + | |
- | var LayerMask category = LayerMask.new() | + | // create collision filter shared by all tests |
- | category.setBit( GameState.CL_AI ) // we are an collider for doing actor ai | + | var LayerMask category = LayerMask.new() |
- | + | category.setBit( GameState.CL_AI ) // we are an collider for doing actor ai | |
- | var LayerMask filter = LayerMask.new() | + | |
- | filter.setBit( GameState.CL_GEOMETRY ) // we can hit geometry like the ground | + | var LayerMask filter = LayerMask.new() |
- | filter.setBit( GameState.CL_AI ) // we can hit other actor ai colliders | + | filter.setBit( GameState.CL_GEOMETRY ) // we can hit geometry like the ground |
- | + | filter.setBit( GameState.CL_AI ) // we can hit other actor ai colliders | |
- | var CollisionFilter collisionFilter = CollisionFilter.new( category, filter ) | + | |
- | + | var CollisionFilter collisionFilter = CollisionFilter.new( category, filter ) | |
- | // set collision test. the test points are located above the ground since otherwise tilting up can not | + | |
- | // be detected. as a rule of thumb the test distance should be two times the start height. for each | + | // set collision test. the test points are located above the ground since otherwise tilting up can not |
- | // test a ray test is used. this is the fastest solution and works well for most situations. | + | // be detected. as a rule of thumb the test distance should be two times the start height. for each |
- | var float offset = 0.5 // height above ground to start testing | + | // test a ray test is used. this is the fastest solution and works well for most situations. |
- | var Vector testDistance = Vector.new( 0.0, -offset * 2.0, 0.0 ) // distance to test downwards | + | var float offset = 0.5 // height above ground to start testing |
- | + | var Vector testDistance = Vector.new( 0.0, -offset * 2.0, 0.0 ) // distance to test downwards | |
- | locomotion.setCCTTiltFrontLeft( ColliderCollisionTest.new( touchSensor, | + | |
- | collisionFilter, | + | locomotion.setCCTTiltFrontLeft( ColliderCollisionTest.new( touchSensor, |
- | + | collisionFilter, | |
- | locomotion.setCCTTiltFrontRight( ColliderCollisionTest.new( touchSensor, | + | locomotion.setCCTTiltFrontRight( ColliderCollisionTest.new( touchSensor, |
- | collisionFilter, | + | collisionFilter, |
- | + | locomotion.setCCTTiltBackLeft( ColliderCollisionTest.new( touchSensor, | |
- | locomotion.setCCTTiltBackLeft( ColliderCollisionTest.new( touchSensor, | + | collisionFilter, |
- | collisionFilter, | + | locomotion.setCCTTiltBackRight( ColliderCollisionTest.new( touchSensor, |
- | + | collisionFilter, | |
- | locomotion.setCCTTiltBackRight( ColliderCollisionTest.new( touchSensor, | + | |
- | collisionFilter, | + | // add mappings so our animator uses the calculated values |
- | + | locomotion.addControllerMaping( controllerTiltOffset, | |
- | // add mappings so our animator uses the calculated values | + | locomotion.addControllerMaping( controllerTiltUpDown, |
- | locomotion.addControllerMaping( controllerTiltOffset, | + | locomotion.addControllerMaping( controllerTiltLeftRight, |
- | locomotion.addControllerMaping( controllerTiltUpDown, | + | end |
- | locomotion.addControllerMaping( controllerTiltLeftRight, | + | |
// tilt is enabled so during Element.postThink the tilt is updated automatically and the result | // tilt is enabled so during Element.postThink the tilt is updated automatically and the result | ||
// applied to animator instance controllers | // applied to animator instance controllers | ||
- | locomotion.updatePostLocomotion( | + | func void postThink( float elapsedFrameTime ) |
+ | | ||
+ | end | ||
</ | </ | ||
====== State control and frame update ====== | ====== State control and frame update ====== | ||
- | To update the locomomotion multiple calls are used. After the player has provided input the [[http:// | + | To update the locomomotion multiple calls are used. After the player has provided input the # |
If you want to enhance the locomotion class you have to be careful about the calling structure. The native classes methods call themselves internally for performance reasons. The entire late binding is skipped. Overwriting the update calls has no effect in this case. To partially change behavior you have to implement the updateLocomotion() and updatePostLocomotion() calls yourself and call the native methods from the script. This allows to inject your changes in the right place. This all works since it is no problem to call a method from script if it is a native class but the native class. | If you want to enhance the locomotion class you have to be careful about the calling structure. The native classes methods call themselves internally for performance reasons. The entire late binding is skipped. Overwriting the update calls has no effect in this case. To partially change behavior you have to implement the updateLocomotion() and updatePostLocomotion() calls yourself and call the native methods from the script. This allows to inject your changes in the right place. This all works since it is no problem to call a method from script if it is a native class but the native class. | ||
====== Player Input Tracker ====== | ====== Player Input Tracker ====== | ||
- | To help with managing the player input for use with locomotions the DragonScript module provides a helper class [[http:// | + | To help with managing the player input for use with locomotions the DragonScript module provides a helper class # |
+ | The //Player Input Tracker// supports all three mentioned locomotion types and has similar // | ||
+ | < | ||
+ | // create an input tracker and set parameters | ||
+ | func void init() | ||
+ | tracker.setSpeedLookLeftRight( 45.0 ) // degrees per second | ||
+ | tracker.setSpeedLookUpDown( 45.0 ) // degrees per second | ||
+ | tracker.setSpeedTurnLeftRight( 30.0 ) // degrees per second. for vehicle type locomotion | ||
+ | tracker.setCanTurn( true ) // player turning commands are used | ||
+ | tracker.setCanMove( true ) // player movement commands are used | ||
+ | tracker.setCanChangeStance( true ) // player stance change commands are used | ||
+ | tracker.setSpeedWalk( 3.0 ) // meters per second. you can set backward speed individually | ||
+ | tracker.setSpeedRun( 8.0 ) // meters per second. you can set backward speed individually | ||
+ | end | ||
+ | |||
+ | // in reaction to player input commands alter state | ||
+ | func void playerPressForward() | ||
+ | tracker.setMoveForward( true ) // button press (true), button release (false). | ||
+ | end | ||
+ | |||
+ | func void playerMoveMouse( Point mouseMovement ) | ||
+ | // mouse movement during this frame update for natural and fps locomotion | ||
+ | tracker.setAnalogLookLeftRight( mouseMovement.getX() ) | ||
+ | tracker.setAnalogLookUpDown mouseMovement.getY() ) | ||
+ | end | ||
+ | |||
+ | func void playerPressTurnVehicle() | ||
+ | tracker.setTurnLeft( true ) // turning for vehicle type locomotion | ||
+ | end | ||
+ | |||
+ | // then during each Element.think() call let the tracker update the locomotion | ||
+ | func void think( float elapsedFrameTime ) | ||
+ | tracker.updateLocomotion( locomotion, elapsedFrameTime ) | ||
+ | end | ||
+ | </ |