@needle-tools/engine 4.14.0-next.b2e3b1a → 4.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/components.needle.json +1 -1
  3. package/dist/{needle-engine.bundle-BC1QDiuv.umd.cjs → needle-engine.bundle-COL2Bar3.umd.cjs} +125 -125
  4. package/dist/{needle-engine.bundle-Bhgt3W8p.min.js → needle-engine.bundle-NolzHLqO.min.js} +127 -127
  5. package/dist/{needle-engine.bundle-CeQXs7Hh.js → needle-engine.bundle-Z_gAD7Kg.js} +4924 -4963
  6. package/dist/needle-engine.d.ts +132 -65
  7. package/dist/needle-engine.js +2 -2
  8. package/dist/needle-engine.min.js +1 -1
  9. package/dist/needle-engine.umd.cjs +1 -1
  10. package/lib/engine/api.d.ts +202 -17
  11. package/lib/engine/api.js +270 -17
  12. package/lib/engine/api.js.map +1 -1
  13. package/lib/engine/engine_components.d.ts +1 -1
  14. package/lib/engine/engine_components.js +3 -7
  15. package/lib/engine/engine_components.js.map +1 -1
  16. package/lib/engine/engine_context.d.ts +0 -12
  17. package/lib/engine/engine_context.js +0 -29
  18. package/lib/engine/engine_context.js.map +1 -1
  19. package/lib/engine/engine_gltf_builtin_components.js +1 -16
  20. package/lib/engine/engine_gltf_builtin_components.js.map +1 -1
  21. package/lib/engine-components/export/usdz/extensions/behavior/BehaviourComponents.d.ts +92 -13
  22. package/lib/engine-components/export/usdz/extensions/behavior/BehaviourComponents.js +92 -32
  23. package/lib/engine-components/export/usdz/extensions/behavior/BehaviourComponents.js.map +1 -1
  24. package/package.json +2 -2
  25. package/src/engine/api.ts +370 -18
  26. package/src/engine/engine_components.ts +3 -7
  27. package/src/engine/engine_context.ts +2 -28
  28. package/src/engine/engine_gltf_builtin_components.ts +1 -17
  29. package/src/engine-components/export/usdz/extensions/behavior/BehaviourComponents.ts +110 -53
@@ -13,7 +13,7 @@ import { AudioSource } from "../../../../AudioSource.js";
13
13
  import { Behaviour, GameObject } from "../../../../Component.js";
14
14
  import { Rigidbody } from "../../../../RigidBody.js";
15
15
  import type { IPointerClickHandler, PointerEventData } from "../../../../ui/PointerEvents.js";
16
- import { ObjectRaycaster,Raycaster } from "../../../../ui/Raycaster.js";
16
+
17
17
  import { makeNameSafeForUSD,USDDocument, USDObject, USDZExporterContext } from "../../ThreeUSDZExporter.js";
18
18
  import { AnimationExtension, RegisteredAnimationInfo, type UsdzAnimation } from "../Animation.js";
19
19
  import { AudioExtension } from "./AudioExtension.js";
