0

I'm trying to detect mouse click on 2D sprite on a 3D scene.

All my Sprite have a Box Collider 2D (well placed) and a script on it but hit is null all the time. I Also tried to put the Update() function on a script on GameEngine GameObject, but I got the same result.

     void Update () {
   if (Input.GetMouseButtonDown(0)) {
         Vector2 mouse_position = Camera.main.ScreenToWorldPoint (Input.mousePosition);
         Collider2D hit = Physics2D.OverlapPoint (mouse_position);

         if (hit) {
             Debug.Log ("Hit" + hit.transform.name);
         } else {
             Debug.Log (hit);
         }
     }
 }

 void OnMouseDown() {
     Debug.Log ("Hit " + this.name);
 }

enter image description here

Arthur
  • 4,870
  • 3
  • 32
  • 57
  • 1
    I'd recommend be using UnityEngine.EventSystems and implementing the the following these interfaces IPointerClickHandler IPointerDownHandler IPointerEnterHandler IPointerExitHandler IPointerUpHandler or at it's most basic level EventTriggers https://unity3d.com/learn/tutorials/topics/user-interface-ui/ui-events-and-event-triggers – Rob Aug 05 '16 at 19:43
  • Arthur - what you are doing is **completely wrong**, heh :) it is far easier. Apart from anything else, **be sure to read this**: http://stackoverflow.com/a/38311402/294884 – Fattie Aug 05 '16 at 20:01
  • indeed Rob has fully explained it for you nicely below – Fattie Aug 05 '16 at 20:08

2 Answers2

2

No need to do what you're doing. The new Canvas UI systems has a sophisticated event system built-in.

If you look at your "Image" component, it has a "Raycast Target" basically turns on or off the event system handlers for that component.

You can listen for clicks/drags and other events on canvas elements using the UnityEngine.EventSystems namespace.

Here's an example for you:

using UnityEngine;
using UnityEngine.EventSystems;
class BuildingUI : Monobehaviour, IPointerDownHandler, IPointerUpHandler {

    void OnPointerDown(PointerEventData eventData)
    {
        Debug.Log("Pointer Down " + eventData.selectedObject.name);
    }

    void OnPointerUp(PointerEventData eventData)
    {
        Debug.Log("Pointer Up " + eventData.selectedObject.name);
    }
}

There are loads of interfaces you can implement, I recommend you checkout the Manual.

Rob
  • 7,039
  • 4
  • 44
  • 75
  • 1
    Quite right. (PS Rob you just have a typo "built-in".) – Fattie Aug 05 '16 at 20:02
  • 2
    OP, if you're trying to do drag and drop. Here's an ***insanely useful*** copy and paste script. http://stackoverflow.com/a/37473953/294884 Just a few years ago studios could charge $20,000 to implement drag and drop. Now you just paste in that script eh. Rob if you haven't seen that one it's very handy – Fattie Aug 05 '16 at 20:07
  • Looks like a decent resource. I've implemented the pointer & drag interfaces a few times now. Very similar to PointerEvents API for web. – Rob Aug 05 '16 at 20:30
  • Thank for this reply, I added the namespace`UnityEngine.EventSystems` ,IPointerDownHandler, IPointerUpHandler` and both method on public, but It' didn't work :/ callback are never triggered – Arthur Aug 06 '16 at 00:05
  • Also tring to add an EventSystem object at the root of my project. But nothing – Arthur Aug 06 '16 at 00:41
  • Okay I don't know why, but I removed my EventSystem GameObject, and re-add it, and i'ts working good ! Thank again for this great reply – Arthur Aug 06 '16 at 16:27
0

I'm pretty sure that the root cause of your problem is that your "Building" objects are UI objects, being under a canvas. There's a number of things that this could lead to, but what I believe is causing your problem is the issue of world and screen space.

You are converting the mouse location from a screen point to world space, when your "Building" objects are under a canvas that does not appear to be using world space for its location. To confirm this, I suggest that you do a Debug.Log for the original mouse position, the converted mouse position, and the actual position of your "Building" objects. If you find that the unconverted mouse position lines up more realistically with your object positions, I suggest removing the conversion.

You may have to do additional work (ie doing some math on the mouse or object positions and/or changing the anchors of your objects) to get it to work perfectly, but this should allow your mouse position and objects to be working with the same units in terms of position.

Blair
  • 6,623
  • 1
  • 36
  • 42
  • Use it's working fine if I put `Input.mousePosition` as attribute of `Physics2D.OverlapPoint`. It's okay if I use Screen mouse position ? Or it's better if I do something to handle that on World ? (and how ?) – Arthur Aug 05 '16 at 19:48
  • 1
    The way you would change it would be changing your Canvas from Screen Space to World space or something like that. I wouldn't recommend that though. If you want your buttons to stay in the same space no matter where your camera moves during your game, you need them to be in screen space, not in world space. Additionally, UI is generally based in screen space and independent of world space, so design-wise it is preferable to use screen coordinates for dealing with UI. – Blair Aug 05 '16 at 19:58