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\$
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\$
  • \$\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 '14 at 20:34
  • \$\begingroup\$ so which way did you go? \$\endgroup\$ – JeanLuc Jan 8 '15 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 '15 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 '15 at 8:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.