Button prefab is causing wrong prefab to trigger

Okay, so I’m having a very weird issue and it is causing me to pull my hair out! Have spent hours trying to work this out.

So, I have a prefab called ‘ShopItem’ this prefab is a UI button with four child objects being UI image or a UI panel. When the prefab is created it gets a listener attached to the on click method. The click handler works, but it seems to only trigger whatever the last instance in the hierarchy.

100348-screen-shot-2017-08-21-at-204923.png

Above you can see the two objects when the game is running, with the game hierarchy shown. These two objects were instantiated using the below script (ignore the messy code this just a test):

void Start() {
    var item = Instantiate(ShopItemPrefab);
    item.name = "Shop Item 1";
    item.GetComponent<Transform>().SetParent(canvas.GetComponent<Transform>());
    item.GetComponent<Transform>().localPosition = new Vector3(-173f, 162f, 1f);
    item.GetComponent<Transform>().localScale = new Vector3(1f, 1f, 1f);

    item.GetComponent<Button>().onClick.AddListener(handleClick);

    var item2 = Instantiate(ShopItemPrefab);
    item2.name = "Shop Item 2";
    item2.GetComponent<Transform>().SetParent(canvas.GetComponent<Transform>());
    item2.GetComponent<Transform>().localPosition = new Vector3(175.5f, 162f, 1f);
    item2.GetComponent<Transform>().localScale = new Vector3(1f, 1f, 1f);

    item2.GetComponent<Button>().onClick.AddListener(handleClick);
}

void handleClick() {
    EventSystem.current.currentSelectedGameObject.GetComponent<ShopItem>().MarkAsSelected();
}

The MarkAsSelected method is then called on the (supposedly) clicked object and basically marks a boolean as true and changes the background sprite.

Link to GIF

Looking at the Gif above I’m clicking the left box, but the right one is the one that gets triggered. Now the weired thing is that neither objects overlap. However, if in the hierarchy view I move ‘Shop Item 2’ above ‘Shop Item 1’ and then click the same box it correctly selects it, but clicking the right box will now trigger the left box.

I hope that makes sense! The confusing thing for me is that I don’t understand how this is happening, neither instance is linked together and it’s not like this is running inside a loop where their may be problems with the variable scopes.

Thank you in advanced for you help, if you have any questions I’m happily answer them. I just don’t know why this is happening!

I think the problem is your using the same message for both buttons. So both buttons are firing one event. Which as listeners to that single event. Means your handleClick is run by both buttons no matter which one gets pressed… Causing whichever one runs last to be your final value of currently selected.

Try 2 events and if your result is as desired. You will need an event that can determine which button triggered the event to set the proper current selection.
ie: Just change

item2.GetComponent<Button>().onClick.AddListener(handleClick);//To
item2.GetComponent<Button>().onClick.AddListener(handleClick2);// and register a second event for the second button.

Okay! I just worked it out. I think it was the way I had created my prefab, having the button as the parent and then the background etc as children of it was causing the click to not be detected. I’m not sure whether it was because the image component was not on the button, so it was technically not rendered?

I have recreated the prefab with an empty object that is just the wrapper, and then instead of having a child background object, this is instead a component on the button.

Below is what I have been trying to get for hours!!! Thank you to @Malace and @tablekorner for helping me figure this out :slight_smile:

100409-aug-22-2017-20-38-29.gif