init
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
using System.Linq;
|
||||
using Sirenix.OdinInspector.Editor.Validation;
|
||||
using UnityEngine;
|
||||
using VOID.Editor.AttributeValidator;
|
||||
using VOID.ScriptableObjects.Animations;
|
||||
|
||||
[assembly: RegisterValidator(typeof(AnimationListValidator))]
|
||||
|
||||
namespace VOID.Editor.AttributeValidator
|
||||
{
|
||||
public class ActionAnimationListValidator : ValueValidator<ActionAnimationList>
|
||||
{
|
||||
private static readonly string[] SimpleEvents = { "OnStart", "OnPerform", "OnEnd" };
|
||||
|
||||
protected override void Validate(ValidationResult result)
|
||||
{
|
||||
if (Value == null) return;
|
||||
|
||||
ValidateClipEvents(result, Value.list.clip, SimpleEvents);
|
||||
}
|
||||
|
||||
private void ValidateClipEvents(ValidationResult result, AnimationClip clip, string[] neededEvents)
|
||||
{
|
||||
if (!clip) return;
|
||||
|
||||
var currentEvents = clip.events.Select(ev => ev.functionName).ToList();
|
||||
var missingEvents = neededEvents.Except(currentEvents).ToList();
|
||||
var invalidEvents = currentEvents.Except(neededEvents).ToList();
|
||||
var duplicatedEvents = currentEvents.GroupBy(s => s).Where(g => g.Count() > 1).Select(g => g.Key).ToList();
|
||||
|
||||
if (missingEvents.Count > 0)
|
||||
{
|
||||
var missingEventsText = string.Join(" ", missingEvents.Select(str => $"<u>{str}</u>"));
|
||||
result
|
||||
.AddError($"<u>{clip.name}</u> is missing required events: " + missingEventsText)
|
||||
.SetSelectionObject(clip);
|
||||
}
|
||||
|
||||
if (invalidEvents.Count > 0)
|
||||
{
|
||||
var invalidEventsText = string.Join(" ", invalidEvents.Select(str => $"<u>{str}</u>"));
|
||||
result
|
||||
.AddWarning($"<u>{clip.name}</u> contain unknown events: " + invalidEventsText)
|
||||
.SetSelectionObject(clip);
|
||||
}
|
||||
|
||||
if (duplicatedEvents.Count > 0)
|
||||
{
|
||||
var duplicatedEventsText = string.Join(" ", duplicatedEvents.Select(str => $"<u>{str}</u>"));
|
||||
result
|
||||
.AddError($"<u>{clip.name}</u> contain duplicated events: " + duplicatedEventsText)
|
||||
.SetSelectionObject(clip);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d2d25375d33f40e0bb0cf42d99e0ef3e
|
||||
timeCreated: 1719581332
|
||||
@@ -0,0 +1,73 @@
|
||||
using System.Linq;
|
||||
using Sirenix.OdinInspector.Editor.Validation;
|
||||
using UnityEngine;
|
||||
using VOID.Editor.AttributeValidator;
|
||||
using VOID.ScriptableObjects.Animations;
|
||||
|
||||
[assembly: RegisterValidator(typeof(AnimationListValidator))]
|
||||
|
||||
namespace VOID.Editor.AttributeValidator
|
||||
{
|
||||
public class AnimationListValidator : ValueValidator<ActionLoopAnimationList>
|
||||
{
|
||||
private static readonly string[] LoopStartEvents = { "OnStart", "OnLoopStart", "OnPerform" };
|
||||
private static readonly string[] LoopEvents = {};
|
||||
private static readonly string[] LoopEndEvents = { "OnLoopEnd", "OnEnd" };
|
||||
|
||||
protected override void Validate(ValidationResult result)
|
||||
{
|
||||
if (Value == null) return;
|
||||
|
||||
ValidateClipEvents(result, Value.list.startClip, LoopStartEvents);
|
||||
ValidateClipEvents(result, Value.list.loopClip, LoopEvents);
|
||||
ValidateClipEvents(result, Value.list.endClip, LoopEndEvents);
|
||||
ValidateStartEndClips(result);
|
||||
}
|
||||
|
||||
private void ValidateClipEvents(ValidationResult result, AnimationClip clip, string[] neededEvents)
|
||||
{
|
||||
if (!clip) return;
|
||||
|
||||
var currentEvents = clip.events.Select(ev => ev.functionName).ToList();
|
||||
var missingEvents = neededEvents.Except(currentEvents).ToList();
|
||||
var invalidEvents = currentEvents.Except(neededEvents).ToList();
|
||||
var duplicatedEvents = currentEvents.GroupBy(s => s).Where(g => g.Count() > 1).Select(g => g.Key).ToList();
|
||||
|
||||
if (missingEvents.Count > 0)
|
||||
{
|
||||
var missingEventsText = string.Join(" ", missingEvents.Select(str => $"<u>{str}</u>"));
|
||||
result
|
||||
.AddError($"<u>{clip.name}</u> is missing required events: " + missingEventsText)
|
||||
.SetSelectionObject(clip);
|
||||
}
|
||||
|
||||
if (invalidEvents.Count > 0)
|
||||
{
|
||||
var invalidEventsText = string.Join(" ", invalidEvents.Select(str => $"<u>{str}</u>"));
|
||||
result
|
||||
.AddWarning($"<u>{clip.name}</u> contain unknown events: " + invalidEventsText)
|
||||
.SetSelectionObject(clip);
|
||||
}
|
||||
|
||||
if (duplicatedEvents.Count > 0)
|
||||
{
|
||||
var duplicatedEventsText = string.Join(" ", duplicatedEvents.Select(str => $"<u>{str}</u>"));
|
||||
result
|
||||
.AddError($"<u>{clip.name}</u> contain duplicated events: " + duplicatedEventsText)
|
||||
.SetSelectionObject(clip);
|
||||
}
|
||||
}
|
||||
|
||||
private void ValidateStartEndClips(ValidationResult result)
|
||||
{
|
||||
if (!Value.list.startClip && !Value.list.endClip) return;
|
||||
|
||||
var subInfo = $"Both {nameof(Value.list.startClip)} and {nameof(Value.list.endClip)} should exists or be deleted!";
|
||||
if (!Value.list.startClip)
|
||||
result.AddError($"<u>{nameof(Value.list.startClip)}</u> does not exists!\n{subInfo}");
|
||||
|
||||
if (!Value.list.endClip)
|
||||
result.AddError($"<u>{nameof(Value.list.endClip)}</u> does not exists!\n{subInfo}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f202a516ff864e749792bc74d6cc50b0
|
||||
timeCreated: 1743195641
|
||||
@@ -0,0 +1,52 @@
|
||||
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<Area>
|
||||
{
|
||||
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<ComplexArea>() == 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<ComplexArea>();
|
||||
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}!"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1a486a4fce9d4fe1a3d9ca9aa04d29c5
|
||||
timeCreated: 1716645645
|
||||
@@ -0,0 +1,42 @@
|
||||
using System.Linq;
|
||||
using Sirenix.OdinInspector.Editor.Validation;
|
||||
using UnityEngine;
|
||||
using VOID.Editor.AttributeValidator;
|
||||
using VOID.Generic;
|
||||
using VOID.Generic.Triggers;
|
||||
|
||||
[assembly: RegisterValidator(typeof(CameraTriggerValidator))]
|
||||
|
||||
namespace VOID.Editor.AttributeValidator
|
||||
{
|
||||
public class CameraTriggerValidator : ValueValidator<ICameraTrigger>
|
||||
{
|
||||
private Component _component;
|
||||
private GameObject _gameObject;
|
||||
|
||||
protected override void Validate(ValidationResult result)
|
||||
{
|
||||
if (Value is not Component component) return;
|
||||
_component = component;
|
||||
_gameObject = _component.gameObject;
|
||||
|
||||
ValidateLayer(result);
|
||||
ValidateIsTrigger(result);
|
||||
}
|
||||
|
||||
private void ValidateLayer(ValidationResult result)
|
||||
{
|
||||
if (LayerManager.CodeInMask(_component.gameObject.layer, LayerManager.Camera)) return;
|
||||
|
||||
result.AddError($"Layer is not <u>{nameof(LayerManager.Camera)}</u>!");
|
||||
}
|
||||
|
||||
private void ValidateIsTrigger(ValidationResult result)
|
||||
{
|
||||
var isTrigger = _gameObject.GetComponents<Collider>().All(c => c.isTrigger);
|
||||
if (isTrigger) return;
|
||||
|
||||
result.AddError("All <u>Is Trigger</u> in colliders must be set to <u>true</u>!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 548b1cf469c446009821a3734df0d267
|
||||
timeCreated: 1731686163
|
||||
@@ -0,0 +1,66 @@
|
||||
using System.Linq;
|
||||
using Sirenix.OdinInspector.Editor.Validation;
|
||||
using Sirenix.Utilities;
|
||||
using UnityEngine;
|
||||
using VOID.Editor.AttributeValidator;
|
||||
using VOID.Generic.World;
|
||||
|
||||
[assembly: RegisterValidator(typeof(ComplexAreaValidator))]
|
||||
|
||||
namespace VOID.Editor.AttributeValidator
|
||||
{
|
||||
public class ComplexAreaValidator : ValueValidator<ComplexArea>
|
||||
{
|
||||
protected override void Validate(ValidationResult result)
|
||||
{
|
||||
if (Value == null) return;
|
||||
|
||||
// Validate only ASSET - skip scene
|
||||
if (!Value.gameObject.scene.path.IsNullOrWhitespace()) return;
|
||||
|
||||
ValidateIsInRootPrefab(result);
|
||||
ValidatePosition(result);
|
||||
ValidateIsAtLeastOneAreaDefined(result);
|
||||
ValidateAreAllAreasHandled(result);
|
||||
}
|
||||
|
||||
private void ValidateIsInRootPrefab(ValidationResult result)
|
||||
{
|
||||
var prefabRoot = Value.transform.root.gameObject;
|
||||
if (prefabRoot != Value.gameObject)
|
||||
{
|
||||
result.AddError($"{nameof(ComplexArea)} is not in prefab root!");
|
||||
}
|
||||
}
|
||||
|
||||
private void ValidatePosition(ValidationResult result)
|
||||
{
|
||||
if (Value.gameObject.transform.localPosition != Vector3.zero)
|
||||
{
|
||||
result.AddError($"{nameof(ComplexArea)}'s position in prefab must be {Vector3.zero}!");
|
||||
}
|
||||
}
|
||||
|
||||
private void ValidateIsAtLeastOneAreaDefined(ValidationResult result)
|
||||
{
|
||||
var areas = Value.areas;
|
||||
|
||||
if (areas.IsNullOrEmpty())
|
||||
{
|
||||
result.AddError($"{nameof(ComplexArea)} does not have any {nameof(Area)} defined!");
|
||||
}
|
||||
}
|
||||
|
||||
private void ValidateAreAllAreasHandled(ValidationResult result)
|
||||
{
|
||||
var areas = Value.areas;
|
||||
var areasInPrefab = Value.transform.root.GetComponentsInChildren<Area>().ToList();
|
||||
var areasDiff = areasInPrefab.Except(areas).ToList();
|
||||
|
||||
if (!areasDiff.IsNullOrEmpty())
|
||||
{
|
||||
result.AddError($"{nameof(ComplexArea)} does not contain all {nameof(Area)} defined in this prefab!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b8f5c7642b3c44009be0fb9d35dc02b3
|
||||
timeCreated: 1716642064
|
||||
@@ -0,0 +1,53 @@
|
||||
using Sirenix.OdinInspector.Editor.Validation;
|
||||
using Sirenix.Utilities;
|
||||
using VOID.Editor.AttributeValidator;
|
||||
using VOID.Generic.DropTable;
|
||||
using VOID.Generic.Objects.Abstract;
|
||||
using VOID.Generic.Objects.Container;
|
||||
using VOID.Generic.Objects.Unit;
|
||||
|
||||
[assembly: RegisterValidator(typeof(DropTableComponentValidator))]
|
||||
|
||||
namespace VOID.Editor.AttributeValidator
|
||||
{
|
||||
public class DropTableComponentValidator : ValueValidator<DropTableComponent>
|
||||
{
|
||||
protected override void Validate(ValidationResult result)
|
||||
{
|
||||
if (Value == null) return;
|
||||
|
||||
var attachedTo = Value.GetComponent<AbstractObject>();
|
||||
|
||||
IsPlacedWithAbstractObject(result, attachedTo);
|
||||
|
||||
if (attachedTo == null) return;
|
||||
|
||||
CanUseTriggerOnSpawn(result, attachedTo);
|
||||
IsDropTableDefined(result);
|
||||
}
|
||||
|
||||
private void IsPlacedWithAbstractObject(ValidationResult result, AbstractObject attachedTo)
|
||||
{
|
||||
// DropTable's GameObject also needs to have AbstractObject (or its children)
|
||||
if (attachedTo != null) return;
|
||||
|
||||
result.AddError($"{nameof(DropTableComponent)} needs to be placed together with any <u><b>{nameof(AbstractObject)}</b></u>");
|
||||
}
|
||||
|
||||
private void CanUseTriggerOnSpawn(ValidationResult result, AbstractObject attachedTo)
|
||||
{
|
||||
// OnSpawn can be used only with Unit or Container
|
||||
if (Value.trigger is not DropTableTrigger.OnSpawn || attachedTo is UnitObject or ContainerObject) return;
|
||||
|
||||
result.AddError($"{nameof(DropTableComponent)}'s {nameof(Value.trigger)}: <u><b>{Value.trigger}</b></u> can't be used with <u><b>{attachedTo.GetType().GetNiceName()}</b></u>");
|
||||
}
|
||||
|
||||
private void IsDropTableDefined(ValidationResult result)
|
||||
{
|
||||
// DropTable is required!
|
||||
if (Value.dropTable != null) return;
|
||||
|
||||
result.AddError($"{nameof(DropTableComponent)}'s drop table is not defined!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0576c79013184fe3beb6fa3238f90302
|
||||
timeCreated: 1717863063
|
||||
@@ -0,0 +1,26 @@
|
||||
using Sirenix.OdinInspector.Editor.Validation;
|
||||
using Sirenix.Utilities;
|
||||
using VOID.Editor.AttributeValidator;
|
||||
using VOID.Generic.DynamicValue;
|
||||
|
||||
[assembly: RegisterValidator(typeof(DynamicFormulaValidator))]
|
||||
|
||||
namespace VOID.Editor.AttributeValidator
|
||||
{
|
||||
public class DynamicFormulaValidator : ValueValidator<DynamicFormula>
|
||||
{
|
||||
protected override void Validate(ValidationResult result)
|
||||
{
|
||||
if (Value == null) return;
|
||||
|
||||
ValidatePresent(result);
|
||||
}
|
||||
|
||||
private void ValidatePresent(ValidationResult result)
|
||||
{
|
||||
if (!Value.dynamicValue.IsNullOrWhitespace()) return;
|
||||
|
||||
result.AddError("Math formula is empty!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1a7a4957ce3047b69d9a190f18b142c0
|
||||
timeCreated: 1723921186
|
||||
@@ -0,0 +1,18 @@
|
||||
using Sirenix.OdinInspector.Editor.Validation;
|
||||
using VOID.Editor.AttributeValidator;
|
||||
using VOID.Generic.DynamicValue;
|
||||
|
||||
[assembly: RegisterValidator(typeof(DynamicTextValidator))]
|
||||
|
||||
namespace VOID.Editor.AttributeValidator
|
||||
{
|
||||
public class DynamicTextValidator : ValueValidator<DynamicText>
|
||||
{
|
||||
protected override void Validate(ValidationResult result)
|
||||
{
|
||||
if (Value == null) return;
|
||||
|
||||
// TODO: walidacja znaczników
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3cbdf6c4f9bd462dbe91d5cb533628f0
|
||||
timeCreated: 1723838013
|
||||
@@ -0,0 +1,37 @@
|
||||
using Sirenix.OdinInspector.Editor.Validation;
|
||||
using UnityEngine;
|
||||
using VOID.Editor.AttributeValidator;
|
||||
using VOID.Generic;
|
||||
using VOID.Generic.Triggers;
|
||||
|
||||
[assembly: RegisterValidator(typeof(DynamicTriggerValidator))]
|
||||
|
||||
namespace VOID.Editor.AttributeValidator
|
||||
{
|
||||
public class DynamicTriggerValidator : ValueValidator<IDynamicTrigger>
|
||||
{
|
||||
protected override void Validate(ValidationResult result)
|
||||
{
|
||||
if (Value is not Component component) return;
|
||||
|
||||
ValidateLayer(result, component);
|
||||
ValidateCollider(result, component);
|
||||
}
|
||||
|
||||
private void ValidateLayer(ValidationResult result, Component component)
|
||||
{
|
||||
if (LayerManager.CodeInMask(component.gameObject.layer, LayerManager.Trigger)) return;
|
||||
|
||||
result.AddError(
|
||||
$"This component uses <u>{nameof(IDynamicTrigger)}</u> which requires layer <u>{nameof(LayerManager.Trigger)}</u>!");
|
||||
}
|
||||
|
||||
private void ValidateCollider(ValidationResult result, Component component)
|
||||
{
|
||||
if (component.GetComponentInChildren<Collider>()) return;
|
||||
|
||||
result.AddError(
|
||||
$"This component uses <u>{nameof(IDynamicTrigger)}</u> which requires at least one <u>collider</u>!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: edf8c57dfd744b9ca332155888b9677d
|
||||
timeCreated: 1731687244
|
||||
@@ -0,0 +1,32 @@
|
||||
using System.Linq;
|
||||
using Sirenix.OdinInspector.Editor.Validation;
|
||||
using UnityEngine;
|
||||
using VOID.Editor.AttributeValidator;
|
||||
using VOID.Generic;
|
||||
using VOID.Generic.Triggers;
|
||||
|
||||
[assembly: RegisterValidator(typeof(HideCeilingTriggerValidator))]
|
||||
|
||||
namespace VOID.Editor.AttributeValidator
|
||||
{
|
||||
public class HideCeilingTriggerValidator : ValueValidator<HideCeilingTrigger>
|
||||
{
|
||||
protected override void Validate(ValidationResult result)
|
||||
{
|
||||
if (Value == null) return;
|
||||
|
||||
ValidateHideableLayer(result);
|
||||
}
|
||||
|
||||
private void ValidateHideableLayer(ValidationResult result)
|
||||
{
|
||||
var isWrongLayer = Value.gameObjectsToHide.SelectMany(go => go.GetComponentsInChildren<Transform>())
|
||||
.Select(transform => transform.gameObject.layer)
|
||||
.Any(layer => layer != LayerManager.StaticHideableIndex);
|
||||
|
||||
if (!isWrongLayer) return;
|
||||
|
||||
result.AddError($"All hideable objects targeted by this components needs layer <u>{nameof(LayerManager.StaticHideable)}</u>");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b19a84b828dc44d19acc91a3562527f6
|
||||
timeCreated: 1747502208
|
||||
@@ -0,0 +1,25 @@
|
||||
using InfinityPBR.ModularCharacterHelper;
|
||||
using Sirenix.OdinInspector.Editor.Validation;
|
||||
using VOID.Editor.AttributeValidator;
|
||||
|
||||
[assembly: RegisterValidator(typeof(ModularCharacterValidator))]
|
||||
|
||||
namespace VOID.Editor.AttributeValidator
|
||||
{
|
||||
public class ModularCharacterValidator : ValueValidator<ModularCharacter>
|
||||
{
|
||||
protected override void Validate(ValidationResult result)
|
||||
{
|
||||
if (Value == null) return;
|
||||
|
||||
ValidateBoneRoot(result);
|
||||
}
|
||||
|
||||
private void ValidateBoneRoot(ValidationResult result)
|
||||
{
|
||||
if (Value.targetRootBone) return;
|
||||
|
||||
result.AddError($"<b>{nameof(Value.targetRootBone)}</b> is required!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2174b4dd14e6457f91bf2752538551b6
|
||||
timeCreated: 1724879981
|
||||
@@ -0,0 +1,33 @@
|
||||
using InfinityPBR.ModularCharacterHelper;
|
||||
using Sirenix.OdinInspector.Editor.Validation;
|
||||
using VOID.Editor.AttributeValidator;
|
||||
|
||||
[assembly: RegisterValidator(typeof(ModularPartValidator))]
|
||||
|
||||
namespace VOID.Editor.AttributeValidator
|
||||
{
|
||||
public class ModularPartValidator : ValueValidator<ModularPart>
|
||||
{
|
||||
protected override void Validate(ValidationResult result)
|
||||
{
|
||||
if (Value == null) return;
|
||||
|
||||
ValidateBoneRoot(result);
|
||||
ValidateSkinnedRenderer(result);
|
||||
}
|
||||
|
||||
private void ValidateBoneRoot(ValidationResult result)
|
||||
{
|
||||
if (Value.boneRoot) return;
|
||||
|
||||
result.AddError($"<b>{nameof(Value.boneRoot)}</b> is required!");
|
||||
}
|
||||
|
||||
private void ValidateSkinnedRenderer(ValidationResult result)
|
||||
{
|
||||
if (Value.skinnedMeshRenderer) return;
|
||||
|
||||
result.AddError($"<b>{nameof(Value.skinnedMeshRenderer)}</b> is required!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b10c2b7729514d839a70884069ed6c0e
|
||||
timeCreated: 1724870308
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3f58b0acec154c95a69320f5a8c74317
|
||||
timeCreated: 1725482081
|
||||
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using Sirenix.OdinInspector;
|
||||
using Sirenix.OdinInspector.Editor;
|
||||
using Sirenix.OdinInspector.Editor.Validation;
|
||||
using Sirenix.Utilities;
|
||||
using UnityEngine;
|
||||
using VOID.Editor.AttributeValidator.Objects;
|
||||
using VOID.Generic.Objects.Abstract;
|
||||
|
||||
[assembly: RegisterValidator(typeof(AbstractObjectValidator))]
|
||||
|
||||
namespace VOID.Editor.AttributeValidator.Objects
|
||||
{
|
||||
public class AbstractObjectValidator : ValueValidator<AbstractObject>
|
||||
{
|
||||
protected override void Validate(ValidationResult result)
|
||||
{
|
||||
if (Value == null) return;
|
||||
if (OdinPrefabUtility.GetPrefabKind(Value.gameObject) is not PrefabKind.Regular) return;
|
||||
|
||||
IsComponentOrderValid(result);
|
||||
}
|
||||
|
||||
private void IsComponentOrderValid(ValidationResult result)
|
||||
{
|
||||
var components = Value.gameObject.GetComponents<Component>();
|
||||
var abstractObjectIndex = Array.FindIndex(components, component => component is AbstractObject);
|
||||
|
||||
// *Object is first (or right after Transform)
|
||||
if (abstractObjectIndex <= 1) return;
|
||||
|
||||
result.AddError($"{Value.GetType().GetNiceName()} should be first component (right after Transform)")
|
||||
.WithFix(() =>
|
||||
{
|
||||
for (var i = 0; i < abstractObjectIndex - 1; i++)
|
||||
UnityEditorInternal.ComponentUtility.MoveComponentUp(components[abstractObjectIndex]);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d353447115784aa3806a3b1582e00469
|
||||
timeCreated: 1744384089
|
||||
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Sirenix.OdinInspector;
|
||||
using Sirenix.OdinInspector.Editor;
|
||||
using Sirenix.OdinInspector.Editor.Validation;
|
||||
using Sirenix.Utilities;
|
||||
using UnityEngine;
|
||||
using VOID.Editor.AttributeValidator.Objects;
|
||||
using VOID.Generic.Objects.Item;
|
||||
using VOID.Generic.Objects.Usable;
|
||||
|
||||
[assembly: RegisterValidator(typeof(ItemObjectDataValidator))]
|
||||
|
||||
namespace VOID.Editor.AttributeValidator.Objects
|
||||
{
|
||||
public class ItemObjectDataValidator : ValueValidator<ItemObjectData>
|
||||
{
|
||||
protected override void Validate(ValidationResult result)
|
||||
{
|
||||
if (Value == null) return;
|
||||
if (Property.Parent.ValueEntry.WeakSmartValue is not ItemObject itemObject) return;
|
||||
if (OdinPrefabUtility.GetPrefabKind(itemObject.gameObject) is not PrefabKind.Regular) return;
|
||||
|
||||
IsStackableValid(result);
|
||||
}
|
||||
|
||||
private void IsStackableValid(ValidationResult result)
|
||||
{
|
||||
var allowedTypes = new List<Type> { typeof(ItemObject), typeof(UsableObject) };
|
||||
if (!Value.stackable || allowedTypes.Contains(Property.ParentType)) return;
|
||||
|
||||
var allowedTypeNames = string.Join(", ", allowedTypes.Select(t => t.GetNiceName()).ToList());
|
||||
result.AddError($"Stackable can be TRUE only for objects of type: {allowedTypeNames}")
|
||||
.WithFix(() => Value.stackable = false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 665bab4b4bfc4f829cb3b4738084cdde
|
||||
timeCreated: 1744214861
|
||||
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Sirenix.OdinInspector.Editor.Validation;
|
||||
using VOID.Editor.AttributeValidator.Objects;
|
||||
using VOID.Generic.Dict;
|
||||
using VOID.Generic.Objects.Unit;
|
||||
|
||||
[assembly: RegisterValidator(typeof(UnitObjectEquipmentValidator))]
|
||||
|
||||
namespace VOID.Editor.AttributeValidator.Objects
|
||||
{
|
||||
public class UnitObjectEquipmentValidator : ValueValidator<UnitObjectEquipment>
|
||||
{
|
||||
protected override void Validate(ValidationResult result)
|
||||
{
|
||||
if (Value == null) return;
|
||||
|
||||
AreValidWearablesPlaced(result);
|
||||
}
|
||||
|
||||
private void AreValidWearablesPlaced(ValidationResult result)
|
||||
{
|
||||
foreach (var slotType in Enum.GetValues(typeof(EquipmentSlotType)).Cast<EquipmentSlotType>())
|
||||
{
|
||||
var wearable = Value.GetEquipped(slotType);
|
||||
if (wearable == null) return;
|
||||
|
||||
// Wrong type of wearable placed in this slot
|
||||
if (Value.CanEquipInSlot(slotType, wearable) == false)
|
||||
result.AddError($"<u><b>{wearable.name}</b></u> can't be placed in <u><b>{slotType}</b></u> slot!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: edb7019ba7024f92b3aad84d20f3431b
|
||||
timeCreated: 1718794692
|
||||
@@ -0,0 +1,15 @@
|
||||
using Sirenix.OdinInspector.Editor.Validation;
|
||||
using VOID.Editor.AttributeValidator;
|
||||
|
||||
[assembly: RegisterValidator(typeof(SceneReferenceValidator))]
|
||||
|
||||
namespace VOID.Editor.AttributeValidator
|
||||
{
|
||||
public class SceneReferenceValidator : ValueValidator<SceneReference>
|
||||
{
|
||||
protected override void Validate(ValidationResult result)
|
||||
{
|
||||
if (ValueEntry.SmartValue == "") result.AddError(Property.NiceName + " is required");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0c3223426e38404fb5bea6a8db202522
|
||||
timeCreated: 1730239681
|
||||
Reference in New Issue
Block a user