#if UNITY_EDITOR using System; using System.IO; using System.Linq; using System.Collections.Generic; using UnityEngine; using UnityEditor; // Namespace namespace RayFire { // Single object snapshot data [Serializable] public class RFSnapshot { // Vars public string nm; // Ids public int oldId; public int parentOldId; public int newId; [NonSerialized]public Transform newTm; public Vector3 pos; public Quaternion rot; public Vector3 scale; public List mats; public RFMesh mesh; // Constructor public RFSnapshot(GameObject go, bool compress) { nm = go.name; oldId = go.GetInstanceID(); if (go.transform.parent != null) parentOldId = go.transform.parent.gameObject.GetInstanceID(); pos = go.transform.position; rot = go.transform.rotation; scale = go.transform.localScale; // Mesh MeshFilter mf = go.GetComponent(); if (mf != null) mesh = new RFMesh (mf.sharedMesh, compress); // Materials MeshRenderer mr = go.GetComponent(); mats = new List(); if (mr != null) foreach (var mat in mr.sharedMaterials) mats.Add (AssetDatabase.GetAssetPath (mat)); } // Create object public static GameObject Create (RFSnapshot cap, float sizeFilter) { // Mesh and size filtering Mesh mesh = null; if (cap.mesh.subMeshCount > 0) { // Size filtering if (cap.mesh.bounds.size.magnitude < sizeFilter) return null; // Get mesh mesh = cap.mesh.GetMesh(); } // Object GameObject go = new GameObject(); go.name = cap.nm; go.transform.position = cap.pos; go.transform.rotation = cap.rot; go.transform.localScale = cap.scale; // Mesh if (mesh != null) { MeshFilter mf = go.AddComponent(); mf.sharedMesh = mesh; } // Materials if (cap.mats.Count > 0) { MeshRenderer mr = go.AddComponent(); List materials = new List(cap.mats.Count); foreach (var matPath in cap.mats) materials.Add ((Material)AssetDatabase.LoadAssetAtPath (matPath, typeof(Material))); mr.sharedMaterials = materials.ToArray(); } cap.newId = go.GetInstanceID(); cap.newTm = go.transform; return go; } // Get parent new id by old id public static void SetParent (List list, int parentId, Transform tm, Transform parentTm) { foreach (var snap in list) { if (snap.oldId == parentId) { tm.parent = snap.newTm; break; } tm.parent = parentTm; } } } // Snapshot asset [Serializable] public class RFSnapshotAsset { // Vars public List assets; // Constructor public RFSnapshotAsset() { assets = new List(); } // Constructor public RFSnapshotAsset(List list, bool compress) { assets = new List(list.Count); foreach (var go in list) assets.Add (new RFSnapshot (go, compress)); } // Save asset public static void Snapshot(GameObject gameObject, bool compress, string assetName) { // Get all nested game objects List tms = gameObject.GetComponentsInChildren().ToList(); tms.Remove (gameObject.transform); // No asset if (tms.Count == 0) { Debug.Log ("RayFire Snapshot: " + gameObject.name + " has no children", gameObject); return; } // Create asset data List list = tms.Select (t => t.gameObject).ToList(); RFSnapshotAsset data = new RFSnapshotAsset (list, compress); // Set Folder string fld = Application.dataPath + "/RayFireSnapshots/"; if (Directory.Exists (fld) == false) Directory.CreateDirectory(fld); string nm = assetName + "_snapshot.json"; string stringData = JsonUtility.ToJson (data, true); // Save data File.WriteAllText (fld + nm, stringData); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } // Load asset public static void Load(UnityEngine.Object snapshotAsset, GameObject gameObject, float sizeFilter) { // No asset if (snapshotAsset == null) { Debug.Log ("RayFire Snapshot: " + gameObject.name + " Snapshot asset is not defined", gameObject); return; } // Get path string path1 = Application.dataPath; string path2 = AssetDatabase.GetAssetPath(snapshotAsset); path2 = path2.Remove (0, 6); // Read string dataString = File.ReadAllText (path1 + path2); RFSnapshotAsset assetData = JsonUtility.FromJson (dataString); // No asset if (assetData == null) { Debug.Log ("RayFire Snapshot: " + gameObject.name + " Snapshot asset is not defined", gameObject); return; } // Create objects from asset if (assetData.assets.Count > 0) foreach (var ast in assetData.assets) RFSnapshot.Create (ast, sizeFilter); // Set parents foreach (var snap in assetData.assets) { RFSnapshot.SetParent (assetData.assets, snap.parentOldId, snap.newTm, gameObject.transform); } } } } #endif