feat: object references are now corrected when their target path is renamed/changes (#1323)

This commit is contained in:
bd_ 2024-10-27 10:07:23 -07:00 committed by GitHub
parent 1153abd16e
commit 32ea6678f7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 50 additions and 8 deletions

View File

@ -11,30 +11,51 @@ namespace nadena.dev.modular_avatar.core
{
private static ComputeContext _context;
private static PrefabStage _lastStage;
private static int? _lastStage;
private static int? GetCurrentContentsRootId(out GameObject contentsRoot)
{
contentsRoot = null;
var stage = PrefabStageUtility.GetCurrentPrefabStage();
if (stage == null || stage.prefabContentsRoot == null) return null;
contentsRoot = stage.prefabContentsRoot;
return stage.prefabContentsRoot.GetInstanceID();
}
[InitializeOnLoadMethod]
private static void Init()
{
EditorApplication.delayCall += ProcessObjectReferences;
EditorApplication.update += () =>
{
if (PrefabStageUtility.GetCurrentPrefabStage() != _lastStage) _context?.Invalidate?.Invoke();
var curStage = GetCurrentContentsRootId(out _);
Debug.Log($"{_lastStage} => {curStage}");
if (curStage != _lastStage)
{
_context?.Invalidate?.Invoke();
}
};
}
private static void ProcessObjectReferences()
{
_lastStage = PrefabStageUtility.GetCurrentPrefabStage();
_lastStage = GetCurrentContentsRootId(out var contentsRoot);
AvatarObjectReference.InvalidateAll();
_context = new ComputeContext("ObjectReferenceFixer");
_context.InvokeOnInvalidate<object>(typeof(ObjectReferenceFixer), _ => ProcessObjectReferences());
IEnumerable<IHaveObjReferences> withReferences = _context.GetComponentsByType<IHaveObjReferences>();
if (_lastStage != null)
if (contentsRoot != null)
withReferences =
withReferences.Concat(
_context.GetComponentsInChildren<IHaveObjReferences>(_lastStage.prefabContentsRoot, true)
_context.GetComponentsInChildren<IHaveObjReferences>(contentsRoot, true)
);
foreach (var obj in withReferences)
@ -56,10 +77,26 @@ namespace nadena.dev.modular_avatar.core
foreach (var (targetObject, referencePath, objRef) in references)
{
if (targetObject == null) continue;
_context.ObservePath(targetObject.transform);
var resolvedTarget = objRef.Get(component);
if (objRef.Get(component) == null) continue;
if (targetObject == null)
{
Undo.RecordObject(component, "");
objRef.targetObject = resolvedTarget;
dirty = true;
}
else
{
// Direct object reference always wins in the event of a conflict.
resolvedTarget = targetObject;
}
if (!targetObject.transform.IsChildOf(avatar.transform)) continue;
foreach (var t in _context.ObservePath(resolvedTarget.transform))
{
_context.Observe(t.gameObject, g => g.name);
}
if (!resolvedTarget.transform.IsChildOf(avatar.transform)) continue;
if (objRef.IsConsistent(avatar)) continue;

View File

@ -29,6 +29,11 @@ namespace nadena.dev.modular_avatar.core
EditorApplication.hierarchyChanged += () => HIERARCHY_CHANGED_SEQ += 1;
}
#endif
internal static void InvalidateAll()
{
HIERARCHY_CHANGED_SEQ++;
}
public AvatarObjectReference Clone()
{