You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/holdable/README.md
+6-1Lines changed: 6 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -33,7 +33,10 @@ Add the `holdable` component to an entity you'd like to make grabbable, such as
33
33
| position | vec3 | Local offset position where the object should be held (relative to controller). |`0 0 0`| Any position coordinates (in meters) |
34
34
| rotation | vec3 | Local offset rotation applied when held (relative to controller). |`0 0 0`| Any rotation angles (in degrees) |
35
35
36
-
**Note**: Left-hand interactions are mirrored - position and rotation offsets are automatically flipped when grabbing with the left hand.
36
+
**Notes**:
37
+
38
+
- Left-hand interactions are mirrored - position and rotation offsets are automatically flipped when grabbing with the left hand.
39
+
- Using "0 0 0" for position or rotation will indicate no custom position or rotation. For rotation, this means the rotation will be the same as the object's original rotation when grabbed.
37
40
38
41
## Behavior & Features
39
42
@@ -51,9 +54,11 @@ Add the `holdable` component to an entity you'd like to make grabbable, such as
51
54
52
55
- You don't need to manually add the intersection class (`.interactable`) - `holdable` adds it automatically.
53
56
- It's recommended to use the `post-model-load-refresh` component (part of `mss-aframe-kit`) if working with GLTF models to ensure raycasters and physics bodies are refreshed post-load.
57
+
- If using a custom rotation and position, just know that rotation pivots around the controller, not the model's center. It's easiest to set the custom rotation before position.
54
58
55
59
## Advanced Usage
56
60
61
+
-**Grip/Release Property Modifiers:** Use the `holdable-grip-` and `holdable-release-` prefixes to apply component modifications on grip and release, respectively. This allows you to change properties like color, scale, or even apply animations when the object is held or released (e.g. `holdable-grip-material="color: blue; opacity: .1"`).
57
62
-**Intersection Class Customization:** Use `data-holdable-intersection-class` on `<a-scene>` to change the default `.interactable` class used for raycaster targeting.
58
63
-**Custom Shape Collision Support:** Preserves and restores multiple `shape__*` components with their configs ([Learn More](https://github.com/c-frame/aframe-physics-system/blob/master/CannonDriver.md#shape)).
59
64
-**Supports Sleepy Physics Objects:** The `sleepy` component from the `aframe-physics-extras` library can be used to reduce jitter for objects that are stacked ([Learn More](https://github.com/wmurphyrd/aframe-physics-extras?tab=readme-ov-file#sleepy)).
* Overview: A component that allows an object to be picked up and held by a controller.
5
5
*
6
-
* Description: This component makes an object "holdable" by VR controllers using raycaster events targeted at objects with the specified intersection class (defaults to "interactable"). When the controller's ray intersects the object, it listens for grip events. On grip down, the component saves any physics settings and re-parents the object to the controller, aligning it based on a local-custom position/rotation (from its schema) or a global default provided by a scene attribute (like `data-holdable-grab-position="0 0 0"`). Rotation pivots around the controller, not the model's center. It's easiest to set the custom rotation before position. If local-custom or global positions are not set, it defaults to where it was actually grabbed (local-computed). On grip up, it restores the original physics and parent. If the object has a `holdable-dynamic-body` attribute, it applies dynamic-body properties after release, even if the object was previously static.
6
+
* Description: This component makes an object "holdable" by VR controllers using raycaster events targeted at objects with the specified intersection class (defaults to "interactable"). When the controller's ray intersects the object, it listens for grip events. On grip down, the component saves any physics settings and re-parents the object to the controller, optionally aligning it based on a local-custom position/rotation (from its schema) or a global default provided by a scene attribute (like `data-holdable-grab-position="0 0 0"`). On grip up, it restores the original physics and parent.
7
7
*
8
-
* Notes:
9
-
* - If using local-computed, using "0 0 0" for position or rotation will indicate no custom position or rotation. For rotation, this means the rotation will be the same as the object's original rotation when grabbed.
10
-
* - Tip: You don't actually need to add the intersection class to the entity, as the holdable component will add it automatically if it is not already present. However, you can add it manually if you want to use the intersection class for other purposes.
11
-
* - Tip: If using models with textures, it's recommended to include the `post-model-load-refresh` component on the scene to ensure raycasters and physics bodies are refreshed after all models have loaded.
12
-
* - Rare: If you want to use another class for raycaster intersections instead of "interactable", you can add it globally to the scene using `data-holdable-intersection-class="your-class"`. This will be used for all holdable objects unless overridden.
13
-
*
14
-
* Limitations:
15
-
* - While there is some code in here showing support for the ammo.js driver, it is not working correctly. After release, collisions no longer work.
16
-
* - There is no way to grab an object with both hands at the same time. User must let go of one hand before grabbing with the other.
8
+
* More info: https://github.com/MakingSpiderSense/mss-aframe-kit/tree/main/docs/holdable
// Modifiers - Apply component modifications handling different component types
104
+
// Note: newProps can be a flag component (e.g., __is_flag: true), a direct value component (e.g., __direct_value: "3 1 2"), or a property-based component with many properties (e.g., { prop1: "value1", prop2: "value2" })
// Simulate pulling the raycaster away by temporarily setting the raycaster's far value to 0, then restoring it. This lets the user grab the object again without moving the controller away first.
0 commit comments