mirror of
https://github.com/bdunderscore/modular-avatar.git
synced 2025-05-14 07:09:09 +08:00
fixing issues with error reporting and dependent component cleanup
This commit is contained in:
parent
eaf01d8c31
commit
6ba3f95177
@ -23,8 +23,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using nadena.dev.modular_avatar.editor.ErrorReporting;
|
using nadena.dev.modular_avatar.editor.ErrorReporting;
|
||||||
@ -147,78 +149,120 @@ namespace nadena.dev.modular_avatar.core.editor
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
AssetDatabase.StartAssetEditing();
|
try
|
||||||
nowProcessing = true;
|
|
||||||
|
|
||||||
ClearEditorOnlyTagComponents(avatarGameObject.transform);
|
|
||||||
|
|
||||||
BoneDatabase.ResetBones();
|
|
||||||
PathMappings.Init(vrcAvatarDescriptor.gameObject);
|
|
||||||
ClonedMenuMappings.Clear();
|
|
||||||
|
|
||||||
// Sometimes people like to nest one avatar in another, when transplanting clothing. To avoid issues
|
|
||||||
// with inconsistently determining the avatar root, we'll go ahead and remove the extra sub-avatars
|
|
||||||
// here.
|
|
||||||
foreach (Transform directChild in avatarGameObject.transform)
|
|
||||||
{
|
{
|
||||||
foreach (var component in directChild.GetComponentsInChildren<VRCAvatarDescriptor>(true))
|
AssetDatabase.StartAssetEditing();
|
||||||
|
nowProcessing = true;
|
||||||
|
|
||||||
|
ClearEditorOnlyTagComponents(avatarGameObject.transform);
|
||||||
|
|
||||||
|
BoneDatabase.ResetBones();
|
||||||
|
PathMappings.Init(vrcAvatarDescriptor.gameObject);
|
||||||
|
ClonedMenuMappings.Clear();
|
||||||
|
|
||||||
|
// Sometimes people like to nest one avatar in another, when transplanting clothing. To avoid issues
|
||||||
|
// with inconsistently determining the avatar root, we'll go ahead and remove the extra sub-avatars
|
||||||
|
// here.
|
||||||
|
foreach (Transform directChild in avatarGameObject.transform)
|
||||||
{
|
{
|
||||||
Object.DestroyImmediate(component);
|
foreach (var component in directChild.GetComponentsInChildren<VRCAvatarDescriptor>(true))
|
||||||
|
{
|
||||||
|
Object.DestroyImmediate(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var component in directChild.GetComponentsInChildren<PipelineSaver>(true))
|
||||||
|
{
|
||||||
|
Object.DestroyImmediate(component);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var component in directChild.GetComponentsInChildren<PipelineSaver>(true))
|
var context = new BuildContext(vrcAvatarDescriptor);
|
||||||
{
|
|
||||||
Object.DestroyImmediate(component);
|
new ActionGenerator(context).OnPreprocessAvatar(vrcAvatarDescriptor);
|
||||||
}
|
new RenameParametersHook().OnPreprocessAvatar(avatarGameObject, context);
|
||||||
|
new MergeAnimatorProcessor().OnPreprocessAvatar(avatarGameObject, context);
|
||||||
|
context.AnimationDatabase.Bootstrap(vrcAvatarDescriptor);
|
||||||
|
|
||||||
|
new MenuInstallHook().OnPreprocessAvatar(avatarGameObject, context);
|
||||||
|
new MergeArmatureHook().OnPreprocessAvatar(context, avatarGameObject);
|
||||||
|
new BoneProxyProcessor().OnPreprocessAvatar(avatarGameObject);
|
||||||
|
new VisibleHeadAccessoryProcessor(vrcAvatarDescriptor).Process(context);
|
||||||
|
new RemapAnimationPass(vrcAvatarDescriptor).Process(context.AnimationDatabase);
|
||||||
|
new BlendshapeSyncAnimationProcessor().OnPreprocessAvatar(avatarGameObject, context);
|
||||||
|
PhysboneBlockerPass.Process(avatarGameObject);
|
||||||
|
|
||||||
|
context.AnimationDatabase.Commit();
|
||||||
|
|
||||||
|
new GCGameObjectsPass(context, avatarGameObject).OnPreprocessAvatar();
|
||||||
|
|
||||||
|
AfterProcessing?.Invoke(avatarGameObject);
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
AssetDatabase.StopAssetEditing();
|
||||||
|
|
||||||
var context = new BuildContext(vrcAvatarDescriptor);
|
nowProcessing = false;
|
||||||
|
|
||||||
new ActionGenerator(context).OnPreprocessAvatar(vrcAvatarDescriptor);
|
// Ensure that we clean up AvatarTagComponents after failed processing. This ensures we don't re-enter
|
||||||
new RenameParametersHook().OnPreprocessAvatar(avatarGameObject, context);
|
// processing from the Awake method on the unprocessed AvatarTagComponents
|
||||||
new MergeAnimatorProcessor().OnPreprocessAvatar(avatarGameObject, context);
|
var toDestroy = avatarGameObject.GetComponentsInChildren<AvatarTagComponent>(true).ToList();
|
||||||
context.AnimationDatabase.Bootstrap(vrcAvatarDescriptor);
|
var retryDestroy = new List<AvatarTagComponent>();
|
||||||
|
|
||||||
new MenuInstallHook().OnPreprocessAvatar(avatarGameObject, context);
|
// Sometimes AvatarTagComponents have interdependencies and need to be deleted in the right order;
|
||||||
new MergeArmatureHook().OnPreprocessAvatar(context, avatarGameObject);
|
// retry until we purge them all.
|
||||||
new BoneProxyProcessor().OnPreprocessAvatar(avatarGameObject);
|
bool madeProgress = true;
|
||||||
new VisibleHeadAccessoryProcessor(vrcAvatarDescriptor).Process(context);
|
while (toDestroy.Count > 0)
|
||||||
new RemapAnimationPass(vrcAvatarDescriptor).Process(context.AnimationDatabase);
|
{
|
||||||
new BlendshapeSyncAnimationProcessor().OnPreprocessAvatar(avatarGameObject, context);
|
if (!madeProgress)
|
||||||
PhysboneBlockerPass.Process(avatarGameObject);
|
{
|
||||||
|
throw new Exception("One or more components failed to destroy." +
|
||||||
|
RuntimeUtil.AvatarRootPath(toDestroy[0].gameObject));
|
||||||
|
}
|
||||||
|
|
||||||
context.AnimationDatabase.Commit();
|
foreach (var component in toDestroy)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (component != null)
|
||||||
|
{
|
||||||
|
UnityEngine.Object.DestroyImmediate(component);
|
||||||
|
madeProgress = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
retryDestroy.Add(component);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
new GCGameObjectsPass(context, avatarGameObject).OnPreprocessAvatar();
|
toDestroy = retryDestroy;
|
||||||
|
retryDestroy = new List<AvatarTagComponent>();
|
||||||
|
}
|
||||||
|
|
||||||
AfterProcessing?.Invoke(avatarGameObject);
|
var activator = avatarGameObject.GetComponent<AvatarActivator>();
|
||||||
|
if (activator != null)
|
||||||
|
{
|
||||||
|
UnityEngine.Object.DestroyImmediate(activator);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClonedMenuMappings.Clear();
|
||||||
|
|
||||||
|
ErrorReportUI.MaybeOpenErrorReportUI();
|
||||||
|
|
||||||
|
AssetDatabase.SaveAssets();
|
||||||
|
|
||||||
|
Resources.UnloadUnusedAssets();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
finally
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
AssetDatabase.StopAssetEditing();
|
BuildReport.LogException(e);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
nowProcessing = false;
|
if (!BuildReport.CurrentReport.CurrentAvatar.successful)
|
||||||
|
{
|
||||||
// Ensure that we clean up AvatarTagComponents after failed processing. This ensures we don't re-enter
|
throw new Exception("Fatal error reported during avatar processing.");
|
||||||
// processing from the Awake method on the unprocessed AvatarTagComponents
|
|
||||||
foreach (var component in avatarGameObject.GetComponentsInChildren<AvatarTagComponent>(true))
|
|
||||||
{
|
|
||||||
UnityEngine.Object.DestroyImmediate(component);
|
|
||||||
}
|
|
||||||
|
|
||||||
var activator = avatarGameObject.GetComponent<AvatarActivator>();
|
|
||||||
if (activator != null)
|
|
||||||
{
|
|
||||||
UnityEngine.Object.DestroyImmediate(activator);
|
|
||||||
}
|
|
||||||
|
|
||||||
ClonedMenuMappings.Clear();
|
|
||||||
|
|
||||||
ErrorReportUI.MaybeOpenErrorReportUI();
|
|
||||||
|
|
||||||
AssetDatabase.SaveAssets();
|
|
||||||
|
|
||||||
Resources.UnloadUnusedAssets();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user