{{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]] >> **ECBehaviorGrabber**
* [[behaviors_use_cases|Behaviors Explained: By Use-Case]]
* [[behaviors_a_to_z|Behaviors Explained: From A to Z]]
====== ECBehaviorGrabber ======
Behavior adding support to grab an [[behavior_grabspot|ECBehaviorGrabSpot]].
Grab spots are typically used for physics interaction like VR hand use but can be used also with mouse interaction. The actual grabbing interaction, exact grab location and orientation as well as attaching logic is handled by other behaviors using listening. This behavior also tracks if what grab spot an actor is grabbing. Hence at most one grab spot can be grabbed by this behavior at each time.
Elements able to be grabbed have to use the [[behavior_grabspot|ECBehaviorGrabSpot]] behavior. Both the grab spot and the grabber have to persist the other behavior. During restoring no notifications are triggered this way.
To detect grab spots a touch sensor is added with a default sphere shape. By default the touch sensor is disabled and has to be enabled if the game logic allows grabbing. The collision filter category is set to BaseGameApp.CollisionFilterBit.trigger and the collision filter mask is set to BaseGameApp.CollisionFilterBit.dynamic.
====== Instance Counts ======
This behavior can be added multiple times to an element. Use the behavior identifier to tell them apart.
====== Element Class Properties ======
Element class properties have the prefix ''grabber.'' or ''grabber(id).'' if id is not empty.
===== shape =====
Shape of collider used to detect grab spots.
* Full name: ''grabber.shape'' or ''grabber(id).shape''
* Type: string (shape format). See "Shape List Encoding" in CodecPropertyString.
* Default Value: empty string
* Example (*.deeclass): box:extends,0.1,0.1,0.1
===== position =====
Attach position relative to parent element or bone.
* Full name: ''grabber.position'' or ''grabber(id).position''
* Type: 3-component float vector
* Default Value: ''(0, 0, 0)''
* Example (*.deeclass):
===== rotation =====
Attach orientation in euler degrees relative to parent element or bone.
* Full name: ''grabber.rotation'' or ''grabber(id).rotation''
* Type: 3-component float vector
* Default Value: ''(0, 0, 0)''
* Example (*.deeclass):
===== bone =====
Name of bone to attach to or empty string to attach to the parent element.
* Full name: ''grabber.bone'' or ''grabber(id).bone''
* Type: string
* Default Value: empty string
* Example (*.deeclass): attach hand.r
====== Events ======
===== spotGrabbed =====
Grabber grabbed grab spot.
===== spotReleased =====
Grabber released grab spot.
===== touchGrabSpot =====
Start touching grab spot.
===== untouchGrabSpot =====
Stop touching grab spot.
===== canTouchGrabSpot =====
Grab spot can be touched if all listeners return true.
===== enabledChanged =====
Grabber enabled changed.
====== Behavior Tree Actions ======
This behavior adds these behavior tree actions if behavior tree is present. If behavior has non-empty identifier replace ''grabber'' with ''grabber(id)''.
===== grabber.set =====
Set one or more grabber parameters.
^Parameter^Value^Description^
|enabled|''true'', ''false''|Grabber is enabled|
This is an example of using this action:
true
===== grabber.update =====
Update grabber.
^Parameter^Value^Description^
|release| |Release grab spot if grabbing one.|
|interactElement.assign|string|Assign grab spot element to [[behavior_interactelement|ECBehaviorInteractElement]] with identifier matching value string. Action fails if no element is grabbed or interact element behavior is absent|
|interact|string|Interact with grab spot. If element is absent action fails. Runs interaction with name value. If interaction with name value is absent fails action. If interaction returns false fails action. Otherwise action succeeds.|
|interact.parameters|string|Optional parameters to use with ''interaction''.|
This is an example of using this action:
===== grabber.check =====
Check one or more grabber parameters. Action succeeds if all parameter value matches their respective grabber parameter otherwise action fails. This action is typically used as first action in a sequence to run the sequence only if a grabber parameter matches (or not).
^Parameter^Value^Description^
|enabled|''true'', ''false''|Grabber is enabled|
|grabbing|''true'', ''false''|Grabber is grabbing a grab spot|
|interact.name|string|Name of interaction|
|interact.has|''true'', ''false''|Has grab spot and interaction with name ''interaction.name'' is present|
|interact.query|''true'', ''false''|Interact with grab spot and test result. Condition is true if grab spot is present, interaction with name ''interaction.name'' is present and interaction returns true. It is recommended to use here only interactions without side effects (hence query interactions).|
|interact.parameters|string|Optional parameters to use with ''interaction.query''.|
|wait| |If present action returns BTResult.running instead of BTResult.failed to wait until the checks are all fulfilled|
This is an example of using this action:
true
====== Behavior Tree Conditions ======
This behavior adds these behavior tree conditions if behavior tree is present. If behavior has non-empty identifier replace ''grabber'' with ''grabber(id)''.
===== grabber.check =====
Check one or more grabber parameters. Conditions returns true if all parameter value match their respective grabber parameter. This condition is typically used to run an action or sequence of actions as long as grabber conditions are true.
^Parameter^Value^Description^
|grabber.enabled|''true'', ''false''|Grabber is enabled|
|grabber.grabbing|''true'', ''false''|Grabber is grabbing a grab spot|
|grabber.interact.name|string|Name of interaction|
|grabber.interact.has|''true'', ''false''|Has grab spot and interaction with name ''interaction.name'' is present|
|grabber.interact.query|''true'', ''false''|Interact with grab spot and test result. Condition is true if grab spot is present, interaction with name ''interaction.name'' is present and interaction returns true. It is recommended to use here only interactions without side effects (hence query interactions).|
|grabber.interact.parameters|string|Optional parameters to use with ''interaction.query''.|
This is an example of using this condition:
true
grabber.check
====== State Machine Actions ======
Same as [[#behavior_tree_actions|Behavior Tree Actions]].
====== State Machine Conditions ======
Same as [[#behavior_tree_conditions|Behavior Tree Conditions]].
====== State Machine Events ======
This behavior sends these state machine events. If behavior has non-empty identifier replace ''grabber'' with ''grabber(id)''.
===== grabber.enabled =====
Grabber has been enabled.
===== grabber.disabled =====
Grabber has been disabled.
===== grabber.grabbed =====
Grabber grabbed grab spot.
===== grabber.released =====
Grabber released grab spot.
===== grabber.touch =====
Start touching grab spot.
===== grabber.untouch =====
Stop touching grab spot.
====== Required Behaviors ======
This behavior does require other behaviors.
====== Optional Behaviors ======
* [[behavior_collider|ECBehaviorCollider]]: If used attaches grab spot touch collider to collider
* [[behavior_vrhand|ECBehaviorVRHand]]: If used attaches grab spot touch collider to VR hand collider
* [[behavior_behaviortree|ECBehaviorBehaviorTree]]: Add actions and conditions for behavior trees to use.
* [[behavior_statemachine|ECBehaviorStateMachine]]: Add actions and conditions for state machine to use and events to send to the state machine.
====== Persistency ======
This behavior does support element class to be persistable (setPersistable).
====== API Documentation ======
#@LinkApiDocDEDS2_HTML~classDragengine_1_1Scenery_1_1ECBehaviorGrabber.html,ECBehaviorGrabber~@#.
Since DragonScript Module Version ''1.9''
====== Use Cases ======
* Grab objects in VR
====== Element Class Example ======
The following example creates an element class with support to test what element the player is pointing at:
class MyElement extends BehaviorElementClass
public var ECBehaviorVRPlayspace vrPlayspace
public var ECBehaviorVRHand vrHandRight
public var ECBehaviorVRHand vrHandLeft
public var ECBehaviorGrabber vrRightHandGrabber
public var ECBehaviorGrabber vrLeftHandGrabber
public func new()
// Create playspace
vrPlayspace = ECBehaviorVRPlayspace.new(this)
// Create hand controllers. The InputDeviceType indicates what device type
// to monitor. vrRightHand and vrLeftHand can exist only once
vrHandRight = ECBehaviorVRHand.new(this, vrPlayspace, InputDeviceType.vrRightHand, "right")
vrHandLeft = ECBehaviorVRHand.new(this, vrPlayspace, InputDeviceType.vrLeftHand, "left")
// Create grabbers for each hand
vrRightHandGrabber = ECBehaviorGrabber.new(this, vrRightHand, "right")
vrLeftHandGrabber = ECBehaviorGrabber.new(this, vrLeftHand, "left")
end
end
The #@LinkApiDocDEDS2_HTML~classDragengine_1_1Scenery_1_1BaseVRActorClass.html,BaseVRActorClass~@# provides full VR support including ECBehaviorGrabber for both hands.
====== Behavior Factory ======
Using element class supporting adding behaviors the behavior can be added like this:
right
4:1 2
second
second
hand.r
left
hand.l
====== Live Examples ======
* [[https://github.com/LordOfDragons/deexamples|DEExamples Repository]]: ExampleVR project.