2
\$\begingroup\$

In my 2d game I have a HUD with some buttons on it. To make it I am using new UI system, which was presented in Unity 4.6. When user is touching button, I am running method, which was declared in EventSystem. But the problem is in that I need to make difference between touch in any part of screen and touch directly on UI, because when I am touching to any part of screen my character starts fighting. And when I am touching the UI image, my character starts fighting and only after that the method that was attached to UI image EventSystem starts. So I need to check what I am touching on screen. For desktop platform everything is okay, when I am running this code:

if (Input.GetMouseButtonDown(0))
{
    EventSystem eventSystem = EventSystem.current;
    if (eventSystem.IsPointerOverGameObject())
    {
        return;
    }
}

And for mobile platforms I am using this code, but it doesn't work. The system doesn't check that user pressed on UI image.

public class TouchController : MonoBehaviour {
    Canvas BonusesAndPotionsCanvas;
    GameObject BonusesAndPotions;
    void Start () 
    {
        BonusesAndPotions = GameObject.FindGameObjectWithTag ("bonuses_and_potions");
        BonusesAndPotionsCanvas = BonusesAndPotions.GetComponent<Canvas> ();
    }

    void Update()
    {
        EventSystem eventSystem = EventSystem.current;
        if (eventSystem.currentSelectedGameObject != null) 
            return;
        for (var i = 0; i < Input.touchCount; ++i) 
        {        
            if (Input.GetTouch(i).phase == TouchPhase.Began)     
            {
                Vector2 worldPoint = Camera.main.ScreenToWorldPoint( Input.GetTouch(i).position );
                if (IsPointerOverUIObject(BonusesAndPotionsCanvas, worldPoint)) 
                    return;
            }
        }
    }

    private bool IsPointerOverUIObject(Canvas canvas, Vector2 screenPosition) 
    {
        PointerEventData eventDataCurrentPosition = new PointerEventData(EventSystem.current);
        eventDataCurrentPosition.position = screenPosition;

        GraphicRaycaster uiRaycaster = canvas.gameObject.GetComponent<GraphicRaycaster>();
        List<RaycastResult> results = new List<RaycastResult>();
        uiRaycaster.Raycast(eventDataCurrentPosition, results);
        return results.Count > 0;
    }
}

Can anyone help me? I will be very glad for any help!

\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

On Mobile you need to need pass Touch.fingerId as parameter into EventSystem.IsPointerOverGameObject(int pointerID), but it is still not perfect, as it fails on TouchPhase.Ended.

See this code:

public void Update()
{
    foreach (Touch touch in Input.touches)
    {
        int pointerID = touch.fingerId;
        if (EventSystem.current.IsPointerOverGameObject(pointerID))
        {
            // at least on touch is over a canvas UI
            return;
        }

        if (touch.phase == TouchPhase.Ended)
        {
            // here we don't know if the touch was over an canvas UI
            return;
        }
    }

    // no canvas UI is used
    // ...
}
\$\endgroup\$
4
  • \$\begingroup\$ Thank you for the answer! For this moment i have no ability to check this method, i'll check it later and i'll write about my progress)) \$\endgroup\$
    – bukka.wh
    Dec 24, 2014 at 20:34
  • \$\begingroup\$ so which way did you go? \$\endgroup\$
    – JeanLuc
    Jan 8, 2015 at 11:51
  • \$\begingroup\$ I am sorry, but I still have no success. if (EventSystem.current.IsPointerOverGameObject(pointerID)) Not working wor me((( May be this is a bug of the new UI system? \$\endgroup\$
    – bukka.wh
    Jan 9, 2015 at 12:08
  • \$\begingroup\$ In the EventSystem GameObject make sure that the component "Standalone Input Module" has "Allow Activation On Mobile Device" disabled. \$\endgroup\$
    – JeanLuc
    Jan 19, 2015 at 8:35

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .