1

I have a plane that contains around 200 tiles, and I'd like to be able to detect which tile has been clicked by the player. Each tile has a box collider attached. I've also created an empty game object in the scene to which I attached EventSystem and the below script:

public class PlaneBehaviour : MonoBehaviour, IPointerDownHandler {
    public GameObject ClickSymbol;

    public void Start() {
        var physicsRaycaster = FindObjectOfType<PhysicsRaycaster>();

        if (physicsRaycaster == null) {
            Camera.main.gameObject.AddComponent<PhysicsRaycaster>();
        }
    }

    public void OnPointerDown(PointerEventData eventData) {
        var o = eventData.pointerCurrentRaycast.gameObject;
    }
}

Now, when user clicks anywhere, nothing happens - I've put a breakpoint inside the OnPointerDown method, but it's not getting hit (and the code inside the Start method is run - I've also verified that by putting a breakpoint in there).

Programmer
  • 121,791
  • 22
  • 236
  • 328
Marek M.
  • 3,799
  • 9
  • 43
  • 93

1 Answers1

4

There are many things that could cause the callback function not being called. Before trying these, put Debug.Log inside the OnPointerDown function to make sure that it's being called:

1.Go to GameObject-->UI--->EventSystem.

A GameObject named "EventSystem" will be created and will proper scripts such as EventSystem, StandAloneInputModule attached to it.

2.The PlaneBehaviour script must be attached to the GameObject with the Collider not to an empty GameObject. It detects click on the Objects it is attached to.

3.If you are using a collider that ends with "2D" in its name then Physics2DRaycaster must be used instead of PhysicsRaycaster.

4.Are you using more than two cameras? If so manually attach PhysicsRaycaster to the correct Camera that is currently showing that Object.

5.Re-size the GameObjects you want to detect clicks on to be bigger. I've seen doing this solve the problems sometimes. You then have to move the camera back if this works.

Programmer
  • 121,791
  • 22
  • 236
  • 328
  • As for the point number 2 - in the question I asked previously, you said to not attach this script to each tile. Now I'm confused :) – Marek M. Jul 21 '17 at 08:36
  • The title of both questions are **not** the-same. The other question answers question about why `if (Input.GetMouseButtonDown(0))` is executed more than once. This is a different question and has nothing to do with `if (Input.GetMouseButtonDown(0))`. The EventSystem is different and should be attached to each individual Object since it is *event based* **not** *poll based*. – Programmer Jul 21 '17 at 08:41
  • Ok, attaching it to the tile prefab did the trick. Thanks again! – Marek M. Jul 21 '17 at 08:49
  • No problem I will change the title to reflect the problem, so that it wont be a duplicate of the [this](https://stackoverflow.com/questions/41391708/how-to-detect-click-touch-events-on-ui-and-gameobjects/41392130#41392130) question and so that it will help others. – Programmer Jul 21 '17 at 08:52
  • I have one more question that's maybe not very much related to this one - if I have a collider for each tile and for some other objects in the scene (I'm building a maze, so each rock - wall has one too) - won't that add up to a number that Unity can't handle, or will start making my game really slow? Maybe I should programatically add colliders only to the objects that are in certain proximity to the player, and remove them after they start being "out of scope"? What do you think? – Marek M. Jul 21 '17 at 09:38
  • Use Object pooling. Instantiate many of them re-use them. Disable them when you don't need them but don't destroy them. – Programmer Jul 21 '17 at 09:47