Community Made Tools

Have you made any useful utilities with Odin?

Login and submit your creations here

Required On Scene Attribute

Authored by Lucas
Shared 30-01-2020

This is a simple attribute to require a field to de present (valid) only when it is on a scene context. If the field is in a prefab, or in prefab mode, it will be considered valid even if it is null.

Usage

public class SomeScript : MonoBehaviour { [RequiredOnScene] public int SomeInt; }

RequiredOnSceneAttribute.cs

using System; namespace Odin { [AttributeUsage(AttributeTargets.Field)] public class RequiredOnSceneAttribute : Attribute { // ReSharper disable once UnassignedField.Global public string ErrorMessage; } }

RequiredOnSceneAttributeValidator.cs

using System; using System.Reflection; using Odin.Editor; using Sirenix.OdinInspector.Editor; using Sirenix.OdinInspector.Editor.Validation; using UnityEditor.Experimental.SceneManagement; using UnityEngine; using Object = UnityEngine.Object; [assembly: RegisterValidator(typeof(RequiredOnSceneAttributeValidator))] namespace Odin.Editor { public class RequiredOnSceneAttributeValidator : AttributeValidator<RequiredOnSceneAttribute> { private StringMemberHelper stringHelper; public override void Initialize(MemberInfo member, Type memberValueType) { if (this.Attribute.ErrorMessage != null) { this.stringHelper = new StringMemberHelper(member.ReflectedType, false, this.Attribute.ErrorMessage); } } protected override void Validate(object parentInstance, object memberValue, MemberInfo member, ValidationResult result) { if (!(parentInstance is MonoBehaviour)) return; MonoBehaviour parent = (MonoBehaviour) parentInstance; GameObject sourceObject = parent.gameObject; bool isInPrefabMode = PrefabStageUtility.GetPrefabStage(sourceObject) != null; bool memberValid = IsValid(memberValue); var scene = sourceObject.scene; bool validScene = scene.IsValid() && scene.isLoaded; bool valid = isInPrefabMode || memberValid || !validScene; if (valid) return; result.ResultType = ValidationResultType.Error; result.Message = stringHelper != null ? stringHelper.GetString(parentInstance) : member.Name+" is required on scene!"; } private static bool IsValid(object memberValue) { switch (memberValue) { case null: case string value when string.IsNullOrEmpty(value): case Object o when o == null: return false; default: return true; } } } }