//---------------------------------------------------------------------------------------------------------------------- internal static void ChangeSceneCacheFile(SceneCachePlayer cachePlayer, string sceneCacheFilePath) { string prefabPath = null; GameObject go = cachePlayer.gameObject; //Check if it's possible to reuse the old assetsFolder string assetsFolder = cachePlayer.GetAssetsFolder(); if (string.IsNullOrEmpty(assetsFolder)) { MeshSyncRuntimeSettings runtimeSettings = MeshSyncRuntimeSettings.GetOrCreateSettings(); string scOutputPath = runtimeSettings.GetSceneCacheOutputPath(); assetsFolder = Path.Combine(scOutputPath, Path.GetFileNameWithoutExtension(sceneCacheFilePath)); } bool isPrefabInstance = cachePlayer.gameObject.IsPrefabInstance(); //We are directly modifying a prefab if (!isPrefabInstance && go.IsPrefab()) { prefabPath = AssetDatabase.GetAssetPath(go); CreateSceneCachePlayerAndPrefab(sceneCacheFilePath, prefabPath, assetsFolder, out SceneCachePlayer player, out GameObject newPrefab); Object.DestroyImmediate(player.gameObject); return; } if (isPrefabInstance) { GameObject prefab = PrefabUtility.GetCorrespondingObjectFromSource(cachePlayer.gameObject); prefabPath = AssetDatabase.GetAssetPath(prefab); } cachePlayer.CloseCache(); //[TODO-sin: 2020-9-28] Find out if it is possible to do undo properly Undo.RegisterFullObjectHierarchyUndo(cachePlayer.gameObject, "SceneCachePlayer"); cachePlayer.Init(assetsFolder); cachePlayer.OpenCacheInEditor(sceneCacheFilePath); //Save as prefab again if (string.IsNullOrEmpty(prefabPath)) { return; } //Prevent overwriting ".sc" file itself bool isPrefabExt = (Path.GetExtension(prefabPath).ToLower() == ".prefab"); if (isPrefabExt) { cachePlayer.gameObject.SaveAsPrefab(prefabPath); } }
void DrawCacheSettings(SceneCachePlayer t, SerializedObject so) { var styleFold = EditorStyles.foldout; styleFold.fontStyle = FontStyle.Bold; t.foldCacheSettings = EditorGUILayout.Foldout(t.foldCacheSettings, "Player", true, styleFold); if (t.foldCacheSettings) { // cache file path EditorGUILayout.PropertyField(so.FindProperty("m_cacheFilePath")); var dataPath = t.cacheFilePath; if (dataPath.root != DataPath.Root.StreamingAssets) { GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (GUILayout.Button("Copy to StreamingAssets", GUILayout.Width(160.0f))) { var srcPath = dataPath.fullPath; var dstPath = Misc.CopyFileToStreamingAssets(dataPath.fullPath); Undo.RecordObject(t, "SceneCachePlayer"); t.OpenCache(dstPath); Repaint(); } if (GUILayout.Button("Move to StreamingAssets", GUILayout.Width(160.0f))) { t.CloseCache(); var srcPath = dataPath.fullPath; var dstPath = Misc.MoveFileToStreamingAssets(dataPath.fullPath); Undo.RecordObject(t, "SceneCachePlayer"); t.OpenCache(dstPath); Repaint(); } GUILayout.EndHorizontal(); } EditorGUILayout.Space(); // time / frame System.Action resetTimeAnimation = () => { so.ApplyModifiedProperties(); t.ResetTimeAnimation(); }; EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(so.FindProperty("m_timeUnit")); if (EditorGUI.EndChangeCheck()) { resetTimeAnimation(); } if (t.timeUnit == SceneCachePlayer.TimeUnit.Seconds) { EditorGUILayout.PropertyField(so.FindProperty("m_time")); EditorGUILayout.PropertyField(so.FindProperty("m_interpolation")); } else if (t.timeUnit == SceneCachePlayer.TimeUnit.Frames) { EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(so.FindProperty("m_baseFrame")); if (EditorGUI.EndChangeCheck()) { resetTimeAnimation(); } EditorGUILayout.PropertyField(so.FindProperty("m_frame")); } // preload { var preloadLength = so.FindProperty("m_preloadLength"); preloadLength.intValue = EditorGUILayout.IntSlider("Preload Length", preloadLength.intValue, 0, t.frameCount); } EditorGUILayout.Space(); } }
//---------------------------------------------------------------------------------------------------------------------- internal static void ChangeSceneCacheFile(SceneCachePlayer cachePlayer, string sceneCacheFilePath) { string prefabPath = null; GameObject go = cachePlayer.gameObject; //Check if it's possible to reuse the old assetsFolder string assetsFolder = cachePlayer.GetAssetsFolder(); if (string.IsNullOrEmpty(assetsFolder)) { MeshSyncProjectSettings projectSettings = MeshSyncProjectSettings.GetOrCreateSettings(); string scOutputPath = projectSettings.GetSceneCacheOutputPath(); assetsFolder = Path.Combine(scOutputPath, Path.GetFileNameWithoutExtension(sceneCacheFilePath)); } bool isPrefabInstance = cachePlayer.gameObject.IsPrefabInstance(); //We are directly modifying a prefab if (!isPrefabInstance && go.IsPrefab()) { prefabPath = AssetDatabase.GetAssetPath(go); CreateSceneCachePlayerAndPrefab(sceneCacheFilePath, prefabPath, assetsFolder, out SceneCachePlayer player, out GameObject newPrefab); Object.DestroyImmediate(player.gameObject); return; } if (isPrefabInstance) { GameObject prefab = PrefabUtility.GetCorrespondingObjectFromSource(cachePlayer.gameObject); //GetCorrespondingObjectFromSource() may return the ".sc" GameObject instead of the prefab //due to the SceneCacheImporter string assetPath = AssetDatabase.GetAssetPath(prefab); if (Path.GetExtension(assetPath).ToLower() == ".prefab") { prefabPath = assetPath; } else { isPrefabInstance = false; } } cachePlayer.CloseCache(); //[TODO-sin: 2020-9-28] Find out if it is possible to do undo properly Undo.RegisterFullObjectHierarchyUndo(cachePlayer.gameObject, "SceneCachePlayer"); Dictionary<string,EntityRecord> prevRecords = new Dictionary<string, EntityRecord>(cachePlayer.GetClientObjects()); GameObject tempGO = null; Dictionary<Transform, Transform> nonPrefabTrans = new Dictionary<Transform, Transform>(); //nonPrefab -> origParent if (isPrefabInstance) { //Move non-prefab transforms tempGO = new GameObject("Temp"); FindNonPrefabChildren(cachePlayer.transform, ref nonPrefabTrans); nonPrefabTrans.Keys.SetParent(tempGO.transform); PrefabUtility.UnpackPrefabInstance(cachePlayer.gameObject, PrefabUnpackMode.Completely, InteractionMode.AutomatedAction); } //remove irrelevant components of the GameObject if the entity type is different void ChangeEntityTypeCB(GameObject updatedGo, TransformData data) { string dataPath = data.path; if (!prevRecords.ContainsKey(dataPath)) return; EntityRecord prevRecord = prevRecords[dataPath]; if (data.entityType == prevRecord.dataType) return; DestroyIrrelevantComponents(updatedGo, data.entityType); } cachePlayer.onUpdateEntity += ChangeEntityTypeCB; cachePlayer.Init(assetsFolder); cachePlayer.OpenCacheInEditor(sceneCacheFilePath); cachePlayer.onUpdateEntity -= ChangeEntityTypeCB; IDictionary<string,EntityRecord> curRecords = cachePlayer.GetClientObjects(); DeleteInvalidRecordedGameObjects(prevRecords, curRecords); if (!isPrefabInstance) { return; } cachePlayer.gameObject.SaveAsPrefab(prefabPath); //Save as prefab if it was originally a prefab instance //Move nonPrefab transforms back foreach (KeyValuePair<Transform, Transform> kv in nonPrefabTrans) { Transform origParent = kv.Value; Transform t = kv.Key; if (null == origParent) { ObjectUtility.Destroy(t.gameObject); } else { t.SetParent(origParent); } } ObjectUtility.Destroy(tempGO); }