@@ -22,32 +22,32 @@ import { ActionBuilder, ActionModel, BehaviorModel, EmphasizeActionMotionType,Gr
22
22
 
23
23
  const debug = getParam("debugusdzbehaviours");
24
24
 
25
- function ensureRaycaster(obj: GameObject) {
26
- if (!obj) return;
27
- if (!obj.getComponentInParent(Raycaster)) {
28
- if (isDevEnvironment())
29
- console.debug("Raycaster on \"" + obj.name + "\" was automatically added, because no raycaster was found in the parent hierarchy.")
30
- obj.addComponent(ObjectRaycaster);
31
- }
32
- }
33
-
34
25
  /**
35
- * Make the object move to the target object's transform when clicked.
26
+ * Moves an object to the target object's transform when clicked.
27
+ * Works in the browser and in USDZ/QuickLook (Everywhere Actions).
28
+ *
29
+ * @see {@link SetActiveOnClick}to toggle visibility of objects when clicked
30
+ * @see {@link PlayAnimationOnClick} to play animations when clicked
31
+ * @see [Everywhere Actions](https://engine.needle.tools/docs/everywhere-actions)
36
32
  * @summary Moves an object to a target transform upon click
37
33
  * @category Everywhere Actions
38
34
  * @group Components
39
35
  */
40
36
  export class ChangeTransformOnClick extends Behaviour implements IPointerClickHandler, UsdzBehaviour {
41
37
 
38
+ /** The object to move. */
42
39
  @serializable(Object3D)
43
40
  object?: Object3D;
44
41
 
42
+ /** The target object whose transform to move to. */
45
43
  @serializable(Object3D)
46
44
  target?: Object3D;
47
45
 
46
+ /** The duration of the movement animation in seconds. */
48
47
  @serializable()
49
48
  duration: number = 1;
50
49
 
50
+ /** If true, the motion is relative to the object's current transform instead of moving to the target's absolute position. */
51
51
  @serializable()
52
52
  relativeMotion: boolean = false;
53
53
 
@@ -57,10 +57,6 @@ export class ChangeTransformOnClick extends Behaviour implements IPointerClickHa
57
57
  private targetRot = new Quaternion();
58
58
  private targetScale = new Vector3();
59
59
 
60
- start(): void {
61
- ensureRaycaster(this.gameObject);
62
- }
63
-
64
60
  onPointerEnter() {
65
61
  this.context.input.setCursor("pointer");
66
62
  }
@@ -189,7 +185,15 @@ export class ChangeTransformOnClick extends Behaviour implements IPointerClickHa
189
185
  }
190
186
 
191
187
  /**
192
- * Change the material of objects when clicked.
188
+ * Switches the material of objects in the scene when clicked.
189
+ * Works in the browser and in USDZ/QuickLook (Everywhere Actions).
190
+ *
191
+ * Finds all objects in the scene that use `materialToSwitch` and replaces it with `variantMaterial`.
192
+ * Multiple `ChangeMaterialOnClick` components using the same `materialToSwitch` can be combined to create a material selection UI.
193
+ *
194
+ * @see {@link SetActiveOnClick} to toggle visibility of objects when clicked
195
+ * @see {@link PlayAnimationOnClick} to play animations when clicked
196
+ * @see [Everywhere Actions](https://engine.needle.tools/docs/everywhere-actions)
193
197
  * @summary Changes the material of objects when clicked
194
198
  * @category Everywhere Actions
195
199
  * @group Components
@@ -218,7 +222,6 @@ export class ChangeMaterialOnClick extends Behaviour implements IPointerClickHan
218
222
  start(): void {
219
223
  // initialize the object list
220
224
  this._objectsWithThisMaterial = this.objectsWithThisMaterial;
221
- ensureRaycaster(this.gameObject);
222
225
  if (isDevEnvironment() && this._objectsWithThisMaterial.length <= 0) {
223
226
  console.warn("ChangeMaterialOnClick: No objects found with material \"" + this.materialToSwitch?.name + "\"");
224
227
  }
@@ -345,7 +348,7 @@ export class ChangeMaterialOnClick extends Behaviour implements IPointerClickHan
345
348
  );
346
349
  ChangeMaterialOnClick._parallelStartHiddenActions.push(...myVariants);
347
350
  if (!ChangeMaterialOnClick._startHiddenBehaviour) {
348
- ChangeMaterialOnClick._startHiddenBehaviour =
351
+ ChangeMaterialOnClick._startHiddenBehaviour =
349
352
  new BehaviorModel("StartHidden_" + this.selfModel.name,
350
353
  TriggerBuilder.sceneStartTrigger(),
351
354
  ActionBuilder.fadeAction(ChangeMaterialOnClick._parallelStartHiddenActions, fadeDuration, false));
@@ -381,29 +384,37 @@ export class ChangeMaterialOnClick extends Behaviour implements IPointerClickHan
381
384
  }
382
385
 
383
386
  /**
384
- * Set the active state of an object when clicked.
387
+ * Shows or hides a target object when this object is clicked.
388
+ * Works in the browser and in USDZ/QuickLook (Everywhere Actions).
389
+ *
390
+ * Optionally hides itself after being clicked (`hideSelf`), or toggles the target's visibility on each click (`toggleOnClick`).
391
+ *
392
+ * @see {@link HideOnStart}to hide an object when the scene starts
393
+ * @see {@link PlayAnimationOnClick} to play animations when clicked
394
+ * @see {@link ChangeMaterialOnClick} to change material when clicked
395
+ * @see [Everywhere Actions](https://engine.needle.tools/docs/everywhere-actions)
385
396
  * @summary Sets the active state of an object when clicked
386
397
  * @category Everywhere Actions
387
398
  * @group Components
388
399
  */
389
400
  export class SetActiveOnClick extends Behaviour implements IPointerClickHandler, UsdzBehaviour {
390
401
 
402
+ /** The target object to show or hide. */
391
403
  @serializable(Object3D)
392
404
  target?: Object3D;
393
405
 
406
+ /** If true, the target's visibility will be toggled on each click. When enabled, `hideSelf` and `targetState` are ignored. */
394
407
  @serializable()
395
408
  toggleOnClick: boolean = false;
396
409
 
410
+ /** The visibility state to apply to the target when clicked. Only used when `toggleOnClick` is false. */
397
411
  @serializable()
398
412
  targetState: boolean = true;
399
413
 
414
+ /** If true, this object will hide itself after being clicked. Only used when `toggleOnClick` is false. */
400
415
  @serializable()
401
416
  hideSelf: boolean = true;
402
417
 
403
- start(): void {
404
- ensureRaycaster(this.gameObject);
405
- }
406
-
407
418
  onPointerEnter() {
408
419
  this.context.input.setCursor("pointer");
409
420
  }
@@ -416,7 +427,7 @@ export class SetActiveOnClick extends Behaviour implements IPointerClickHandler,
416
427
 
417
428
  if (!this.toggleOnClick && this.hideSelf)
418
429
  this.gameObject.visible = false;
419
-
430
+
420
431
  if (this.target)
421
432
  this.target.visible = this.toggleOnClick ? !this.target.visible : this.targetState;
422
433
  }
@@ -442,7 +453,7 @@ export class SetActiveOnClick extends Behaviour implements IPointerClickHandler,
442
453
 
443
454
  beforeCreateDocument() {
444
455
  if (!this.target) return;
445
-
456
+
446
457
  // need to cache on the object itself, because otherwise different actions would override each other's visibility state
447
458
  // TODO would probably be better to have this somewhere on the exporter, not on this component
448
459
  if (this.gameObject[SetActiveOnClick.wasVisible] === undefined)
@@ -503,7 +514,7 @@ export class SetActiveOnClick extends Behaviour implements IPointerClickHandler,
503
514
  // It's much easier to reason about nested actions when we're not duplicating tons of hierarchy...
504
515
  // We can probably only do a shallow clone when the tapped object has geometry of its own, otherwise
505
516
  // we end up with nothing to tap on.
506
-
517
+
507
518
  // Option A: we deep clone ourselves. This makes hierarchical cases and nested behaviours really complex.
508
519
  // We do this currently when the object doesn't have any geometry.
509
520
  if (!this.selfModelClone.geometry) {
@@ -522,11 +533,11 @@ export class SetActiveOnClick extends Behaviour implements IPointerClickHandler,
522
533
  clone.name += "_toggle" + (SetActiveOnClick.clonedToggleIndex++);
523
534
  originalModel.add(clone);
524
535
  this.gameObject[SetActiveOnClick.toggleClone] = clone;
525
-
536
+
526
537
  console.warn("USDZExport: Toggle " + this.gameObject.name + " doesn't have geometry. It will be deep cloned and nested behaviours will likely not work.");
527
538
  }
528
539
  const clonedSelfModel = this.gameObject[SetActiveOnClick.toggleClone];
529
-
540
+
530
541
  if (!this.gameObject[SetActiveOnClick.reverseToggleClone]) {
531
542
  const clone = this.selfModelClone.clone();
532
543
  clone.setMatrix(new Matrix4());
@@ -578,7 +589,7 @@ export class SetActiveOnClick extends Behaviour implements IPointerClickHandler,
578
589
  TriggerBuilder.tapTrigger(selfModel),
579
590
  ActionBuilder.parallel(...toggleSequence)
580
591
  ));
581
-
592
+
582
593
  const reverseSequence: ActionModel[] = [];
583
594
  reverseSequence.push(ActionBuilder.fadeAction(this.toggleModel, 0, false));
584
595
  reverseSequence.push(ActionBuilder.fadeAction(selfModel, 0, true));
@@ -621,7 +632,13 @@ export class SetActiveOnClick extends Behaviour implements IPointerClickHandler,
621
632
  }
