Search Issue Tracker
Fixed in 2017.3.0f3
Fixed in 2017.1.X, 2017.2.X
Votes
5
Found in
2017.2.0b11
Issue ID
950588
Regression
Yes
OnClick event of the Button is called as many times as there are different events registered to it
To reproduce:
1. Open the project, attached by the user (Click.zip)
2. Open "sample" scene
3. Enter Play mode
4. Press the button on the screen
5. Observe the console
Expected: the event on the Button is called once
Reproduced in 2017.1.1p2, 2017.2.0b11, 2017.3.0a7
Did not reproduce in 5.5.4p2, 5.6.3p3, 2017.1.1p1
Regression introduce in 2017.1.1p2
Reproduced on Windows 10
Fixed in 2017.3.0b3
Add comment
All about bugs
View bugs we have successfully reproduced, and vote for the bugs you want to see fixed most urgently.
Latest issues
- UI Source Image property gets set to 'None' when using a specific Sprite and Play mode is entered
- Rendering locks up when not looking at a transparent material on Meta Quest 2
- Volumetrics break when using a Custom Pass to create a Thickness Buffer for Alpha Clipping
- All tests are run instead of only the failed ones when the "Rerun Failed" button is pressed
- GameObject is not masked when the "Render PostProcessing Effects" pass executes with a resolved non-MSAA Color target and MSAA DepthStencil target
m4ko
Nov 28, 2017 13:15
So... we have had a couple new releases since september. Any news on a non-2017.3.X version fix? Anyone working with unity ui can not upgrade AT ALL since 2017.1.1p1 (last version without the bug).
"Fixed in 2017.3.0b3" doesn't help us at all.
jvetulani
Nov 22, 2017 20:43
This is also happening in Unity 2017.30b1 on Linux.
Pixel24
Nov 16, 2017 15:47
Is there a fix for this? I updated to Unity 2017.3b9 and this issue is back!
justdizzy
Oct 31, 2017 18:48
(Removing foot from mouth) I just tried using 2017.1.2p2, and at least in the Editor it seems fixed for me.
justdizzy
Oct 31, 2017 18:15
sigh... one of the (few) reasons I wish I'd stayed with open-source Cocos2d-x; if a bug was found, even if the official build wouldn't include it for a while, I could always fix the code directly in my project.
aliak
Oct 29, 2017 22:03
Oh, Unity just stop it!!! So tired of stupid bugs that cost me a weekend!
It happens to me when onClick has a callback with bool paramenter.
odysoftware
Oct 13, 2017 12:42
Yeah I am curious too. Its interesting that the priority is 2 (must be fixed in next final release). But they haven't done so in 2017.1.1f and even not now in 2017.2... I mean 2017.3 seems to be months ahead - they need to backport it ??
Seb-1814
Oct 13, 2017 11:54
Will this fix be backported to 2017.1 or 2017.2 ?
jeremyburgesspp
Oct 03, 2017 22:02
Hi all who are watching - just thought people suffering from this bug might want to be aware that there's a [dirty] workaround you can apply. The issue in question is that the implementing generically parameterised UnityEvent Invoke methods have a bug in how they iterate their invokable calls (you can see it in the disassembly). A simple way to work around this is to forceably invoke the Invoke method on UnityEventBase passing through the array of args correctly using reflection.
What we did is create an extension method for UnityEvent (but in your case you may need to create equivalents for, for instance UnityEvent<T0, T1> etc...) which does just that (see below). We then subclassed Button, and wholesale replaced all references to Unity UI buttons to ours, by just find/replacing the relevant script reference in all prefab/scene files. How our button's OnClick is shown below.
Note that as the bug is in the UnityEvent types this may or may not be a workable solution for you, and will manifest for all types which make use of UnityEvent (for instance Toggles) - we just only had buttons that we needed to solve.
Extension method:
private static object[] s_unityEventEmptyObjectArray = new object[1]{new object[0]};
private static MethodInfo s_unityEventInvokeMethod = null;
public static void SafeInvoke(this UnityEvent unityEvent)
{
if (s_unityEventInvokeMethod == null)
{
s_unityEventInvokeMethod = unityEvent.GetType().BaseType.GetMethod("Invoke",
BindingFlags.NonPublic | BindingFlags.Instance,
null,
new System.Type[]{typeof(UnityEngine.Object[])},
null);
}
s_unityEventInvokeMethod.Invoke(unityEvent, s_unityEventEmptyObjectArray);
}
Button OnClick method:
public override void OnPointerClick(UnityEngine.EventSystems.PointerEventData eventData)
{
// Don't call base class as onClick.Invoke() calls each thing multiple times
// Early outs...
if (!IsActive () || !IsInteractable ())
{
return;
}
if (eventData.button != UnityEngine.EventSystems.PointerEventData.InputButton.Left)
{
return;
}
// Use our magic method.
onClick.SafeInvoke();
}
Guilherme-Otranto
Oct 03, 2017 16:40
Worth mentioning, it is not just onclick.
I created a simple ExecuteEvent script, which is called by the button.
My hope was to migrate the event to this script and call it from the button. No luck.
So, the "Workaround is possible" is true, but it is a much messier solution than what I initially imagined.