Forum rules - please read before posting.

Hotspot distinguish pinch vs tap

I've a 2d game, where you navigate by tapping hotspots to proceed, and pinching to go back (using the pinch script below).
https://adventure-creator.fandom.com/wiki/Pinch_input_events

If the user pinches and the first finger that hits the screen happens to land on a hotspot, even though the second finger touches the screen a millisecond later, the system triggers the events for the hotspot before it can recognise a pinch action.

How can i get the system to differentiate between a single finger tap and a pinch (a 2 finger tap would also work in place of a pinch if that leads to an easy solution)?

Whilst trying to solution this, I was able to set hotspot triggers to double taps, but I would like to avoid double tap navigation at all cost.

«1

Comments

  • By default, taps are recognised when they begin - so toucing a Hotspot with a single finger would result in this behaviour.

    This could be avoided in a different ways, depending on preference - e.g. recognising taps when they end, or requiring a tap to be held for a set time. What would suit your needs best?

  • I think when a tap ends would work quite well.

  • edited June 2023

    This might need expanding upon, but try attaching this to an object in the scene:

    using UnityEngine;
    using AC;
    
    public class TapUp : MonoBehaviour
    {
    
        private void Start ()
        {
            AC.KickStarter.playerInput.InputGetTouchPhaseDelegate = CustomInputTouchPhase;
        }
    
        private TouchPhase CustomInputTouchPhase (int index)
        {
            if (index < Input.touchCount)
            {
                if (index == 0)
                {
                    TouchPhase touchPhase = Input.GetTouch (index).phase;
                    if (touchPhase == TouchPhase.Ended)
                    {
                        return TouchPhase.Began;
                    }
                    else if (touchPhase == TouchPhase.Began)
                    {
                        return TouchPhase.Stationary;
                    }
                    return Input.GetTouch (index).phase;
                }
            }
            return TouchPhase.Canceled;
        }
    
    }
    
  • Can't seem to get around this error that the code throws.
    error CS0117: 'KickStarter' does not contain a definition for 'PlayerInput'

  • edited June 2023

    Do you have a non-AC script or class in your project named "KickStarter"?

    I've amended the script above to counteract this.

  • This code no longer throws errors, but that being said, hotspot taps are not recognised at all. I've been playing around but havn't been able to make it work, could this be settings related?
    I'm using 'Touch Screeb' Input method and 'Context Sensative' Interaction Method.

  • edited June 2023

    I'll attempt a recreation. Are you relying on Unity's legacy Input Manager system, and can you share a shot of your Settings Manager?

  • edited June 2023

    Here are my Input Mgr and Settings Mgr.
    I'm assuming given the notification I'm seeing in the Input Mgr, that I'm on the legacy system.
    https://imgur.com/a/mXk2azV
    Link Name

    Link Name

  • Thanks for the details.

    Remove the TapUp script and try this instead: open up AC's PlayerInteraction script and look at lines 612 and 739 (using the latest release).

    Both lines should mention MouseState.SingleClick. Replace these to MouseState.LetGo, and Hotspots should then be interacted with when a tap is released, as opposed to started.

  • Chris this works flawlessly! Thank you so much.
    Really appreciate the help on this.

  • No problem, I'll look into providing an option to handle this in the next release.

  • Hi Chris. Is there a way to change how long the press has to be held for? Right now
    the MouseState.LetGo doesn't register unless its held for a few milliseconds longer that feels comfortable for a player.

    I've been pouring over the the PlayerInteraction script but haven't been able to solve this myself. Any suggestions?

  • edited April 5

    It's been a while, but I believe this was handled by converting a "LetGo" state to "SingleClick" under certain conditions - so that the checks for a click can continue as normal.

    This is handled in PlayerInteraction's ContextSensitiveClick function - in the current release, line 642.

    However, the original assignment of mouseState is handled within PlayerInput. The location varies based on your chosen Input method, but for touch-screen it's the code block from 466-525, with LetGo set at 514.

    Before it can be set to LetGo, however, it must first be set to HeldDown - which may be the issue.

    Try replacing:

    if (mouseState == MouseState.HeldDown && dragState == DragState.None && CanClick ())
    

    with:

    if (Input.touchCount == 1 && Input.GetTouch (0).phase == TouchPhase.Ended && dragState == DragState.None && CanClick ())
    
  • Replacing the code on line 512 of the PlayerInput.cs file seems to cause the below error.

    Assets\AdventureCreator\Scripts\Controls\PlayerInput.cs(512,11): error CS0019: Operator '&&' cannot be applied to operands of type 'bool' and 'TouchPhase'

  • Apologies - I've amended the above.

  • This has made an improvement, its definitely shaved some milliseconds off, but the user still needs to hold the hotspot for for what feels like half a second before they lift their finger in order to trigger the hotspot.

    The Hotspot input mode is set to Touch up so that pinch actions (which take user to previous scene) dont trigger hotspots.
    I have tried replacing the same code on like 354 aswell but that didn't give any improvement.

    Ideally I need users to be able to click around with abandon, I know where I've placed my hotspots and I myself am having to really press the touchscreen with real commitment and not always triggering them. I've tried this on a few touchscreen devices and seeing the same problem.

  • edited April 9

    Perhaps a different approach is called for.

    If you set your Interaction method to Custom Script, you can replace AC's default input/interaction code with your own. For a simple "tap up to interact" behaviour, this should be enough:

    using UnityEngine;
    using AC;
    
    public class TapUpInteract : MonoBehaviour
    {
    
        void Update ()
        {
            #if UNITY_EDITOR
            if (Input.GetMouseButtonUp (0))
            #else
            if (Input.touchCount == 1 && Input.GetTouch (0).phase == TouchPhase.Ended)
            #endif
            {
                Hotspot hotspot = KickStarter.playerInteraction.GetActiveHotspot ();;
                if (hotspot)
                {
                    if (InvInstance.IsValid (KickStarter.runtimeInventory.SelectedInstance))
                    {
                        hotspot.RunInventoryInteraction (KickStarter.runtimeInventory.SelectedInstance);
                    }
                    else
                    {
                        hotspot.RunUseInteraction ();
                    }
                }
            }
        }
    
    }
    
  • Thanks a million Chris this now works beautifully!! Much appreciated.

  • I've just noticed that when I drag and hold an inventory item over my hotspots now, when I release them, it sees it as a 'Use' interaction rather than an 'Inventory' interaction.

  • Fixed - try the above now.

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.