From bcb535ec7bdfc456f5fdd236f62ea775e65663da Mon Sep 17 00:00:00 2001 From: soupday <79094830+soupday@users.noreply.github.com> Date: Tue, 21 Jun 2022 16:25:52 +0100 Subject: [PATCH] 1.3.2 Animation Mode fix after recompile. --- Editor/AnimPlayerGUI.cs | 20 +++++-- Editor/ImporterWindow.cs | 14 ++--- Editor/MeshUtil.cs | 13 ++--- Editor/Util.cs | 120 ++++++++++++++++++++++++++++++++++++--- Editor/WindowManager.cs | 60 +++++++++++++++++--- 5 files changed, 190 insertions(+), 37 deletions(-) diff --git a/Editor/AnimPlayerGUI.cs b/Editor/AnimPlayerGUI.cs index 3d17141..cd1457f 100644 --- a/Editor/AnimPlayerGUI.cs +++ b/Editor/AnimPlayerGUI.cs @@ -24,11 +24,12 @@ public static class AnimPlayerGUI private static bool forceUpdate = false; private static FacialProfile defaultProfile = new FacialProfile(ExpressionProfile.ExPlus, VisemeProfile.PairsCC3); - public static void OpenPlayer(GameObject fbx) + public static void OpenPlayer(GameObject scenePrefab) { - if (fbx) + if (scenePrefab) { - SetCharacter(fbx); + scenePrefab = Util.TryResetScenePrefab(scenePrefab); + SetCharacter(scenePrefab); } if (!IsPlayerShown()) @@ -49,7 +50,7 @@ public static void OpenPlayer(GameObject fbx) } } - public static void ClosePlayer() + public static void ClosePlayer() { if (IsPlayerShown()) { @@ -58,6 +59,12 @@ public static void ClosePlayer() if (AnimationMode.InAnimationMode()) AnimationMode.StopAnimationMode(); + if (CharacterAnimator) + { + GameObject scenePrefab = Util.GetScenePrefabInstanceRoot(CharacterAnimator.gameObject); + Util.TryResetScenePrefab(scenePrefab); + } + #if SCENEVIEW_OVERLAY_COMPATIBLE //2021.2.0a17+ AnimPlayerOverlay.HideAll(); @@ -91,8 +98,8 @@ public static void SetCharacter(GameObject scenePrefab) if (WindowManager.IsPreviewScene) scenePrefab = WindowManager.GetPreviewScene().GetPreviewCharacter(); - if (scenePrefab) - { + if (scenePrefab) + { Animator animator = scenePrefab.GetComponent(); GameObject sceneFbx = Util.GetCharacterSourceFbx(scenePrefab); AnimationClip clip = Util.GetFirstAnimationClipFromCharacter(sceneFbx); @@ -131,6 +138,7 @@ static public void UpdateAnimatorClip(Animator animator, AnimationClip clip) if (WorkingClip && CharacterAnimator) { + // also restarts animation mode SampleOnce(); } } diff --git a/Editor/ImporterWindow.cs b/Editor/ImporterWindow.cs index 5ff6b68..0ec59c8 100644 --- a/Editor/ImporterWindow.cs +++ b/Editor/ImporterWindow.cs @@ -1036,12 +1036,11 @@ bool UpdatePreviewCharacter(GameObject prefabAsset) { if (WindowManager.IsPreviewScene) { - bool animationMode = AnimationMode.InAnimationMode(); - if (animationMode) AnimationMode.StopAnimationMode(); + bool animationMode = WindowManager.StopAnimationMode(); WindowManager.GetPreviewScene().UpdatePreviewCharacter(prefabAsset); - if (animationMode) AnimationMode.StartAnimationMode(); + WindowManager.RestartAnimationMode(animationMode); } return WindowManager.IsPreviewScene; @@ -1049,7 +1048,7 @@ bool UpdatePreviewCharacter(GameObject prefabAsset) private void BuildCharacter() { - Util.LogInfo("Doing: Building materials..."); + Util.LogInfo("Building materials:"); // refresh the character info for any Json changes contextCharacter.Refresh(); @@ -1085,6 +1084,8 @@ private void BakeCharacter() { if (contextCharacter.HQMaterials) { + Util.LogInfo("Baking materials:"); + WindowManager.HideAnimationPlayer(true); ComputeBake baker = new ComputeBake(contextCharacter.Fbx, contextCharacter); @@ -1104,12 +1105,11 @@ bool ShowBakedCharacter(GameObject bakedAsset) { if (WindowManager.IsPreviewScene) { - bool animationMode = AnimationMode.InAnimationMode(); - if (animationMode) AnimationMode.StopAnimationMode(); + bool animationMode = WindowManager.StopAnimationMode(); WindowManager.GetPreviewScene().ShowBakedCharacter(bakedAsset); - if (animationMode) AnimationMode.StartAnimationMode(); + WindowManager.RestartAnimationMode(animationMode); } return WindowManager.IsPreviewScene; diff --git a/Editor/MeshUtil.cs b/Editor/MeshUtil.cs index 9db8914..3384f79 100644 --- a/Editor/MeshUtil.cs +++ b/Editor/MeshUtil.cs @@ -206,9 +206,8 @@ public static Mesh GetMeshFrom(Object obj) } public static bool ReplaceMesh(Object obj, Mesh mesh) - { - bool animationMode = AnimationMode.InAnimationMode(); - if (animationMode) AnimationMode.StopAnimationMode(); + { + bool animationMode = WindowManager.StopAnimationMode(obj); bool replaced = false; Object o = null; @@ -236,18 +235,16 @@ public static bool ReplaceMesh(Object obj, Mesh mesh) } } - if (replaced) - { - GameObject prefabAsset = Util.FindRootPrefabAssetFromSceneObject(obj); + if (replaced) + { GameObject sceneRoot = Util.GetScenePrefabInstanceRoot(obj); - string prefabPath = AssetDatabase.GetAssetPath(prefabAsset); // this doesn't work... //PrefabUtility.ApplyObjectOverride(obj, prefabPath, InteractionMode.UserAction); // only this works: PrefabUtility.ApplyPrefabInstance(sceneRoot, InteractionMode.UserAction); } - if (animationMode) AnimationMode.StartAnimationMode(); + WindowManager.RestartAnimationMode(animationMode); return replaced; } diff --git a/Editor/Util.cs b/Editor/Util.cs index 187b337..f0a601c 100644 --- a/Editor/Util.cs +++ b/Editor/Util.cs @@ -25,7 +25,32 @@ namespace Reallusion.Import { public static class Util { - public static int LOG_LEVEL = 1; + public static int log_level = -1; + public static int LOG_LEVEL + { + get + { + if (log_level == -1) + { + if (EditorPrefs.HasKey("RL_Log_Level")) + { + log_level = EditorPrefs.GetInt("RL_Log_Level"); + } + else + { + log_level = 0; + EditorPrefs.SetInt("RL_Log_Level", log_level); + } + } + return log_level; + } + + set + { + log_level = value; + EditorPrefs.SetInt("RL_Log_Level", value); + } + } public static bool IsCC3Character(Object obj) { @@ -765,16 +790,97 @@ public static GameObject FindRootPrefabAssetFromSceneObject(Object sceneObject) GameObject instanceRoot = GetScenePrefabInstanceRoot(sceneObject); return FindRootPrefabAsset(instanceRoot); + } + + public static void ResetPrefabTransforms(GameObject prefabObj) + { + if (prefabObj) + { + GameObject source = PrefabUtility.GetCorrespondingObjectFromOriginalSource(prefabObj); + if (source && source != prefabObj) + { + bool resetPos = false; + bool resetRot = false; + bool resetSca = false; + if (prefabObj.transform.position != source.transform.position) resetPos = true; + if (prefabObj.transform.rotation != source.transform.rotation) resetRot = true; + if (prefabObj.transform.localScale != source.transform.localScale) resetSca = true; + if (resetPos) prefabObj.transform.position = source.transform.position; + if (resetRot) prefabObj.transform.rotation = source.transform.rotation; + if (resetSca) prefabObj.transform.localScale = source.transform.localScale; + /* + if (resetPos || resetRot || resetSca) + { + string report = "Resetting " + prefabObj.name + ":"; + if (resetPos) report += " Position"; + if (resetRot) report += " Rotation"; + if (resetSca) report += " Scale"; + Debug.Log(report); + } + */ + + for (int i = 0; i < prefabObj.transform.childCount; i++) + { + Transform child = prefabObj.transform.GetChild(i); + ResetPrefabTransforms(child.gameObject); + } + } + } } - public static void ResetPrefabTransforms(Transform root) + public static GameObject TryResetScenePrefab(GameObject scenePrefab) { - for (int i = 0; i < root.childCount; i++) - { - Transform child = root.transform.GetChild(i); - PrefabUtility.RevertObjectOverride(child, InteractionMode.AutomatedAction); - ResetPrefabTransforms(child); + if (PrefabNeedsReset(scenePrefab)) + { + Util.LogInfo("Resetting Prefab"); + ResetPrefabTransforms(scenePrefab); + /* + GameObject prefabSource = PrefabUtility.GetCorrespondingObjectFromSource(scenePrefab); + Transform t = scenePrefab.transform; + Transform parent = t.parent; + Vector3 pos = t.position; + Quaternion rot = t.rotation; + Vector3 sca = t.localScale; + GameObject.DestroyImmediate(scenePrefab); + scenePrefab = (GameObject)PrefabUtility.InstantiatePrefab(prefabSource); + scenePrefab.transform.parent = parent; + scenePrefab.transform.position = pos; + scenePrefab.transform.rotation = rot; + scenePrefab.transform.localScale = sca; + */ } + + return scenePrefab; + } + + public static bool PrefabNeedsReset(GameObject prefabObj) + { + if (prefabObj) + { + GameObject source = PrefabUtility.GetCorrespondingObjectFromOriginalSource(prefabObj); + if (source && source != prefabObj) + { + bool resetPos = false; + bool resetRot = false; + bool resetSca = false; + if (prefabObj.transform.position != source.transform.position) resetPos = true; + if (prefabObj.transform.rotation != source.transform.rotation) resetRot = true; + if (prefabObj.transform.localScale != source.transform.localScale) resetSca = true; + if (resetPos || resetRot || resetSca) + { + return true; + } + + for (int i = 0; i < prefabObj.transform.childCount; i++) + { + Transform child = prefabObj.transform.GetChild(i); + bool result = PrefabNeedsReset(child.gameObject); + if (result) return true; + } + } + } + + return false; } public static void FindSceneObjects(Transform root, string search, List found) diff --git a/Editor/WindowManager.cs b/Editor/WindowManager.cs index 651082b..2a22577 100644 --- a/Editor/WindowManager.cs +++ b/Editor/WindowManager.cs @@ -4,6 +4,7 @@ using UnityEngine.SceneManagement; using UnityEditor; using UnityEditor.SceneManagement; +using UnityEditor.Compilation; using System; namespace Reallusion.Import @@ -17,13 +18,14 @@ public static class WindowManager public static bool openedInPreviewScene; public static bool showPlayer = true; public static bool showRetarget = false; + private static bool eventsAdded = false; static WindowManager() - { + { // Even if update is not the most elegant. Using hierarchyWindowChanged for CPU sake will not work in all cases, because when hierarchyWindowChanged is called, Time's values might be all higher than current values. Why? Because current values are set at the first frame. If you keep reloading the same scene, this case happens. EditorApplication.update += WindowManager.MonitorScene; showPlayer = Importer.ANIMPLAYER_ON_BY_DEFAULT; - currentScene = EditorSceneManager.GetActiveScene(); + currentScene = EditorSceneManager.GetActiveScene(); previewScene = PreviewScene.FetchPreviewScene(currentScene); if (previewScene.IsValidPreviewScene) @@ -36,6 +38,20 @@ static WindowManager() previewScene = default; previewSceneHandle = default; } + + if (!eventsAdded) + { + AssemblyReloadEvents.beforeAssemblyReload += OnBeforeAssemblyReload; + } + } + + public static void OnBeforeAssemblyReload() + { + if (AnimationMode.InAnimationMode()) + { + Util.LogInfo("Disabling Animation Mode on editor assembly reload."); + AnimationMode.StopAnimationMode(); + } } public static PreviewScene OpenPreviewScene(GameObject prefab) @@ -68,10 +84,10 @@ public static PreviewScene GetPreviewScene() } return default; - } + } - private static void MonitorScene() - { + private static void MonitorScene() + { Scene activeScene = EditorSceneManager.GetActiveScene(); if (currentScene != activeScene) { @@ -252,14 +268,14 @@ public static void TakeScreenShot() public static void ShowAnimationPlayer() { - GameObject currentCharacterFbx; + GameObject scenePrefab; if (IsPreviewScene) - currentCharacterFbx = GetPreviewScene().GetPreviewCharacter(); + scenePrefab = GetPreviewScene().GetPreviewCharacter(); else - currentCharacterFbx = Selection.activeGameObject; + scenePrefab = Selection.activeGameObject; - AnimPlayerGUI.OpenPlayer(currentCharacterFbx); + AnimPlayerGUI.OpenPlayer(scenePrefab); openedInPreviewScene = IsPreviewScene; if (showRetarget) ShowAnimationRetargeter(); @@ -294,6 +310,32 @@ public static void HideAnimationRetargeter(bool updateShowRetarget) if (updateShowRetarget) showRetarget = false; + } + + public static bool StopAnimationMode(UnityEngine.Object obj = null) + { + bool inAnimationMode = false; + if (AnimationMode.InAnimationMode()) + { + inAnimationMode = true; + AnimationMode.StopAnimationMode(); + if (obj) + { + GameObject scenePrefab = Util.GetScenePrefabInstanceRoot(obj); + Util.TryResetScenePrefab(scenePrefab); + } + } + + return inAnimationMode; + } + + public static void RestartAnimationMode(bool inAnimationMode) + { + if (inAnimationMode) + { + if (!AnimationMode.InAnimationMode()) + AnimationMode.StartAnimationMode(); + } } } }