Skip to content

Interaction

Shaye Garg edited this page Oct 3, 2021 · 5 revisions

Interactions are one of the most important parts of ModelBehaviors.

They are also one of the most complex parts.

interaction uses multiple inbuilt enums and structs, all of which are defined here:

// An enum that defines a mouse event.
enum MouseEvent {
    RightSingle, // Single click with the right mouse button
    MiddleSingle, // Single click with the middle mouse button
    LeftSingle, // Single click with the left mouse button
    RightDouble, // Double click with the right mouse button
    MiddleDouble, // Double click with the middle mouse button
    LeftDouble, // Double click with the left mouse button
    RightDrag, // Right mouse button held down
    MiddleDrag, // Middle mouse button held down
    LeftDrag, // Left mouse button held down
    RightRelease, // Right mouse button released
    MiddleRelease, // Middle mouse button released
    LeftRelease, // Left mouse button released
    Lock, // Control locked in lock mode
    Unlock, // Control unlocked in lock mode
    Move, // Mouse moved
    Leave, // Mouse stopped hovering over the component
    WheelUp, // Wheel moved up
    WheelDown // Wheel moved down
}
// A cursor that the simulator can display
enum Cursor {
    None,
    UpArrow,
    DownArrow,
    LeftArrow,
    RightArrow,
    Hand,
    Crosshair,
    Grab,
    GrabOpen,
    TurnLeft,
    TurnRight,
    TurnLeftSmall,
    TurnRightSmall,
    TurnLeftUpsideDown,
    TurnRightUpsideDown
    UpDownArrows,
    LeftRightArrows,
    DiagonalArrows
}
// An enum that defines a part of the interaction hitbox.
enum Hitbox {
    Left, // The left side of the hitbox
    Right, // The right side of the hitbox
    Up, // The top of the hitbox
    Down, // The bottom of the hitbox
    Center // The center of the hitbox
}
// An axis for interaction
enum Axis {
    X, // The X axis (left and right)
    Y, // The Y axis (up and down)
    Any // Both axes (or neither)
}
// A (legacy) tooltip that changes based upon an animation (or cursor).
struct AnimTooltip {
    percent: num | none = none, // The normalized animation value (0 to 1) at which the tooltip will appear.
    cursor: Cursor | none = none, // The mouse cursor at which the tooltip will appear
    value: str // The value of the tooltip, using the legacy tooltip IDs.
}
// A normal drag, where you can decide how to process it
struct NormalDrag {
    axis: Axis, // The axis you will use to process the drag.
    scalar: num // A value that the simulator uses to scale the values of `(M:RelativeX)` and `(M:RelativeY)`
}
// A drag that is along the path of an animation
struct TrajectoryDrag {
    anim: str, // The animation to use for the drag
    node: str, // The GLTF node affected by the animation
    sync: bool, // If the animation should be synced with the drag
    use_lag: bool, // If the animation `lag` should be used while syncing the animation
}

You can create an interaction like:

interaction {
    legacy_cursors: <expr>,
    lock_cursors: <expr>,
    legacy_events: <expr>,
    lock_events: <expr>,
    legacy_callback: <expr>,
    lock_callback: <expr>,
    tooltip_title: <expr>,
    lock_tooltips: <expr>,
    animated_tooltips: <expr>,
    can_lock: <expr>,
    cursor_animated: <expr>,
    drag_mode: <expr>
}
// This will become:
interaction {
    legacy_cursors: Cursor.Hand,
    lock_cursors: Cursor.Hand,
    legacy_events: [MouseEvent.LeftSingle],
    lock_events: [MouseEvent.LeftSingle],
    legacy_callback: @{
        @"L:ElevatorsInvisible, Bool" = !@"L:ElevatorsInvisible, Bool"
    },
    lock_callback: @{
        @"L:ElevatorsInvisible, Bool" = !@"L:ElevatorsInvisible, Bool"
    },
    tooltip_title: @{ "Interactable Elevators" },
    lock_tooltips: ["MyInputEvent"],
    animated_tooltips: [none],
    can_lock: false,
    cursor_animated: false,
    drag_mode: NormalDrag {
        axis: Axis.Any,
        scalar: 1
    }
}

This must be placed inside a component that has a node.

legacy_cursors: Either a single Cursor or a map from Hitbox to Cursor (essentially an argument with type Cursor | [Hitbox : Cursor]). If a single Cursor is passed, it will appear whenever the mouse is hovering. If the map is passed, the cursor will change depending on where the mouse is hovering. These are the cursors that will appear while the mouse is hovering above the component if the Legacy interaction mode is selected.

lock_cursors: The same as legacy_cursors. These are the cursors that will appear while the mouse is hovering above the component if the Lock interaction mode is selected.

legacy_events: An array of MouseEvents ([MouseEvent]). These are the MouseEvents on which the appropriate callback code will be called.

lock_events: The same as legacy_events but for Lock mode.

legacy_callback: The RPN code to run when in Legacy mode.

lock_callback: The RPN code to run when in Lock mode.

tooltip_title: The RPN code that will create the tooltip's title.

lock_tooltips: The InputEvents to use as tooltips in Lock mode. I don't know why there are multiple.

animated_tooltips: An array of AnimTooltips.

can_lock: If the control can be locked or if it is just a click-based interaction (bool).

cursor_animated: If the cursor is animated or not. This tells the sim that the switch has a limit to its motion, so when the animation value reaches 0, the left and down cursors will be replaced with one that indicates 'invalid', and when it reaches 1, the right and up cursors will be replaced.

drag_mode: The mode of dragging used. Can be either NormalDrag or TrajectoryDrag (has a type NormalDrag | TrajectoryDrag).

Clone this wiki locally