UnityApplePencil icon indicating copy to clipboard operation
UnityApplePencil copied to clipboard

Started and Ended TouchPhase Analogue states?

Open yosun opened this issue 1 year ago • 1 comments

previously i have been using hybrid touch, but i realize this is updating at a different frame rate than unity's Input.touch...

How does one determine using this plugin when the pencil event has started and ended?

yosun avatar Jul 10 '24 09:07 yosun

Here is some code cribbed from my app...this probably won't work as-is, I'm doing some other stuff with UIToolkit that I cut out and haven't tested this by itself. But maybe it will help you. Handling estimated/predicted touches is tricky, so if you don't know about those, read about it in Apple's Pencil documentation, or try throwing those events away to start.

    bool captured;

    /// <summary>Subscribing to the low-level InputSystem events lets us get lots more events.  If we just use the
    /// UI system events, the events are capped by the framerate.  Note that we don't use the UI's pointer events at 
    /// all for this because their PointerDownEvent comes after we've already missed a few pen down events.</summary>
    void OnInputEvent(InputEventPtr eventPtr, InputDevice device) {
        // not an event we care about
        if (!eventPtr.IsA<StateEvent>() && !eventPtr.IsA<DeltaStateEvent>())
            return;

        var pen = device as Pen;
        var pencil = device as ApplePencil;
        if (pencil == null)
            return;
    
        // apple pencil sends estimation updates after the pencil is lifted, so we need to pass them through, taking
        // care not to change the state of the pen by reading the button bitmask (which would affect press?)
        // fixme - is that how this works?
        bool isEstimationUpdate = pencil.isEstimationUpdate.ReadValueFromEvent(eventPtr) > 0;
        bool isPredicted = pencil.isPredicted.ReadValueFromEvent(eventPtr) > 0;

        // look for a new pointer down event on the canvas
        var isPointerDownEvent = false;
        if (!captured && !isEstimationUpdate && !isPredicted) {
            // check the current and previous values of press to see if we're starting a new stroke.
            if (pen.press.ReadValueFromEvent(eventPtr) == 0 || pen.press.ReadValue() != 0)
                return;
            isPointerDownEvent = true;
            captured = true;
        }

        // handle move events.  Apple Pencil needs special handling due to its estimated properties.
        var pos = pen.position.ReadValueFromEvent(eventPtr);
        var press = pen.press.ReadValueFromEvent(eventPtr) > 0;
        int estimationUpdateID = estimationUpdateID = pencil.estimationUpdateIndex.ReadValueFromEvent(eventPtr);
        byte buttonsBitmask = (byte) pencil.buttonsBitmask.ReadValueFromEvent(eventPtr);
        byte expectingUpdatesFor = (byte) (buttonsBitmask & (byte) UITouchProperty.All);
        if (isPointerDownEvent) {
            // pointer down event
        } else if (!press && !isEstimationUpdate && !isPredicted) {
            // pointer up event
            captured = false;
        } else {
            // pointer move event (we include estimation updates with these)
        }
    }

all-iver avatar Jul 10 '24 21:07 all-iver