using Sirenix.OdinInspector.Editor.Validation; using Sirenix.Utilities; using UnityEngine; using VOID.Editor.AttributeValidator; using VOID.Generic.World; [assembly: RegisterValidator(typeof(AreaValidator))] namespace VOID.Editor.AttributeValidator { public class AreaValidator : ValueValidator { protected override void Validate(ValidationResult result) { if (Value == null) return; // Validate only ASSET - skip scene if (!Value.gameObject.scene.path.IsNullOrWhitespace()) return; ValidateIsInComplexAreaPrefab(result); ValidatePosition(result); } private void ValidateIsInComplexAreaPrefab(ValidationResult result) { if (Value.transform.root.gameObject.GetComponent() == null) { result.AddError( $"{nameof(Area)} needs to be placed inside prefab with component {nameof(ComplexArea)}!" ); } } private void ValidatePosition(ValidationResult result) { var complexArea = Value.transform.root.gameObject.GetComponent(); if (!complexArea) return; var relativePosition = complexArea.transform.position - Value.transform.position; var xValid = relativePosition.x % Area.Size < Vector3.kEpsilon; var yValid = relativePosition.y % Area.Size < Vector3.kEpsilon; var zValid = relativePosition.z % Area.Size < Vector3.kEpsilon; if (!xValid || !yValid || !zValid) { result.AddError( $"'{Value.name}' is placed in invalid position." + $"\nRelative position to ComplexArea is {relativePosition} and is not dividable by {Area.Size}!" ); } } } }