622
633
 
623
634
  /**
624
- * Hides the object on scene start.
635
+ * Hides the object when the scene starts.
636
+ * Works in the browser and in USDZ/QuickLook (Everywhere Actions).
637
+ *
638
+ * Useful for setting up objects that should initially be hidden and shown later via a {@link SetActiveOnClick} component.
639
+ *
640
+ * @see {@link SetActiveOnClick} to show or hide objects on click
641
+ * @see [Everywhere Actions](https://engine.needle.tools/docs/everywhere-actions)
625
642
  * @summary Hides the object on scene start
626
643
  * @category Everywhere Actions
627
644
  * @group Components
@@ -663,26 +680,36 @@ export class HideOnStart extends Behaviour implements UsdzBehaviour {
663
680
  }
664
681
 
665
682
  private wasVisible: boolean = false;
666
-
683
+
667
684
  beforeCreateDocument() {
668
685
  this.wasVisible = GameObject.isActiveSelf(this.gameObject);
669
686
  }
670
687
  }
671
688
 
672
689
  /**
673
- * Emphasize the target object when clicked.
690
+ * Applies an emphasis animation to a target object when this object is clicked.
691
+ * Works in USDZ/QuickLook (Everywhere Actions).
692
+ *
693
+ * The emphasis effect can be a bounce, jiggle, or other motion type defined by `motionType`.
694
+ *
695
+ * @see {@link PlayAnimationOnClick} to play animations when clicked
696
+ * @see {@link SetActiveOnClick} to toggle visibility when clicked
697
+ * @see [Everywhere Actions](https://engine.needle.tools/docs/everywhere-actions)
674
698
  * @summary Emphasizes the target object when clicked
675
699
  * @category Everywhere Actions
676
700
  * @group Components
677
701
  */
