Skip to content

t1k:cocos:playable:tutorials

FieldValue
Moduleplayable
Version0.5.6
Efforthigh
Tools

Keywords: ads, arrow hint, cocos, finger tutorial, playable, tutorials, UI

/t1k:cocos:playable:tutorials

FingerTutorial, ArrowHint & TutorialSequence

Section titled “FingerTutorial, ArrowHint & TutorialSequence”

Three Cocos Components for guiding the player through the FTUE. FingerTutorial shows an animated finger sprite for tap/drag/hold gestures. ArrowHint shows a pulsing arrow that tracks a moving target. TutorialSequence orchestrates both into step-by-step flows and fires TutorialCompleteSignal via SignalBus. See also: t1k-cocos-playable-signalbus, t1k-cocos-playable-gameflow, t1k-cocos-playable-animation-presets.

See references/tutorial-patterns.md for composite parameter details (TutorialHandParameter, RichTextParameter).

Import paths:

  • db://assets/PLAGameFoundation/tutorials/FingerTutorial
  • db://assets/PLAGameFoundation/tutorials/ArrowHint
  • db://assets/PLAGameFoundation/tutorials/TutorialSequence

Attach to the finger sprite node. Set targetNode (and dragTargetNode for DRAG) in Inspector or at runtime.

PropertyTypeDefaultDescription
targetNodeNodenullNode to point the finger at
dragTargetNodeNodenullDrag endpoint (DRAG action only)
actionFingerActionTAPAnimation style
loopDelaynumber0.5Seconds between animation loops
autoStartbooleantrueCall show() automatically in start()
export enum FingerAction { TAP = 0, DRAG = 1, HOLD = 2 }
finger.show(); // fade in and begin looping animation
finger.hide(); // fade out and deactivate node
finger.setTarget(node: Node); // change targetNode at runtime
finger.dragTargetNode = node; // set drag endpoint at runtime
finger.action = FingerAction.DRAG;

The node starts with active = false and UIOpacity = 0. show() sets active = true and fades in.

Attach to the arrow sprite node. The arrow repositions itself every update() to track a moving targetNode.

PropertyTypeDefaultDescription
targetNodeNodenullNode to point at
pulseScalenumber0.2Amplitude of scale pulse (e.g. 0.2 = scales between 0.8 and 1.2)
pulseSpeednumber1.0Seconds per full pulse cycle
autoStartbooleantrueCall show() automatically in start()
offsetVec3(0,50,0)Offset from target in local parent space
arrow.show();
arrow.hide();
arrow.setTarget(node: Node);
arrow.offset = new Vec3(0, 80, 0); // adjust offset at runtime

Orchestrates FingerTutorial and ArrowHint through a series of steps. Wire fingerNode and arrowNode in the Inspector.

PropertyTypeDescription
fingerNodeNodeNode carrying a FingerTutorial component
arrowNodeNodeNode carrying an ArrowHint component
interface TutorialStepConfig {
finger?: { target: Node; action?: FingerAction; dragTarget?: Node };
arrow?: { target: Node; offset?: Vec3 };
text?: string; // reserved for future label support
condition?: () => boolean; // auto-advance when returns true
duration?: number; // auto-advance after N seconds
}
seq.setSteps(steps: TutorialStepConfig[]): void;
seq.begin(): void; // show step 0 and start the sequence
seq.nextStep(): void; // manually advance to next step
seq.skip(): void; // hide everything and fire TutorialCompleteSignal
export class TutorialCompleteSignal {
constructor(public readonly sequenceNode: Node = null) {}
}

Fired by SignalBus when the last step completes or skip() is called.

See references/tutorial-patterns.md for complete usage patterns.

  • TutorialSequence uses SignalBus.instance.fire(new TutorialCompleteSignal(...)) — subscribe in GameView or the FTUE state to advance game flow.
  • FingerTutorial positions itself in its parent’s local space by converting targetNode.worldPosition — both nodes must share a common Canvas ancestor.
  • Disable autoStart on FingerTutorial and ArrowHint when using TutorialSequence to prevent them from starting before begin() is called.
  • Clean up subscriptions to TutorialCompleteSignal in onDestroy.
  • Setting autoStart = true on FingerTutorial/ArrowHint when also using TutorialSequence — they will start independently before begin() is called.
  • Forgetting to set dragTargetNode when using FingerAction.DRAG — it silently falls back to the TAP animation.
  • Not subscribing to TutorialCompleteSignal before calling begin() — if the sequence is short (duration-based), the signal may fire before the subscription is registered. Subscribe first, then call begin().
  • ES2017 target: do not use optional chaining (?.) or nullish coalescing (??) in game code.
  • Tutorials in playable ads have a 5-second budget — past that, networks penalize CTR.
  • Skip-tutorial state must persist for the session — replaying tutorial on every retry kills funnel.
  • Highlight rectangles need to update when their target moves — static cutout windows lag a frame behind on scroll/animate.