[RequiredLocalizedString] Require LocalizedString Table and Entry Assignment

ENOSI Studio

When developing a game in Unity, LocalizedString fields often need to have both a localization table and entry assigned. However, Odin Inspector’s [Required] attribute does not validate LocalizedString references by default.

My solution? A custom [RequiredLocalStr] attribute that detects empty or unassigned LocalizedString references directly in the Inspector.

The attribute helps to prevent localization errors caused by unassigned tables or entries.

Prerequisite

  • Odin Inspector

1. Creating the Attribute Class

C#
using System;

namespace Enosi.Core.Validators.Attributes
{

[RequiredLocalizedString]    

    [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
    public class RequiredLocalizedStringAttribute : Attribute { }
}

2. Creating the Drawer Class

C#
#if UNITY_EDITOR
using Enosi.Core.Validators.Attributes;
using Sirenix.OdinInspector.Editor;
using Sirenix.Utilities.Editor;
using UnityEngine;
using UnityEngine.Localization;

namespace Enosi.Core.Validators.Drawer
{
    [DrawerPriority(1, 1, 1)]
    public class RequiredLocalStrDrawer : OdinAttributeDrawer<RequiredLocalizedStringAttribute, LocalizedString>
    {
        protected override void DrawPropertyLayout(GUIContent label)
        {
            CallNextDrawer(label);

            LocalizedString value = ValueEntry.SmartValue;
            if (value == null || value.IsEmpty)
                SirenixEditorGUI.ErrorMessageBox($"{label?.text ?? Property.NiceName} : Unassigned LocalizedString (table or entry).");
        }
    }
}
#endif

3. Usage

Example of attribute usage:

C#
public class Example : MonoBehaviour 
{
    [RequiredLocalizedString] 
    public LocalizedString myLocalStr;
}

How does [RequiredLocalStr] work?

[RequiredLocalStr] is implemented as an Odin OdinAttributeDrawer targeting the LocalizedString type. The custom drawer overrides DrawPropertyLayout() and first calls CallNextDrawer(label) to render the default Inspector field.

It then retrieves the current value through ValueEntry.SmartValue and checks whether the LocalizedString is null or IsEmpty. If either condition is true, SirenixEditorGUI.ErrorMessageBox() displays a validation error directly below the field.

Conclusion

[RequiredLocalStr] provides a simple way to ensure required LocalizedString references are properly assigned, helping prevent missing localization data before runtime.


– MARTIN B