mirror of
https://github.com/bdunderscore/modular-avatar.git
synced 2025-01-01 20:25:07 +08:00
chore: automatically save assets referenced at the end of processing
This commit is contained in:
parent
dec90cb6ca
commit
7ce6d93083
@ -31,8 +31,6 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
private Dictionary<string, HashSet<ClipHolder>> _pathToClip =
|
||||
new Dictionary<string, HashSet<ClipHolder>>();
|
||||
|
||||
private HashSet<BlendTree> _processedBlendTrees = new HashSet<BlendTree>();
|
||||
|
||||
internal void Commit()
|
||||
{
|
||||
foreach (var clip in _clips)
|
||||
@ -115,11 +113,10 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
// Protect the original animations from mutations by creating temporary clones; in the case of a proxy
|
||||
// animation, we'll restore the original in a later pass
|
||||
var placeholder = Object.Instantiate(state.motion);
|
||||
AssetDatabase.AddObjectToAsset(placeholder, state);
|
||||
clipHolder.CurrentClip = placeholder;
|
||||
if (isProxyAnim)
|
||||
{
|
||||
_clipCommitActions.Add(() => { Object.DestroyImmediate(placeholder, true); });
|
||||
_clipCommitActions.Add(() => { Object.DestroyImmediate(placeholder); });
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,16 +174,6 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
processClip(holder);
|
||||
recordPaths(holder);
|
||||
_clips.Add(holder);
|
||||
_clipCommitActions.Add(() =>
|
||||
{
|
||||
if (holder.CurrentClip != holder.OriginalClip)
|
||||
{
|
||||
if (string.IsNullOrEmpty(AssetDatabase.GetAssetPath(holder.CurrentClip)))
|
||||
{
|
||||
AssetDatabase.AddObjectToAsset(holder.CurrentClip, AssetDatabase.GetAssetPath(state));
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
case BlendTree tree:
|
||||
@ -260,10 +247,6 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
{
|
||||
children[i].motion = curClip;
|
||||
dirty = true;
|
||||
if (string.IsNullOrWhiteSpace(AssetDatabase.GetAssetPath(curClip)))
|
||||
{
|
||||
AssetDatabase.AddObjectToAsset(curClip, AssetDatabase.GetAssetPath(state));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
internal class AnimatorCombiner
|
||||
{
|
||||
private readonly AnimatorController _combined;
|
||||
private bool isSaved;
|
||||
|
||||
private AnimatorOverrideController _overrideController;
|
||||
|
||||
@ -55,9 +56,11 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
|
||||
private int controllerBaseLayer = 0;
|
||||
|
||||
public AnimatorCombiner(BuildContext context)
|
||||
public AnimatorCombiner(BuildContext context, String assetName)
|
||||
{
|
||||
_combined = context.CreateAnimator();
|
||||
isSaved = !string.IsNullOrEmpty(AssetDatabase.GetAssetPath(_combined));
|
||||
_combined.name = assetName;
|
||||
}
|
||||
|
||||
public AnimatorController Finish()
|
||||
@ -289,7 +292,10 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
|
||||
AnimationClip newClip = new AnimationClip();
|
||||
newClip.name = "rebased " + clip.name;
|
||||
if (isSaved)
|
||||
{
|
||||
AssetDatabase.AddObjectToAsset(newClip, _combined);
|
||||
}
|
||||
|
||||
foreach (var binding in AnimationUtility.GetCurveBindings(clip))
|
||||
{
|
||||
@ -396,7 +402,10 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
|
||||
cloneMap[original] = obj;
|
||||
|
||||
if (isSaved)
|
||||
{
|
||||
AssetDatabase.AddObjectToAsset(obj, _combined);
|
||||
}
|
||||
|
||||
SerializedObject so = new SerializedObject(obj);
|
||||
SerializedProperty prop = so.GetIterator();
|
||||
|
@ -211,11 +211,15 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
new BlendshapeSyncAnimationProcessor().OnPreprocessAvatar(avatarGameObject, context);
|
||||
PhysboneBlockerPass.Process(avatarGameObject);
|
||||
|
||||
context.CommitReferencedAssets();
|
||||
|
||||
AfterProcessing?.Invoke(avatarGameObject, context);
|
||||
|
||||
context.AnimationDatabase.Commit();
|
||||
|
||||
new GCGameObjectsPass(context, avatarGameObject).OnPreprocessAvatar();
|
||||
|
||||
context.CommitReferencedAssets();
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Animations;
|
||||
@ -16,6 +17,8 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
internal readonly AnimationDatabase AnimationDatabase = new AnimationDatabase();
|
||||
internal readonly UnityEngine.Object AssetContainer;
|
||||
|
||||
private bool SaveImmediate = false;
|
||||
|
||||
internal readonly Dictionary<VRCExpressionsMenu, VRCExpressionsMenu> ClonedMenus
|
||||
= new Dictionary<VRCExpressionsMenu, VRCExpressionsMenu>();
|
||||
|
||||
@ -41,7 +44,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
|
||||
public void SaveAsset(Object obj)
|
||||
{
|
||||
if (AssetDatabase.IsMainAsset(obj) || AssetDatabase.IsSubAsset(obj)) return;
|
||||
if (!SaveImmediate || AssetDatabase.IsMainAsset(obj) || AssetDatabase.IsSubAsset(obj)) return;
|
||||
|
||||
AssetDatabase.AddObjectToAsset(obj, AssetContainer);
|
||||
}
|
||||
@ -67,7 +70,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
{
|
||||
if (controller == null) return null;
|
||||
|
||||
var merger = new AnimatorCombiner(this);
|
||||
var merger = new AnimatorCombiner(this, controller.name + " (clone)");
|
||||
switch (controller)
|
||||
{
|
||||
case AnimatorController ac:
|
||||
@ -85,7 +88,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
|
||||
public AnimatorController ConvertAnimatorController(AnimatorOverrideController overrideController)
|
||||
{
|
||||
var merger = new AnimatorCombiner(this);
|
||||
var merger = new AnimatorCombiner(this, overrideController.name + " (clone)");
|
||||
merger.AddOverrideController("", overrideController, null);
|
||||
return merger.Finish();
|
||||
}
|
||||
@ -122,5 +125,64 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
|
||||
return newMenu;
|
||||
}
|
||||
|
||||
public void CommitReferencedAssets()
|
||||
{
|
||||
HashSet<UnityEngine.Object> referencedAssets = new HashSet<UnityEngine.Object>();
|
||||
HashSet<UnityEngine.Object> sceneAssets = new HashSet<UnityEngine.Object>();
|
||||
|
||||
Walk(AvatarDescriptor.gameObject);
|
||||
|
||||
foreach (var asset in referencedAssets
|
||||
.Where(o => !sceneAssets.Contains(o))
|
||||
.Where(o => string.IsNullOrEmpty(AssetDatabase.GetAssetPath(o))))
|
||||
{
|
||||
AssetDatabase.AddObjectToAsset(asset, AssetContainer);
|
||||
}
|
||||
|
||||
SaveImmediate = true;
|
||||
|
||||
void Walk(GameObject obj)
|
||||
{
|
||||
sceneAssets.Add(obj);
|
||||
|
||||
foreach (var component in obj.GetComponents<Component>())
|
||||
{
|
||||
sceneAssets.Add(component);
|
||||
if (component is Transform t)
|
||||
{
|
||||
foreach (Transform child in t)
|
||||
{
|
||||
Walk(child.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
var so = new SerializedObject(component);
|
||||
var sp = so.GetIterator();
|
||||
bool enterChildren = true;
|
||||
|
||||
while (sp.Next(enterChildren))
|
||||
{
|
||||
enterChildren = true;
|
||||
if (sp.name == "m_GameObject") continue;
|
||||
if (sp.propertyType == SerializedPropertyType.String)
|
||||
{
|
||||
enterChildren = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sp.propertyType != SerializedPropertyType.ObjectReference)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sp.objectReferenceValue != null)
|
||||
{
|
||||
referencedAssets.Add(sp.objectReferenceValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -92,11 +92,11 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
|
||||
if (!mergeSessions.TryGetValue(merge.layerType, out var session))
|
||||
{
|
||||
session = new AnimatorCombiner(context);
|
||||
session = new AnimatorCombiner(context, merge.layerType.ToString() + " (merged)");
|
||||
mergeSessions[merge.layerType] = session;
|
||||
if (defaultControllers_.ContainsKey(merge.layerType))
|
||||
if (defaultControllers_.TryGetValue(merge.layerType, out var defaultController))
|
||||
{
|
||||
session.AddController("", defaultControllers_[merge.layerType], null);
|
||||
session.AddController("", defaultController, null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,7 +142,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
{
|
||||
// For non-default layers, ensure we always clone the controller for the benefit of subsequent
|
||||
// processing phases
|
||||
mergeSessions[layer.type] = new AnimatorCombiner(_context);
|
||||
mergeSessions[layer.type] = new AnimatorCombiner(_context, layer.type.ToString());
|
||||
mergeSessions[layer.type].AddController("", controller, null);
|
||||
}
|
||||
}
|
||||
|
@ -195,7 +195,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
{
|
||||
var path = AssetDatabase.GetAssetPath(obj);
|
||||
|
||||
return path != null && path.StartsWith(GetGeneratedAssetsFolder() + "/");
|
||||
return string.IsNullOrEmpty(path) || path.StartsWith(GetGeneratedAssetsFolder() + "/");
|
||||
}
|
||||
|
||||
public static Type FindType(string typeName)
|
||||
|
Loading…
Reference in New Issue
Block a user