Creating Custom Fixes

Adding fixes to your validators is a huge part of the convenience of the validator. They can be executed at the push of a button for one or more validator entries using the bulk fixing feature.

Let's have a look at a small example. You should be familiar with Validator Types Overview and have gone through at least one of the tutorials mentioned on the page. If you are not, please read that tutorial first.

We will start with the usual boilerplate code.

using Sirenix.OdinInspector.Editor.Validation;

[assembly: RegisterValidationRule(typeof(EmptyStringValidator))]

public class EmptyStringValidator : ValueValidator<string>
{
    protected override void Validate(ValidationResult result)
    {   
        // [...]
    }
}

Next we are going to add our validation logic. In this case, we are making sure that our string is not empty and add a warning to the validator whenever it is.

using Sirenix.OdinInspector.Editor.Validation;

[assembly: RegisterValidationRule(typeof(EmptyStringValidator))]

public class EmptyStringValidator : ValueValidator<string>
{
    protected override void Validate(ValidationResult result)
    {   
        if (string.IsNullOrEmpty(this.Value))
        {
            result.AddWarning("This string is empty! Are you sure that's correct?");
        }
    }
}

But wouldn't it be cool if we could just push a button to set the string and fix our issue? Let's add that next!

using Sirenix.OdinInspector.Editor.Validation;

[assembly: RegisterValidationRule(typeof(EmptyStringValidator))]

public class EmptyStringValidator : ValueValidator<string>
{
    protected override void Validate(ValidationResult result)
    {   
        if (string.IsNullOrEmpty(this.Value))
        {
            result.AddWarning("This string is empty! Are you sure that's correct?")
                .WithFix(() => this.Value = "I'm not empty anymore");
        }
    }
}

That was pretty easy, we just added the .WithFix() method and provided an Action to execute once the execute button is pressed. Right now the fix is fairly rudimentary we probably would like to decide which value to give each individual entry, and we can do so by expanding our example to take an argument which we will be able to set inside the validator window before executing the fix.

using Sirenix.OdinInspector.Editor.Validation;

[assembly: RegisterValidationRule(typeof(EmptyStringValidator))]

public class EmptyStringValidator : ValueValidator<string>
{
    protected override void Validate(ValidationResult result)
    {   
        if (string.IsNullOrEmpty(this.Value))
        {
            result.AddWarning("This string is empty! Are you sure that's correct?")
                .WithFix((FixArgs args) => this.Value = args.NewValue);
        }
    }

    private class FixArgs
    {
        public string NewValue;
    }
}

That was pretty easy as well, we simply added a new class inside our validator which will hold all the arguments we want to pass around. In this case it will just be the new string value we want to set, but it could also be an Enum, List, GameObject, ...

The class must be a non-abstract type with a public parameterless constructor.

Next, we added the argument to our Action and set the value to our new one that was chosen inside the validator window. The resulting fix should now look like this and if we execute it, it should use our argument as the new value.