{{tag>dragonscript behavior}}
[[:start|Start Page]] >> [[main|DragonScript Scripting Language]] >> [[dragengine:modules:dragonscript:abstractions|Abstraction Layers: How you want to build your Game]] >> [[dragengine:modules:dragonscript:behavior_elements|Behavior Elements]] >> **ECBehaviorActorIK**
* [[behaviors_use_cases|Behaviors Explained: By Use-Case]]
* [[behaviors_a_to_z|Behaviors Explained: From A to Z]]
====== ECBehaviorActorIK ======
Behavior adding inverse kinematic support to actors.
IK is typically used for situations where actors touch specific points on an object while interacting with them and the exact position or orientation is not well defined. This can be used for example if the actor pulls a lever but the lever can be on different heights above the ground. Using the IK behavior this can be solved without duplicating coding.
To use this behavior add it to the element class after [[behavior_actoranimated|ECBehaviorActorAnimated]]. By default the behavior is disabled. To use IK enable/disable the behavior from the actor action at the appropriate time. Once enabled the behavior tries to find in [[behavior_actoranimated|ECBehaviorActorAnimated]] the animator controllers to input the IK parameters. All controllers are optional and will be updated only if present. Assign to the behavior the target position to track. The behavior actively tracks the element each frame update so dynamic targets are possible. The target is defined using an Element instance with optional local matrix and bone name. Bone name is supported if target is castable to BehaviorElement and supports
[[behavior_component|ECBehaviorComponent]].
The behavior supports these controllers to input IK information to the animator.
The **IK Position Controller** is used to set position of the target relative to the component assigned to the animator. The position is assigned as '//'vector value//.
The **IK Rotation Controller** is used to set orientation of the target relative to the component assigned to the animator. The orientation is assigned as //vector value//.
The **IK Height Controller** is used to set the height of the target above the ground. This is the same value as ''position.getY()'' but assigned as single //value//. This controller
allows to fine tune animators to different target heights above ground. To get the best results you usually have to use an animation for reaching at objects in upright and crouched position. Using this controller you can blend between such animations.
The **IK Pan Controller** is used to set the left-right position of the target. This is the same value as ''position.getX()'' but assigned as single //value//.
The **IK Distance Controller** is used to set the forward-backward position of the target. This is the same value as ''position.getZ()'' but assigned as single //value//.
The **IK Azimuth Controller** is used to set the left-right rotation of the target. This is the same value as ''rotation.getY()'' but assigned as single //value//.
The **IK Elevation Controller** is used to set the up-down rotation of the target. This is the same value as ''rotation.getX()'' but assigned as single //value//.
====== Instance Counts ======
This behavior can be used multiple times on an element. Use the behavior identifier to tell them apart. Multiple instances can be used for example to apply inverse kinematics to different body parts at the same time or to allow switching between different parameter sets (like controller names or ranges) for the same body part.
====== Element Class Properties ======
Element class properties have the prefix **actorIK.** or **actorIK(id).** if id is not empty.
===== controllerIKPosition =====
Name of the controller to assign IK position to using //vector value//. If the controller is not found it is ignored.
* Full name: "actorIK.controllerIKPosition" or "actorIK(id).controllerIKPosition"
* Type string
* Default Value ''ik.position''
* Example (*.deeclass) ik.position
===== controllerIKRotation =====
Name of the controller to assign IK rotatio to using //vector value//. If the controller is not found it is ignored.
* Full name: "actorIK.controllerIKRotation" or "actorIK(id).controllerIKRotation"
* Type string
* Default Value ''ik.rotation''
* Example (*.deeclass) ik.rotation
===== controllerIKHeight =====
Name of the controller to assign IK height (Y axis position) to using //value//. If the controller is not found it is ignored.
* Full name: "actorIK.controllerIKHeight" or "actorIK(id).controllerIKHeight"
* Type string
* Default Value ''ik.height''
* Example (*.deeclass) ik.height
===== controllerIKPan =====
Name of the controller to assign IK pan (X axis position) to using //value//. If the controller is not found it is ignored.
* Full name: "actorIK.controllerIKPan" or "actorIK(id).controllerIKPan"
* Type string
* Default Value ''ik.pan''
* Example (*.deeclass) ik.pan
===== controllerIKDistance =====
Name of the controller to assign IK distance (Z axis position) to using //value//. If the controller is not found it is ignored.
* Full name: "actorIK.controllerIKDistance" or "actorIK(id).controllerIKDistance"
* Type string
* Default Value ''ik.distance''
* Example (*.deeclass) ik.distance
===== controllerIKAzimuth =====
Name of the controller to assign IK azimuth (Y axis rotation) to using //value//. If the controller is not found it is ignored.
* Full name: "actorIK.controllerIKAzimuth" or "actorIK(id).controllerIKAzimuth"
* Type string
* Default Value ''ik.azimuth''
* Example (*.deeclass) ik.azimuth
===== controllerIKElevation =====
Name of the controller to assign IK elevation (X axis rotation) to using //value//. If the controller is not found it is ignored.
* Full name: "actorIK.controllerIKElevation" or "actorIK(id).controllerIKElevation"
* Type string
* Default Value ''ik.elevation''
* Example (*.deeclass) ik.elevation
====== Events ======
This behavior has no events.
====== Required Behaviors ======
* [[behavior_actoranimated|ECBehaviorActorAnimated]]
====== Optional Behaviors ======
This behavior does not support optional behaviors.
====== Persistency ======
This behavior does support element class to be persistable (setPersistable).
====== API Documentation ======
#@LinkApiDocDEDS2_HTML~classDragengine_1_1Scenery_1_1ECBehaviorActorIK.html,ECBehaviorActorIK~@#.
Since DragonScript Module Version ''1.2''
====== Use Cases ======
* Actor interacts with objects located in different distances or heights relative to the actor but the animation should properly touch the object
====== Element Class Example ======
pin Dragengine.Scenery
class ObjectElementClass extends BaseActorClass
public var ECBehaviorActorIK actorIK
public func new() super("ExampleObject")
// the base actor class creates an actor animated behavior we can use
// create actor ik behavior. assign the controller names used in the animator
// to control the inverse kinematics if different than the default.
actorIK = ECBehaviorActorIK.new(this, getActorAnimated())
actorIK.getControllerIKPosition().setValue("ik.position")
actorIK.getControllerIKRotation().setValue("ik.rotation")
actorIK.getControllerIKHeight().setValue("ik.height")
end
end
class ActorActionIK extends BAAFirstPerson
public var ECBehaviorActorIK.Instance actorIK
public func new()
end
// store the behavior so we can use it
protected func void initBehaviors()
super.initBehaviors()
actorIK = ECBehaviorActorIK.getInstanceIn(actor)
end
// enable IK while this action is assigned to an actor then disable it again.
// using disable() instead of setEnabled(false) also clears the target
public func void activate()
super.activate()
actorIK.setTarget(targetElementToTouch)
actorIK.setEnabled(true)
end
public func void deactivate()
actorIK.disable()
super.deactivate()
end
end
Example class applying IK to two body groups at the same time if desired.
pin Dragengine.Scenery
class ObjectElementClass extends BaseActorClass
public var ECBehaviorActorIK actorIKLeft
public var ECBehaviorActorIK actorIKRight
public func new() super("ExampleObject")
// the base actor class creates an actor animated behavior we can use
// create actor ik behavior for the left and right hand. assign the controller
// names used in the animator to control the inverse kinematics
actorIKLeft = ECBehaviorActorIK.new(this, getActorAnimated(), "left")
actorIKLeft.getControllerIKPosition().setValue("ik.left.position")
actorIKLeft.getControllerIKRotation().setValue("ik.left.rotation")
actorIKLeft.getControllerIKHeight().setValue("ik.left.height")
actorIKRight = ECBehaviorActorIK.new(this, getActorAnimated(), "right")
actorIKRight.getControllerIKPosition().setValue("ik.right.position")
actorIKRight.getControllerIKRotation().setValue("ik.right.rotation")
actorIKRight.getControllerIKHeight().setValue("ik.right.height")
// using this setup actor actions can enable IK handling for each hand
// individually or for both at the same time
end
end
class ActorActionIK extends BAAFirstPerson
public var ECBehaviorActorIK.Instance actorIKLeft
public var ECBehaviorActorIK.Instance actorIKRight
public func new()
end
// store the behavior so we can use it
protected func void initBehaviors()
super.initBehaviors()
actorIKLeft = ECBehaviorActorIK.getInstanceIn(actor, "left")
actorIKRight = ECBehaviorActorIK.getInstanceIn(actor, "right")
end
// enable IK while this action is assigned to an actor then disable it again.
// using disable() instead of setEnabled(false) also clears the target.
// the element is facing us hence our left side is actually on the right side
// from the point of view of the element. the target position is always
// relative to the target element.
public func void activate()
super.activate()
actorIKLeft.setTarget(targetElementToTouch, Vector.new(0.2, 0, 0))
actorIKLeft.setEnabled(true)
actorIKRight.setTarget(targetElementToTouch, Vector.new(-0.2, 0, 0))
actorIKRight.setEnabled(true)
// you can change target position later on using setTargetMatrix(Vector)
end
public func void deactivate()
actorIKLeft.disable()
actorIKRight.disable()
super.deactivate()
end
end
====== Behavior Factory ======
Using element class supporting adding behaviors the behavior can be added like this:
second
ik.position
ik.position.x
====== Live Examples ======
* [[https://github.com/LordOfDragons/deexamples|DEExamples Repository]]