mirror of
https://github.com/bdunderscore/modular-avatar.git
synced 2024-12-29 18:55:06 +08:00
ensure that MA processing runs even if all MA components are inactive
This commit is contained in:
parent
ab2761a30f
commit
f49c6a0d2e
@ -23,6 +23,9 @@
|
||||
*/
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using VRC.SDK3.Avatars.Components;
|
||||
|
||||
namespace nadena.dev.modular_avatar.core.editor
|
||||
{
|
||||
@ -45,10 +48,10 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
{
|
||||
EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
|
||||
RuntimeUtil.OnDemandProcessAvatar = MaybeProcessAvatar;
|
||||
Menu.SetChecked(MENU_NAME, ModularAvatarSettings.applyOnPlay);
|
||||
EditorApplication.delayCall += () => Menu.SetChecked(MENU_NAME, ModularAvatarSettings.applyOnPlay);
|
||||
}
|
||||
|
||||
private static void MaybeProcessAvatar(RuntimeUtil.OnDemandSource source, AvatarTagComponent component)
|
||||
private static void MaybeProcessAvatar(RuntimeUtil.OnDemandSource source, MonoBehaviour component)
|
||||
{
|
||||
if (ModularAvatarSettings.applyOnPlay && source == armedSource && component != null)
|
||||
{
|
||||
|
@ -172,6 +172,12 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
{
|
||||
UnityEngine.Object.DestroyImmediate(component);
|
||||
}
|
||||
|
||||
var activator = avatarGameObject.GetComponent<AvatarActivator>();
|
||||
if (activator != null)
|
||||
{
|
||||
UnityEngine.Object.DestroyImmediate(activator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
119
Packages/nadena.dev.modular-avatar/Runtime/Activator.cs
Normal file
119
Packages/nadena.dev.modular-avatar/Runtime/Activator.cs
Normal file
@ -0,0 +1,119 @@
|
||||
#if UNITY_EDITOR
|
||||
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using VRC.SDK3.Avatars.Components;
|
||||
|
||||
namespace nadena.dev.modular_avatar.core
|
||||
{
|
||||
/// <summary>
|
||||
/// This component is used to trigger MA processing upon entering play mode (prior to Av3Emu running).
|
||||
/// We create it on a hidden object via AvatarTagObject's OnValidate, and it will proceed to add MAAvatarActivator
|
||||
/// components to all avatar roots which contain MA components. This MAAvatarActivator component then performs MA
|
||||
/// processing on Awake.
|
||||
///
|
||||
/// Note that we do not directly process the avatars from MAActivator. This is to avoid processing avatars that are
|
||||
/// initially inactive in the scene (which can have high overhead if the user has a lot of inactive avatars in the
|
||||
/// scene).
|
||||
/// </summary>
|
||||
[AddComponentMenu("")]
|
||||
[ExecuteInEditMode]
|
||||
[DefaultExecutionOrder(-9998)]
|
||||
public class Activator : MonoBehaviour
|
||||
{
|
||||
private const string TAG_OBJECT_NAME = "ModularAvatarInternal_Activator";
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (!RuntimeUtil.isPlaying || this == null) return;
|
||||
|
||||
var scene = gameObject.scene;
|
||||
foreach (var root in scene.GetRootGameObjects())
|
||||
{
|
||||
foreach (var avatar in root.GetComponentsInChildren<VRCAvatarDescriptor>())
|
||||
{
|
||||
if (avatar.GetComponentInChildren<AvatarTagComponent>(true) != null)
|
||||
{
|
||||
avatar.gameObject.GetOrAddComponent<AvatarActivator>().hideFlags = HideFlags.HideInInspector;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool HasMAComponentsInScene()
|
||||
{
|
||||
var scene = gameObject.scene;
|
||||
foreach (var root in scene.GetRootGameObjects())
|
||||
{
|
||||
if (root.GetComponentInChildren<AvatarTagComponent>(true) != null) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
EditorApplication.delayCall += () =>
|
||||
{
|
||||
gameObject.hideFlags = HideFlags.HideInHierarchy;
|
||||
if (!HasMAComponentsInScene())
|
||||
{
|
||||
var scene = gameObject.scene;
|
||||
DestroyImmediate(gameObject);
|
||||
EditorSceneManager.MarkSceneDirty(scene);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
internal static void CreateIfNotPresent(Scene scene)
|
||||
{
|
||||
if (!scene.IsValid() || EditorSceneManager.IsPreviewScene(scene)) return;
|
||||
if (EditorApplication.isPlayingOrWillChangePlaymode) return;
|
||||
|
||||
foreach (var root in scene.GetRootGameObjects())
|
||||
{
|
||||
if (root.GetComponent<Activator>() != null) return;
|
||||
}
|
||||
|
||||
var oldActiveScene = SceneManager.GetActiveScene();
|
||||
try
|
||||
{
|
||||
SceneManager.SetActiveScene(scene);
|
||||
var gameObject = new GameObject(TAG_OBJECT_NAME);
|
||||
gameObject.AddComponent<Activator>();
|
||||
gameObject.hideFlags = HideFlags.HideInHierarchy;
|
||||
}
|
||||
finally
|
||||
{
|
||||
SceneManager.SetActiveScene(oldActiveScene);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[AddComponentMenu("")]
|
||||
[ExecuteInEditMode]
|
||||
[DefaultExecutionOrder(-9997)]
|
||||
public class AvatarActivator : MonoBehaviour
|
||||
{
|
||||
private void Awake()
|
||||
{
|
||||
if (!RuntimeUtil.isPlaying || this == null) return;
|
||||
RuntimeUtil.OnDemandProcessAvatar(RuntimeUtil.OnDemandSource.Awake, this);
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (!RuntimeUtil.isPlaying || this == null) return;
|
||||
RuntimeUtil.OnDemandProcessAvatar(RuntimeUtil.OnDemandSource.Start, this);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
DestroyImmediate(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e41c5d0c41074360bc33887977722a4d
|
||||
timeCreated: 1671337621
|
@ -22,7 +22,6 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace nadena.dev.modular_avatar.core
|
||||
@ -44,5 +43,18 @@ namespace nadena.dev.modular_avatar.core
|
||||
if (!RuntimeUtil.isPlaying || this == null) return;
|
||||
RuntimeUtil.OnDemandProcessAvatar(RuntimeUtil.OnDemandSource.Start, this);
|
||||
}
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
if (RuntimeUtil.isPlaying) return;
|
||||
|
||||
RuntimeUtil.delayCall(() =>
|
||||
{
|
||||
if (this == null) return;
|
||||
#if UNITY_EDITOR
|
||||
Activator.CreateIfNotPresent(gameObject.scene);
|
||||
#endif
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -49,7 +49,7 @@ namespace nadena.dev.modular_avatar.core
|
||||
Start
|
||||
}
|
||||
|
||||
public delegate void OnDemandProcessAvatarDelegate(OnDemandSource source, AvatarTagComponent component);
|
||||
public delegate void OnDemandProcessAvatarDelegate(OnDemandSource source, MonoBehaviour component);
|
||||
|
||||
public static OnDemandProcessAvatarDelegate OnDemandProcessAvatar = (_m, _c) => { };
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user