OnValueChanged invoked multiple times if the value is modified from within code during the OnValueChanged callback

Issue #605 new
Ryan created an issue

System Info

Unity: 2018.3.8f1

Odin: 2.1.5

Editor Only: Yes

OS: OSX Catalina 10.15

What happened

I have a dropdown with an OnValueChanged listener. I want to be able to revert the value if the user picks a “bad” value from the dropdown.

If I check the value from within the OnValueChanged listener, and attempt to set it to its previous value, OnValueChanged is invoked twice AND my variable is set back to the value the user selected. Strangely, if I set the value of the variable in this second pass, the value is updated correctly.

This MonoBehaviour below replicates the behavior. Select any value besides “BadValue” in the dropdown, then attempt to select “BadValue”. Note that OnValueChanged is logged twice.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Sirenix.OdinInspector;

public class DropdownRevertingBug : MonoBehaviour
{
    public List<string> DropdownValues = new List<string>()
    {
        "A",
        "B",
        "C",
        "BadValue"
    };

    private string _DropdownOldValue;

    [ValueDropdown(nameof(DropdownValues)), OnValueChanged(nameof(DropdownChanged))]
    public string Dropdown = "A";

    public void DropdownChanged()
    {
        Debug.Log("OnValueChanged");
        if (Dropdown.Equals("BadValue"))
        {
            Dropdown = _DropdownOldValue;
        }

        _DropdownOldValue = Dropdown;
    }

    [Button("Set to A")]
    public void AssignDropdownValue()
    {
        Dropdown = DropdownValues[0];
    }
}

Expected Behavior

The value is set to whatever value is assigned to it the first time in the callback and not modified by the editor thereafter. OnValueChanged is invoked once.

Comments (2)

  1. Lans

    If you put a return after resetting to the previous value, to make sure the old value is not updated to the bad value you can fix the problem in this case.

    Perhaps you could seperate the Dropdown value from a value that you can change in code without calling the OnValueChanged whenever that is changed?

  2. Ryan reporter

    The problem I’m reporting is that the callback is run twice. Any error handling logic I have when the user selects a bad value is run twice. For example, I pop up a dialog box in my editor if the user selects “BadValue”, meaning that unless I add code to detect that this bug has happened, the user sees this dialog twice. I’d rather that code not be there.

    Regarding separating the dropdown value, I’d rather not write code that separates my view from my data. I use Odin so I don’t have to do that.

  3. Log in to comment