678
702
  export class EmphasizeOnClick extends Behaviour implements UsdzBehaviour {
679
703
 
704
+ /** The target object to emphasize. */
680
705
  @serializable()
681
706
  target?: Object3D;
682
707
 
708
+ /** The duration of the emphasis animation in seconds. */
683
709
  @serializable()
684
710
  duration: number = 0.5;
685
711
 
712
+ /** The type of motion to use for the emphasis effect (e.g. `"bounce"`, `"jiggle"`). */
686
713
  @serializable()
687
714
  motionType: EmphasizeActionMotionType = "bounce";
688
715
 
@@ -704,29 +731,37 @@ export class EmphasizeOnClick extends Behaviour implements UsdzBehaviour {
704
731
  }
705
732
 
706
733
  /**
707
- * Plays an audio clip when clicked.
734
+ * Plays an audio clip when this object is clicked.
735
+ * Works in the browser and in USDZ/QuickLook (Everywhere Actions).
736
+ *
737
+ * Assign a `target` {@link AudioSource} to use its spatial audio settings, or assign a `clip` URL directly.
738
+ * If no `target` is assigned, an {@link AudioSource} will be created automatically on this object.
739
+ *
740
+ * @see {@link AudioSource}for spatial audio settings
741
+ * @see {@link PlayAnimationOnClick} to play animations when clicked
742
+ * @see {@link SetActiveOnClick} to toggle visibility when clicked
743
+ * @see [Everywhere Actions](https://engine.needle.tools/docs/everywhere-actions)
708
744
  * @summary Plays an audio clip when clicked
709
745
  * @category Everywhere Actions
710
746
  * @group Components
711
747
  */
712
748
  export class PlayAudioOnClick extends Behaviour implements IPointerClickHandler, UsdzBehaviour {
713
749
 
750
+ /** The {@link AudioSource} to use for playback. If not set, one will be created automatically on this object. */
714
751
  @serializable(AudioSource)
715
752
  target?: AudioSource;
716
753
 
754
+ /** URL of the audio clip to play. If not set, the clip assigned to `target` is used. */
717
755
  @serializable(URL)
718
756
  clip: string = "";
719
757
 
758
+ /** If true, clicking again while the audio is playing will stop it. */
720
759
  @serializable()
721
760
  toggleOnClick: boolean = false;
722
761
 
723
762
  // Not exposed, but used for implicit playback of PlayOnAwake audio sources
724
763
  trigger: "tap" | "start" = "tap";
725
764
 
726
- start(): void {
727
- ensureRaycaster(this.gameObject);
728
- }
729
-
730
765
  ensureAudioSource() {
731
766
  if (!this.target) {
732
767
  const newAudioSource = this.gameObject.addComponent(AudioSource);
@@ -781,7 +816,7 @@ export class PlayAudioOnClick extends Behaviour implements IPointerClickHandler,
781
816
  const clipName = AudioExtension.getName(clipUrl);
782
817
  const volume = this.target ? this.target.volume : 1;
783
818
  const auralMode = this.target && this.target.spatialBlend == 0 ? "nonSpatial" : "spatial";
784
-
819
+
785
820
  // This checks if any child is clickable – if yes, the tap trigger is added; if not, we omit it.
786
821
  let anyChildHasGeometry = false;
787
822
  this.gameObject.traverse(c => {
@@ -790,7 +825,7 @@ export class PlayAudioOnClick extends Behaviour implements IPointerClickHandler,
790
825
  // Workaround: seems iOS often simply doesn't play audio on scene start when this is NOT present.
791
826
  // unclear why, but having a useless tap action (nothing to tap on) "fixes" it.
792
827
  anyChildHasGeometry = true;
793
-
828
+
794
829
  const audioClip = ext.addAudioClip(clipUrl);
795
830
  // const stopAction: IBehaviorElement = ActionBuilder.playAudioAction(playbackTarget, audioClip, "stop", volume, auralMode);
796
831
  let playAction: IBehaviorElement = ActionBuilder.playAudioAction(playbackTarget, audioClip, "play", volume, auralMode);
@@ -831,16 +866,30 @@ export class PlayAudioOnClick extends Behaviour implements IPointerClickHandler,
831
866
  }
832
867
 
833
868
  /**
834
- * Plays an animation when clicked.
869
+ * Plays an animation state when this object is clicked.
870
+ * Works in the browser and in USDZ/QuickLook (Everywhere Actions).
871
+ *
872
+ * Assign an {@link Animator} and a `stateName` to play a specific animation state,
873
+ * or assign an {@link Animation} component to play a legacy animation clip.
874
+ *
875
+ * For USDZ export, the component follows animator state transitions automatically, including looping states.
876
+ *
877
+ * @see {@link Animator}for playing animator state machine animations
878
+ * @see {@link Animation} for playing legacy animation clips
879
+ * @see {@link PlayAudioOnClick} to play audio when clicked
880
+ * @see {@link SetActiveOnClick} to toggle visibility when clicked
881
+ * @see [Everywhere Actions](https://engine.needle.tools/docs/everywhere-actions)
835
882
  * @summary Plays an animation when clicked
836
883
  * @category Everywhere Actions
837
884
  * @group Components
838
885
  */
839
886
  export class PlayAnimationOnClick extends Behaviour implements IPointerClickHandler, UsdzBehaviour, UsdzAnimation {
840
887
 
888
+ /** The {@link Animator} component whose state to play when clicked. */
841
889
  @serializable(Animator)
842
890
  animator?: Animator;
843
891
 
892
+ /** The name of the animation state to play. Required when using an {@link Animator}. */
844
893
  @serializable()
845
894
  stateName?: string;
846
895
 
@@ -852,10 +901,6 @@ export class PlayAnimationOnClick extends Behaviour implements IPointerClickHand
852
901
 
853
902
  private get target() { return this.animator?.gameObject || this.animation?.gameObject }
854
903
 
855
- start(): void {
856
- ensureRaycaster(this.gameObject);
857
- }
858
-
859
904
 
860
905
  onPointerEnter() {
861
906
  this.context.input.setCursor("pointer");
@@ -905,9 +950,9 @@ export class PlayAnimationOnClick extends Behaviour implements IPointerClickHand
905
950
  afterCreateDocument(ext: BehaviorExtension, context: USDZExporterContext) {
906
951
  if ((this.animationSequence === undefined && this.animationLoopAfterSequence === undefined) || !this.stateAnimationModel) return;
907
952
  if (!this.target) return;
908
-
953
+
909
954
  const document = context.document;
910
-
955
+
911
956
  // check if the AnimationExtension has been attached and what data it has for the current object
912
957
  const animationExt = context.extensions.find(ext => ext instanceof AnimationExtension) as AnimationExtension;
913
958
  if (!animationExt) return;
@@ -921,7 +966,7 @@ export class PlayAnimationOnClick extends Behaviour implements IPointerClickHand
921
966
  if (requiresExclusivePlayback) {
922
967
  if (isDevEnvironment())
923
968
  console.warn("Setting exclusive playback for " + this.target.name + "@" + this.stateName + " because it has " + animationExt.getClipCount(this.target) + " animations. This works around QuickLook bug FB13410767.");
924
-
969
+
925
970
  PlayAnimationOnClick.rootsWithExclusivePlayback.add(this.target);
926
971
  }
927
972
 
@@ -941,7 +986,7 @@ export class PlayAnimationOnClick extends Behaviour implements IPointerClickHand
941
986
  this.trigger == "tap" ? TriggerBuilder.tapTrigger(this.selfModel) : TriggerBuilder.sceneStartTrigger(),
942
987
  sequence
943
988
  );
944
-
989
+
945
990
  // See comment above for why exclusive playback is currently required when playing multiple animations on the same root.
946
991
  if (requiresExclusivePlayback)
947
992
  playAnimationOnTap.makeExclusive(true);
@@ -1010,14 +1055,14 @@ export class PlayAnimationOnClick extends Behaviour implements IPointerClickHand
1010
1055
  let animationLoopAfterSequence: Array<RegisteredAnimationInfo> = [];
1011
1056
 
1012
1057
  if (animation) {
1013
- const anim = ext.registerAnimation(target, animation.clip);
1058
+ const anim = ext.registerAnimation(target, animation.clip);
1014
1059
  if (anim) {
1015
1060
  if (animation.loop)
1016
1061
  animationLoopAfterSequence.push(anim);
1017
1062
  else
1018
1063
  animationSequence.push(anim);
1019
1064
  }
1020
-
1065
+
1021
1066
  let randomTimeOffset = 0;
1022
1067
  if (animation.minMaxOffsetNormalized) {
1023
1068
  const from = animation.minMaxOffsetNormalized.x;
@@ -1111,7 +1156,7 @@ export class PlayAnimationOnClick extends Behaviour implements IPointerClickHand
1111
1156
  if (lastClip) {
1112
1157
  let clipCopy: AnimationClip | undefined;
1113
1158
  if (ext.holdClipMap.has(lastClip)) {
1114
- clipCopy = ext.holdClipMap.get(lastClip);
1159
+ clipCopy = ext.holdClipMap.get(lastClip);
1115
1160
  }
1116
1161
  else {
1117
1162
  // We're creating a "hold" clip here; exactly 1 second long, and inteprolates exactly on the duration of the clip
@@ -1241,17 +1286,24 @@ export class PreliminaryTrigger extends Behaviour {
1241
1286
  }
1242
1287
 
1243
1288
  /**
1244
- * Hides or shows the object when clicked.
1289
+ * Action to show or hide an object.
1290
+ * Use together with a {@link TapGestureTrigger} to show or hide objects when tapped or clicked.
1291
+ *
1292
+ * @see {@link TapGestureTrigger} to trigger actions on tap/click
1293
+ * @see {@link SetActiveOnClick} for a combined trigger and action component
1294
+ * @see [Everywhere Actions](https://engine.needle.tools/docs/everywhere-actions)
1245
1295
  * @summary Hides or shows the object when clicked
1246
1296
  * @category Everywhere Actions
1247
1297
  * @group Components
1248
1298
  */
1249
1299
  export class VisibilityAction extends PreliminaryAction {
1250
1300
 
1301
+ /** The type of visibility action to apply. */
1251
1302
  //@type int
1252
1303
  @serializable()
1253
1304
  type: VisibilityActionType = VisibilityActionType.Hide;
1254
1305
 
1306
+ /** The duration of the fade animation in seconds. */
1255
1307
  @serializable()
1256
1308
  duration: number = 1;
1257
1309
 
@@ -1268,7 +1320,12 @@ export class VisibilityAction extends PreliminaryAction {
1268
1320
  }
1269
1321
 
1270
1322
  /**
1271
- * Triggers an action when the object is tapped/clicked.
1323
+ * Triggers a {@link PreliminaryAction} (such as {@link VisibilityAction}) when the object is tapped or clicked.
1324
+ * Works in the browser and in USDZ/QuickLook (Everywhere Actions).
1325
+ *
1326
+ * @see {@link VisibilityAction} for controlling object visibility on tap
1327
+ * @see {@link SetActiveOnClick} for a combined trigger and action component
1328
+ * @see [Everywhere Actions](https://engine.needle.tools/docs/everywhere-actions)
1272
1329
  * @summary Triggers an action when the object is tapped/clicked
1273
1330
  * @category Everywhere Actions
1274
1331
  * @group Components