Is there a way to check if any changes were made? #146
-
I'm working on my own inspector extension which also overrides the default MonoBehaviour editor like so:
This works fine and all but of course Tri Inspector will stop working if this editor exists. There's an option to disable my editor but then it won't do the Synchronize() step as it should. Is there a way (if TriEditor compatibility is required) to register a global validation method for ALL properties, or some sort of way to achieve this via inheriting from the TriEditor? I'm not very familiar with VisualElements at all, and I haven't found something that works yet. I'd like for a user to be able to use both these libraries if they wish to do so. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
One of the ways is to create a validator that will add a synchronization button source codeusing System.Linq;
using System.Reflection;
using TriInspector;
using UnityEngine;
[assembly: RegisterTriValueValidator(typeof(OutOfSyncValidator))]
public class OutOfSyncValidator : TriValueValidator<MonoBehaviour>
{
public override TriExtensionInitializationResult Initialize(TriPropertyDefinition propertyDefinition)
{
var isRoot = propertyDefinition.OwnerType == null;
return isRoot ? TriExtensionInitializationResult.Ok : TriExtensionInitializationResult.Skip;
}
public override TriValidationResult Validate(TriValue<MonoBehaviour> propertyValue)
{
var mb = propertyValue.SmartValue;
var expectedHash = CalcHash(mb).ToString();
var actualHash = mb.gameObject.name;
if (actualHash != expectedHash)
{
return TriValidationResult.Error("Name is out of sync")
.WithFix(() => mb.gameObject.name = expectedHash, "Synchronize");
}
return TriValidationResult.Valid;
}
private static int CalcHash(MonoBehaviour mb)
{
return mb.GetType()
.GetFields(BindingFlags.Instance | BindingFlags.Public)
.Sum(fi => fi.GetValue(mb)?.GetHashCode() ?? 0);
}
} You can also create your own drawer that will do automatic synchronization source codeusing System.Linq;
using System.Reflection;
using TriInspector;
using UnityEngine;
[assembly: RegisterTriValueDrawer(typeof(OutOfSyncAutoFixDrawer), TriDrawerOrder.Decorator)]
public class OutOfSyncAutoFixDrawer : TriValueDrawer<MonoBehaviour>
{
public override TriExtensionInitializationResult Initialize(TriPropertyDefinition propertyDefinition)
{
var isRoot = propertyDefinition.OwnerType == null;
return isRoot ? TriExtensionInitializationResult.Ok : TriExtensionInitializationResult.Skip;
}
public override TriElement CreateElement(TriValue<MonoBehaviour> propertyValue, TriElement next)
{
var element = new OutOfSyncFixElement(propertyValue.Property);
element.AddChild(next);
return element;
}
private class OutOfSyncFixElement : TriElement
{
private readonly TriProperty _rootProperty;
public OutOfSyncFixElement(TriProperty property)
{
_rootProperty = property;
}
protected override void OnAttachToPanel()
{
base.OnAttachToPanel();
_rootProperty.ChildValueChanged += OnValueChanged;
}
protected override void OnDetachFromPanel()
{
_rootProperty.ChildValueChanged -= OnValueChanged;
base.OnDetachFromPanel();
}
private void OnValueChanged(TriProperty changedProperty)
{
_rootProperty.PropertyTree.ApplyChanges();
for (var targetIndex = 0; targetIndex < _rootProperty.PropertyTree.TargetsCount; targetIndex++)
{
var mb = (MonoBehaviour) _rootProperty.GetValue(targetIndex);
mb.gameObject.name = CalcHash(mb).ToString();
}
_rootProperty.PropertyTree.Update();
}
private static int CalcHash(MonoBehaviour mb)
{
return mb.GetType()
.GetFields(BindingFlags.Instance | BindingFlags.Public)
.Sum(fi => fi.GetValue(mb)?.GetHashCode() ?? 0);
}
}
} |
Beta Was this translation helpful? Give feedback.
One of the ways is to create a validator that will add a synchronization button
source code