Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: remake updating shared SkinnedMeshEditorSorter #518

Merged
merged 2 commits into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG-PRERELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ The format is based on [Keep a Changelog].
### Removed

### Fixed
- Editor of EditSkinnedMesh components may not work well if the object is inactive `#518`

### Security

Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ The format is based on [Keep a Changelog].
- MergeBone may make some bone inactive to active if bone being merged is inactive `#454`
- Avoid problematic material slot in MergeSkinnedMesh [`#508`](https://github.com/anatawa12/AvatarOptimizer/pull/508)
- This avoids [Unity's bug in 2019][unity-bug-material]. In Unity 2022, this is no longer needed.
- Editor of EditSkinnedMesh components may not work well if the object is inactive `#518`

[unity-bug]: https://issuetracker.unity3d.com/issues/crash-on-gettargetassemblybyscriptpath-when-a-po-file-in-the-packages-directory-is-not-under-an-assembly-definition
[unity-bug-material]: https://issuetracker.unity3d.com/issues/material-is-applied-to-two-slots-when-applying-material-to-a-single-slot-while-recording-animation
Expand Down
52 changes: 14 additions & 38 deletions Editor/EditSkinnedMeshComponentUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using JetBrains.Annotations;
using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;

namespace Anatawa12.AvatarOptimizer
{
Expand All @@ -14,34 +13,20 @@ internal static class EditSkinnedMeshComponentUtil
{
static EditSkinnedMeshComponentUtil()
{
RuntimeUtil.OnAwakeEditSkinnedMesh += OnAwake;
RuntimeUtil.OnDestroyEditSkinnedMesh += OnDestroy;

AssemblyReloadEvents.afterAssemblyReload += AfterAssemblyReload;
}

private static void AfterAssemblyReload()
{
foreach (var component in Enumerable.Range(0, SceneManager.sceneCount)
.Select(SceneManager.GetSceneAt)
.SelectMany(x => x.GetRootGameObjects())
.SelectMany(x => x.GetComponentsInChildren<EditSkinnedMeshComponent>(true)))
OnAwake(component);
}

// might be called by Processor to make sure the component is registered
internal static void OnAwake(EditSkinnedMeshComponent component)
{
EditorShared.AddComponent(component);
EditorApplication.hierarchyChanged += ResetSharedSorter;
}

private static void OnDestroy(EditSkinnedMeshComponent component)
private static SkinnedMeshEditorSorter CreateSharedSorterWithScene()
{
EditorShared.RemoveComponent(component);
var sorter = new SkinnedMeshEditorSorter();
foreach (var component in Resources.FindObjectsOfTypeAll<EditSkinnedMeshComponent>()
.Where(x => !EditorUtility.IsPersistent(x))
.Where(x => x.gameObject.scene.IsValid()))
sorter.AddComponent(component);
return sorter;
}

public static bool IsModifiedByEditComponent(SkinnedMeshRenderer renderer) =>
EditorShared.IsModifiedByEditComponent(renderer);
private static void ResetSharedSorter() => _editorShared = null;

public static (string name, float weight)[] GetBlendShapes(SkinnedMeshRenderer renderer) => EditorShared.GetBlendShapes(renderer);

Expand All @@ -55,7 +40,11 @@ public static (string name, float weight)[] GetBlendShapes(SkinnedMeshRenderer r
public static Material[] GetMaterials(SkinnedMeshRenderer renderer, EditSkinnedMeshComponent before = null,
bool fast = true) => EditorShared.GetMaterials(renderer, before, fast);

private static readonly SkinnedMeshEditorSorter EditorShared = new SkinnedMeshEditorSorter();
[CanBeNull] private static SkinnedMeshEditorSorter _editorShared;

[NotNull]
private static SkinnedMeshEditorSorter EditorShared =>
_editorShared ?? (_editorShared = CreateSharedSorterWithScene());
}

internal class SkinnedMeshEditorSorter
Expand All @@ -69,12 +58,6 @@ public void AddComponent(EditSkinnedMeshComponent component)
processors.AddProcessor(processor);
}

public void RemoveComponent(EditSkinnedMeshComponent component)
{
var target = component.GetComponent<SkinnedMeshRenderer>();
GetProcessors(target)?.RemoveProcessorOf(component);
}

public bool IsModifiedByEditComponent(SkinnedMeshRenderer renderer) =>
ProcessorsByRenderer.ContainsKey(renderer);

Expand Down Expand Up @@ -151,13 +134,6 @@ public void AddProcessor(IEditSkinnedMeshProcessor processor)
PurgeCache();
}

public void RemoveProcessorOf(EditSkinnedMeshComponent component)
{
var removed = _processors.RemoveWhere(x => x.Component == component);
if (removed == 0) return;
PurgeCache(removing: true);
}

internal List<IEditSkinnedMeshProcessor> GetSorted()
{
if (_sorted != null) return _sorted;
Expand Down
4 changes: 0 additions & 4 deletions Runtime/EditSkinnedMeshComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,7 @@
namespace Anatawa12.AvatarOptimizer
{
[RequireComponent(typeof(SkinnedMeshRenderer))]
[ExecuteAlways]
internal abstract class EditSkinnedMeshComponent : AvatarTagComponent
{
private void Awake() => RuntimeUtil.OnAwakeEditSkinnedMesh?.Invoke(this);

private void OnDestroy() => RuntimeUtil.OnDestroyEditSkinnedMesh?.Invoke(this);
}
}
3 changes: 0 additions & 3 deletions Runtime/RuntimeUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,5 @@ public static string RelativePath(GameObject root, GameObject child)
#else
public static bool isPlaying => true;
#endif

public static Action<EditSkinnedMeshComponent> OnAwakeEditSkinnedMesh;
public static Action<EditSkinnedMeshComponent> OnDestroyEditSkinnedMesh;
}
}