├── Assets ├── Editor Default Resources.meta ├── Editor Default Resources │ ├── MemoryProfiler_EditorResources.meta │ └── MemoryProfiler_EditorResources │ │ ├── MemoryProfiler_00015.jpg │ │ ├── MemoryProfiler_00015.jpg.meta │ │ ├── MemoryProfiler_DialogGUISkin.guiskin │ │ ├── MemoryProfiler_DialogGUISkin.guiskin.meta │ │ ├── MemoryProfiler_MemHeapGUISkin.guiskin │ │ ├── MemoryProfiler_MemHeapGUISkin.guiskin.meta │ │ ├── MemoryProfiler_NodeGUISkin.guiskin │ │ ├── MemoryProfiler_NodeGUISkin.guiskin.meta │ │ ├── MemoryProfiler_bgMenu.jpg │ │ ├── MemoryProfiler_bgMenu.jpg.meta │ │ ├── MemoryProfiler_bgWindow2.png │ │ ├── MemoryProfiler_bgWindow2.png.meta │ │ ├── MemoryProfiler_bgWindow3ON.png │ │ ├── MemoryProfiler_bgWindow3ON.png.meta │ │ ├── MemoryProfiler_bgWindowtest.meta │ │ ├── MemoryProfiler_bgWindowtest │ │ ├── MemoryProfiler_bgWindowtest-blue.png │ │ ├── MemoryProfiler_bgWindowtest-blue.png.meta │ │ ├── MemoryProfiler_bgWindowtest-green.png │ │ ├── MemoryProfiler_bgWindowtest-green.png.meta │ │ ├── MemoryProfiler_bgWindowtest-orange.png │ │ ├── MemoryProfiler_bgWindowtest-orange.png.meta │ │ ├── MemoryProfiler_bgWindowtest-purple.png │ │ ├── MemoryProfiler_bgWindowtest-purple.png.meta │ │ ├── MemoryProfiler_bgWindowtest-red.png │ │ ├── MemoryProfiler_bgWindowtest-red.png.meta │ │ ├── MemoryProfiler_bgWindowtest2-blue.png │ │ ├── MemoryProfiler_bgWindowtest2-blue.png.meta │ │ ├── MemoryProfiler_bgWindowtest2-green.png │ │ ├── MemoryProfiler_bgWindowtest2-green.png.meta │ │ ├── MemoryProfiler_bgWindowtest2-orange.png │ │ ├── MemoryProfiler_bgWindowtest2-orange.png.meta │ │ ├── MemoryProfiler_bgWindowtest2-purple.png │ │ ├── MemoryProfiler_bgWindowtest2-purple.png.meta │ │ ├── MemoryProfiler_bgWindowtest2-red.png │ │ ├── MemoryProfiler_bgWindowtest2-red.png.meta │ │ ├── MemoryProfiler_bgWindowtest2.png │ │ ├── MemoryProfiler_bgWindowtest2.png.meta │ │ ├── MemoryProfiler_bgWindowtest_img.png │ │ └── MemoryProfiler_bgWindowtest_img.png.meta │ │ ├── MemoryProfiler_heapsection.png │ │ ├── MemoryProfiler_heapsection.png.meta │ │ ├── MemoryProfiler_memSegment.jpg │ │ ├── MemoryProfiler_memSegment.jpg.meta │ │ ├── MemoryProfiler_memSegmentGUISkin.guiskin │ │ └── MemoryProfiler_memSegmentGUISkin.guiskin.meta ├── Editor.meta ├── Editor │ ├── MemoryProfiler.meta │ └── MemoryProfiler │ │ ├── ArrayTools.cs │ │ ├── ArrayTools.cs.meta │ │ ├── BytesAndOffset.cs │ │ ├── BytesAndOffset.cs.meta │ │ ├── CrawledDataUnpacker.cs │ │ ├── CrawledDataUnpacker.cs.meta │ │ ├── Crawler.cs │ │ ├── Crawler.cs.meta │ │ ├── HighLevelAPI.cs │ │ ├── HighLevelAPI.cs.meta │ │ ├── Inspector.cs │ │ ├── Inspector.cs.meta │ │ ├── JsonDotNet20.meta │ │ ├── JsonDotNet20 │ │ ├── Newtonsoft.Json.dll │ │ ├── Newtonsoft.Json.dll.mdb │ │ ├── Newtonsoft.Json.dll.mdb.meta │ │ ├── Newtonsoft.Json.dll.meta │ │ ├── Newtonsoft.Json.pdb │ │ ├── Newtonsoft.Json.pdb.meta │ │ ├── Newtonsoft.Json.xml │ │ ├── Newtonsoft.Json.xml.meta │ │ ├── license.txt │ │ ├── license.txt.meta │ │ ├── readme.txt │ │ └── readme.txt.meta │ │ ├── LowLevelAPI.cs │ │ ├── LowLevelAPI.cs.meta │ │ ├── ManagedHeapExtensions.cs │ │ ├── ManagedHeapExtensions.cs.meta │ │ ├── MemoryProfilerWindow.cs │ │ ├── MemoryProfilerWindow.cs.meta │ │ ├── PackedManagedObject.cs │ │ ├── PackedManagedObject.cs.meta │ │ ├── PackedMemorySnapshotUtility.cs │ │ ├── PackedMemorySnapshotUtility.cs.meta │ │ ├── PrimitiveValueReader.cs │ │ ├── PrimitiveValueReader.cs.meta │ │ ├── ProfilerData.meta │ │ ├── ProfilerData │ │ ├── MemoryElement.cs │ │ ├── MemoryElement.cs.meta │ │ ├── TreeViewWithTreeModel.cs │ │ └── TreeViewWithTreeModel.cs.meta │ │ ├── ProfilerNodes.meta │ │ ├── ProfilerNodes │ │ ├── ProfilerNode.cs │ │ ├── ProfilerNode.cs.meta │ │ ├── ProfilerNodeObjectInfo.cs │ │ ├── ProfilerNodeObjectInfo.cs.meta │ │ ├── ProfilerNodeView.cs │ │ ├── ProfilerNodeView.cs.meta │ │ ├── ProfilerNodeZoomArea.cs │ │ └── ProfilerNodeZoomArea.cs.meta │ │ ├── ProfilerTreeView.cs │ │ ├── ProfilerTreeView.cs.meta │ │ ├── ProfilerWindow.cs │ │ ├── ProfilerWindow.cs.meta │ │ ├── ShortestPathToRootFinder.cs │ │ ├── ShortestPathToRootFinder.cs.meta │ │ ├── StringTools.cs │ │ ├── StringTools.cs.meta │ │ ├── TreeAsset 1.asset │ │ ├── TreeAsset 1.asset.meta │ │ ├── TreeDataModel.meta │ │ ├── TreeDataModel │ │ ├── TreeElement.cs │ │ ├── TreeElement.cs.meta │ │ ├── TreeElementUtility.cs │ │ ├── TreeElementUtility.cs.meta │ │ ├── TreeModel.cs │ │ └── TreeModel.cs.meta │ │ ├── TreeMapView.cs │ │ ├── TreeMapView.cs.meta │ │ ├── TreeViewExamples.meta │ │ ├── TreeViewExamples │ │ ├── BackendData.meta │ │ ├── BackendData │ │ │ ├── MyTreeAsset.cs │ │ │ ├── MyTreeAsset.cs.meta │ │ │ ├── MyTreeAssetEditor.cs │ │ │ ├── MyTreeAssetEditor.cs.meta │ │ │ ├── MyTreeElement.cs │ │ │ ├── MyTreeElement.cs.meta │ │ │ ├── MyTreeElementGenerator.cs │ │ │ ├── MyTreeElementGenerator.cs.meta │ │ │ ├── TreeViewWithTreeModel.cs │ │ │ └── TreeViewWithTreeModel.cs.meta │ │ ├── MultiColumnTreeView.cs │ │ ├── MultiColumnTreeView.cs.meta │ │ ├── MultiColumnWindow.cs │ │ ├── MultiColumnWindow.cs.meta │ │ ├── SimpleTreeView.cs │ │ ├── SimpleTreeView.cs.meta │ │ ├── SimpleTreeViewWindow.cs │ │ ├── SimpleTreeViewWindow.cs.meta │ │ ├── TransformsTreeView.cs │ │ ├── TransformsTreeView.cs.meta │ │ ├── TransformsTreeViewWindow.cs │ │ └── TransformsTreeViewWindow.cs.meta │ │ ├── Treemap.meta │ │ ├── Treemap │ │ ├── Group.cs │ │ ├── Group.cs.meta │ │ ├── ITreemapRenderable.cs │ │ ├── ITreemapRenderable.cs.meta │ │ ├── Item.cs │ │ ├── Item.cs.meta │ │ ├── Tests.meta │ │ ├── Tests │ │ │ ├── TreemapTests.cs │ │ │ └── TreemapTests.cs.meta │ │ ├── Utility.cs │ │ └── Utility.cs.meta │ │ ├── TypeTools.cs │ │ ├── TypeTools.cs.meta │ │ ├── ZoomArea.cs │ │ └── ZoomArea.cs.meta ├── Resources.meta └── Resources │ ├── MemoryProfiler_Resources.meta │ └── MemoryProfiler_Resources │ ├── MemoryProfiler_Background.png │ └── MemoryProfiler_Background.png.meta ├── Documentation └── Images │ ├── HeapView.jpg │ ├── PlainData.jpg │ ├── TreeView.jpg │ ├── memoryProfiler.jpg │ ├── memoryProfiler1.jpg │ └── memoryProfiler2.jpg ├── ExampleMemorySnapshot └── memorysnapshot.memsnap2 └── README.md /Assets/Editor Default Resources.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cbedf8123829b0c40b79ed2982dcfe00 3 | folderAsset: yes 4 | timeCreated: 1489206756 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9177a7a1b81633f47a4bce4e38bda635 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_00015.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertoardila/support-unity-memoryprofiler/12e57074757ec7fa09983e6a1752e02acc45ace4/Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_00015.jpg -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_00015.jpg.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2ba2098d7de1a664b8e77bab805a1e7c 3 | timeCreated: 1503442668 4 | licenseType: Pro 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 4 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | sRGBTexture: 1 12 | linearTexture: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 6 25 | cubemapConvolution: 0 26 | seamlessCubemap: 0 27 | textureFormat: 1 28 | maxTextureSize: 2048 29 | textureSettings: 30 | filterMode: -1 31 | aniso: -1 32 | mipBias: -1 33 | wrapMode: -1 34 | nPOTScale: 1 35 | lightmap: 0 36 | compressionQuality: 50 37 | spriteMode: 0 38 | spriteExtrude: 1 39 | spriteMeshType: 1 40 | alignment: 0 41 | spritePivot: {x: 0.5, y: 0.5} 42 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 43 | spritePixelsToUnits: 100 44 | alphaUsage: 1 45 | alphaIsTransparency: 0 46 | spriteTessellationDetail: -1 47 | textureType: 0 48 | textureShape: 1 49 | maxTextureSizeSet: 0 50 | compressionQualitySet: 0 51 | textureFormatSet: 0 52 | platformSettings: 53 | - buildTarget: DefaultTexturePlatform 54 | maxTextureSize: 2048 55 | textureFormat: -1 56 | textureCompression: 1 57 | compressionQuality: 50 58 | crunchedCompression: 0 59 | allowsAlphaSplitting: 0 60 | overridden: 0 61 | - buildTarget: Standalone 62 | maxTextureSize: 2048 63 | textureFormat: -1 64 | textureCompression: 1 65 | compressionQuality: 50 66 | crunchedCompression: 0 67 | allowsAlphaSplitting: 0 68 | overridden: 0 69 | - buildTarget: XboxOne 70 | maxTextureSize: 2048 71 | textureFormat: -1 72 | textureCompression: 1 73 | compressionQuality: 50 74 | crunchedCompression: 0 75 | allowsAlphaSplitting: 0 76 | overridden: 0 77 | spriteSheet: 78 | serializedVersion: 2 79 | sprites: [] 80 | outline: [] 81 | spritePackingTag: 82 | userData: 83 | assetBundleName: 84 | assetBundleVariant: 85 | -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_DialogGUISkin.guiskin.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3b45f3e9000f1f04ab091ec625205e55 3 | timeCreated: 1489379728 4 | licenseType: Free 5 | NativeFormatImporter: 6 | mainObjectFileID: 11400000 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_MemHeapGUISkin.guiskin.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8c3a9b4d3278e8a4b91b3633e49f14c9 3 | timeCreated: 1489380430 4 | licenseType: Free 5 | NativeFormatImporter: 6 | mainObjectFileID: 11400000 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_NodeGUISkin.guiskin.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 893bf395d7e342a40906d5e5a56608f3 3 | timeCreated: 1489206589 4 | licenseType: Free 5 | NativeFormatImporter: 6 | mainObjectFileID: 11400000 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgMenu.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertoardila/support-unity-memoryprofiler/12e57074757ec7fa09983e6a1752e02acc45ace4/Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgMenu.jpg -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgMenu.jpg.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 109c7547ee47f4c4c9b5dfa2c63af04e 3 | timeCreated: 1489379545 4 | licenseType: Free 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -3 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | spriteMode: 0 41 | spriteExtrude: 1 42 | spriteMeshType: 1 43 | alignment: 0 44 | spritePivot: {x: 0.5, y: 0.5} 45 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 46 | spritePixelsToUnits: 100 47 | alphaIsTransparency: 0 48 | textureType: 0 49 | buildTargetSettings: [] 50 | spriteSheet: 51 | serializedVersion: 2 52 | sprites: [] 53 | outline: [] 54 | spritePackingTag: 55 | userData: 56 | assetBundleName: 57 | assetBundleVariant: 58 | -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindow2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertoardila/support-unity-memoryprofiler/12e57074757ec7fa09983e6a1752e02acc45ace4/Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindow2.png -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindow2.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2d74e967f59502342a1561ed451a0987 3 | timeCreated: 1489207781 4 | licenseType: Free 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -3 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | spriteMode: 0 41 | spriteExtrude: 1 42 | spriteMeshType: 1 43 | alignment: 0 44 | spritePivot: {x: 0.5, y: 0.5} 45 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 46 | spritePixelsToUnits: 100 47 | alphaIsTransparency: 0 48 | textureType: 0 49 | buildTargetSettings: [] 50 | spriteSheet: 51 | serializedVersion: 2 52 | sprites: [] 53 | outline: [] 54 | spritePackingTag: 55 | userData: 56 | assetBundleName: 57 | assetBundleVariant: 58 | -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindow3ON.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertoardila/support-unity-memoryprofiler/12e57074757ec7fa09983e6a1752e02acc45ace4/Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindow3ON.png -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindow3ON.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9ffbe828544731b40aa284503ea46c9f 3 | timeCreated: 1489211839 4 | licenseType: Free 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -3 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | spriteMode: 0 41 | spriteExtrude: 1 42 | spriteMeshType: 1 43 | alignment: 0 44 | spritePivot: {x: 0.5, y: 0.5} 45 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 46 | spritePixelsToUnits: 100 47 | alphaIsTransparency: 0 48 | textureType: 0 49 | buildTargetSettings: [] 50 | spriteSheet: 51 | serializedVersion: 2 52 | sprites: [] 53 | outline: [] 54 | spritePackingTag: 55 | userData: 56 | assetBundleName: 57 | assetBundleVariant: 58 | -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 627b447a58049a4408abf8c810cb767a 3 | folderAsset: yes 4 | timeCreated: 1489364351 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest-blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertoardila/support-unity-memoryprofiler/12e57074757ec7fa09983e6a1752e02acc45ace4/Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest-blue.png -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest-blue.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 670275e215537914c8aac141bfa960e3 3 | timeCreated: 1489364351 4 | licenseType: Free 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -3 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | spriteMode: 0 41 | spriteExtrude: 1 42 | spriteMeshType: 1 43 | alignment: 0 44 | spritePivot: {x: 0.5, y: 0.5} 45 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 46 | spritePixelsToUnits: 100 47 | alphaIsTransparency: 0 48 | textureType: 0 49 | buildTargetSettings: [] 50 | spriteSheet: 51 | serializedVersion: 2 52 | sprites: [] 53 | outline: [] 54 | spritePackingTag: 55 | userData: 56 | assetBundleName: 57 | assetBundleVariant: 58 | -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest-green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertoardila/support-unity-memoryprofiler/12e57074757ec7fa09983e6a1752e02acc45ace4/Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest-green.png -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest-green.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 640d0aa78746eca40b0483b2ce75f44d 3 | timeCreated: 1489364351 4 | licenseType: Free 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -3 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | spriteMode: 0 41 | spriteExtrude: 1 42 | spriteMeshType: 1 43 | alignment: 0 44 | spritePivot: {x: 0.5, y: 0.5} 45 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 46 | spritePixelsToUnits: 100 47 | alphaIsTransparency: 0 48 | textureType: 0 49 | buildTargetSettings: [] 50 | spriteSheet: 51 | serializedVersion: 2 52 | sprites: [] 53 | outline: [] 54 | spritePackingTag: 55 | userData: 56 | assetBundleName: 57 | assetBundleVariant: 58 | -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest-orange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertoardila/support-unity-memoryprofiler/12e57074757ec7fa09983e6a1752e02acc45ace4/Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest-orange.png -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest-orange.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4e0e26a1544003a4d8adab4d77f26b14 3 | timeCreated: 1489364351 4 | licenseType: Free 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -3 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | spriteMode: 0 41 | spriteExtrude: 1 42 | spriteMeshType: 1 43 | alignment: 0 44 | spritePivot: {x: 0.5, y: 0.5} 45 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 46 | spritePixelsToUnits: 100 47 | alphaIsTransparency: 0 48 | textureType: 0 49 | buildTargetSettings: [] 50 | spriteSheet: 51 | serializedVersion: 2 52 | sprites: [] 53 | outline: [] 54 | spritePackingTag: 55 | userData: 56 | assetBundleName: 57 | assetBundleVariant: 58 | -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest-purple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertoardila/support-unity-memoryprofiler/12e57074757ec7fa09983e6a1752e02acc45ace4/Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest-purple.png -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest-purple.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3a2ba5c3cdf2b7a41a4fcad70dfde22f 3 | timeCreated: 1489364351 4 | licenseType: Free 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -3 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | spriteMode: 0 41 | spriteExtrude: 1 42 | spriteMeshType: 1 43 | alignment: 0 44 | spritePivot: {x: 0.5, y: 0.5} 45 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 46 | spritePixelsToUnits: 100 47 | alphaIsTransparency: 0 48 | textureType: 0 49 | buildTargetSettings: [] 50 | spriteSheet: 51 | serializedVersion: 2 52 | sprites: [] 53 | outline: [] 54 | spritePackingTag: 55 | userData: 56 | assetBundleName: 57 | assetBundleVariant: 58 | -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest-red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertoardila/support-unity-memoryprofiler/12e57074757ec7fa09983e6a1752e02acc45ace4/Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest-red.png -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest-red.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b992ad746b72ffd4d8c99968c5b6a026 3 | timeCreated: 1489364351 4 | licenseType: Free 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -3 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | spriteMode: 0 41 | spriteExtrude: 1 42 | spriteMeshType: 1 43 | alignment: 0 44 | spritePivot: {x: 0.5, y: 0.5} 45 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 46 | spritePixelsToUnits: 100 47 | alphaIsTransparency: 0 48 | textureType: 0 49 | buildTargetSettings: [] 50 | spriteSheet: 51 | serializedVersion: 2 52 | sprites: [] 53 | outline: [] 54 | spritePackingTag: 55 | userData: 56 | assetBundleName: 57 | assetBundleVariant: 58 | -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest2-blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertoardila/support-unity-memoryprofiler/12e57074757ec7fa09983e6a1752e02acc45ace4/Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest2-blue.png -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest2-blue.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5dc000f00b44c00469ab936440437b07 3 | timeCreated: 1489364351 4 | licenseType: Free 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -3 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | spriteMode: 0 41 | spriteExtrude: 1 42 | spriteMeshType: 1 43 | alignment: 0 44 | spritePivot: {x: 0.5, y: 0.5} 45 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 46 | spritePixelsToUnits: 100 47 | alphaIsTransparency: 0 48 | textureType: 0 49 | buildTargetSettings: [] 50 | spriteSheet: 51 | serializedVersion: 2 52 | sprites: [] 53 | outline: [] 54 | spritePackingTag: 55 | userData: 56 | assetBundleName: 57 | assetBundleVariant: 58 | -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest2-green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertoardila/support-unity-memoryprofiler/12e57074757ec7fa09983e6a1752e02acc45ace4/Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest2-green.png -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest2-green.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0074d2f4d724c9f4584fd970586c3a56 3 | timeCreated: 1489364351 4 | licenseType: Free 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -3 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | spriteMode: 0 41 | spriteExtrude: 1 42 | spriteMeshType: 1 43 | alignment: 0 44 | spritePivot: {x: 0.5, y: 0.5} 45 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 46 | spritePixelsToUnits: 100 47 | alphaIsTransparency: 0 48 | textureType: 0 49 | buildTargetSettings: [] 50 | spriteSheet: 51 | serializedVersion: 2 52 | sprites: [] 53 | outline: [] 54 | spritePackingTag: 55 | userData: 56 | assetBundleName: 57 | assetBundleVariant: 58 | -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest2-orange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertoardila/support-unity-memoryprofiler/12e57074757ec7fa09983e6a1752e02acc45ace4/Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest2-orange.png -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest2-orange.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8d3f67714faea594cbde2ff56fbe4f24 3 | timeCreated: 1489364351 4 | licenseType: Free 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -3 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | spriteMode: 0 41 | spriteExtrude: 1 42 | spriteMeshType: 1 43 | alignment: 0 44 | spritePivot: {x: 0.5, y: 0.5} 45 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 46 | spritePixelsToUnits: 100 47 | alphaIsTransparency: 0 48 | textureType: 0 49 | buildTargetSettings: [] 50 | spriteSheet: 51 | serializedVersion: 2 52 | sprites: [] 53 | outline: [] 54 | spritePackingTag: 55 | userData: 56 | assetBundleName: 57 | assetBundleVariant: 58 | -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest2-purple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertoardila/support-unity-memoryprofiler/12e57074757ec7fa09983e6a1752e02acc45ace4/Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest2-purple.png -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest2-purple.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d68da63d7fab06b47b75483bb17f90ea 3 | timeCreated: 1489364351 4 | licenseType: Free 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -3 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | spriteMode: 0 41 | spriteExtrude: 1 42 | spriteMeshType: 1 43 | alignment: 0 44 | spritePivot: {x: 0.5, y: 0.5} 45 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 46 | spritePixelsToUnits: 100 47 | alphaIsTransparency: 0 48 | textureType: 0 49 | buildTargetSettings: [] 50 | spriteSheet: 51 | serializedVersion: 2 52 | sprites: [] 53 | outline: [] 54 | spritePackingTag: 55 | userData: 56 | assetBundleName: 57 | assetBundleVariant: 58 | -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest2-red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertoardila/support-unity-memoryprofiler/12e57074757ec7fa09983e6a1752e02acc45ace4/Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest2-red.png -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest2-red.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 849d63f453113a84a92854d9ccc8a197 3 | timeCreated: 1489364351 4 | licenseType: Free 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -3 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | spriteMode: 0 41 | spriteExtrude: 1 42 | spriteMeshType: 1 43 | alignment: 0 44 | spritePivot: {x: 0.5, y: 0.5} 45 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 46 | spritePixelsToUnits: 100 47 | alphaIsTransparency: 0 48 | textureType: 0 49 | buildTargetSettings: [] 50 | spriteSheet: 51 | serializedVersion: 2 52 | sprites: [] 53 | outline: [] 54 | spritePackingTag: 55 | userData: 56 | assetBundleName: 57 | assetBundleVariant: 58 | -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertoardila/support-unity-memoryprofiler/12e57074757ec7fa09983e6a1752e02acc45ace4/Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest2.png -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest2.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0260d191b614a31479cd596d5c51dc49 3 | timeCreated: 1489364351 4 | licenseType: Free 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -3 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | spriteMode: 0 41 | spriteExtrude: 1 42 | spriteMeshType: 1 43 | alignment: 0 44 | spritePivot: {x: 0.5, y: 0.5} 45 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 46 | spritePixelsToUnits: 100 47 | alphaIsTransparency: 0 48 | textureType: 0 49 | buildTargetSettings: [] 50 | spriteSheet: 51 | serializedVersion: 2 52 | sprites: [] 53 | outline: [] 54 | spritePackingTag: 55 | userData: 56 | assetBundleName: 57 | assetBundleVariant: 58 | -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest_img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertoardila/support-unity-memoryprofiler/12e57074757ec7fa09983e6a1752e02acc45ace4/Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest_img.png -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_bgWindowtest/MemoryProfiler_bgWindowtest_img.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3c44eacbbdd44a647a99f4a8e887455a 3 | timeCreated: 1489364351 4 | licenseType: Free 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -3 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | spriteMode: 0 41 | spriteExtrude: 1 42 | spriteMeshType: 1 43 | alignment: 0 44 | spritePivot: {x: 0.5, y: 0.5} 45 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 46 | spritePixelsToUnits: 100 47 | alphaIsTransparency: 0 48 | textureType: 0 49 | buildTargetSettings: [] 50 | spriteSheet: 51 | serializedVersion: 2 52 | sprites: [] 53 | outline: [] 54 | spritePackingTag: 55 | userData: 56 | assetBundleName: 57 | assetBundleVariant: 58 | -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_heapsection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertoardila/support-unity-memoryprofiler/12e57074757ec7fa09983e6a1752e02acc45ace4/Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_heapsection.png -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_heapsection.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 602e9c0ab8f28e34dbf12591a0f7df6b 3 | timeCreated: 1489380397 4 | licenseType: Free 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -3 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | spriteMode: 0 41 | spriteExtrude: 1 42 | spriteMeshType: 1 43 | alignment: 0 44 | spritePivot: {x: 0.5, y: 0.5} 45 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 46 | spritePixelsToUnits: 100 47 | alphaIsTransparency: 0 48 | textureType: 0 49 | buildTargetSettings: [] 50 | spriteSheet: 51 | serializedVersion: 2 52 | sprites: [] 53 | outline: [] 54 | spritePackingTag: 55 | userData: 56 | assetBundleName: 57 | assetBundleVariant: 58 | -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_memSegment.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertoardila/support-unity-memoryprofiler/12e57074757ec7fa09983e6a1752e02acc45ace4/Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_memSegment.jpg -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_memSegment.jpg.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 94d4b1074a71be241a893c8568d68a38 3 | timeCreated: 1489381935 4 | licenseType: Free 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -3 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | spriteMode: 0 41 | spriteExtrude: 1 42 | spriteMeshType: 1 43 | alignment: 0 44 | spritePivot: {x: 0.5, y: 0.5} 45 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 46 | spritePixelsToUnits: 100 47 | alphaIsTransparency: 0 48 | textureType: 0 49 | buildTargetSettings: [] 50 | spriteSheet: 51 | serializedVersion: 2 52 | sprites: [] 53 | outline: [] 54 | spritePackingTag: 55 | userData: 56 | assetBundleName: 57 | assetBundleVariant: 58 | -------------------------------------------------------------------------------- /Assets/Editor Default Resources/MemoryProfiler_EditorResources/MemoryProfiler_memSegmentGUISkin.guiskin.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a758ec10fff0d4b4dbe1bf2a9308779f 3 | timeCreated: 1489381692 4 | licenseType: Free 5 | NativeFormatImporter: 6 | mainObjectFileID: 11400000 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 52a3a78daeceee1408f51de4c6f2f691 3 | folderAsset: yes 4 | timeCreated: 1432403102 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 966fae9e20e62ff4d887e0f2be6ecb2c 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/ArrayTools.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEditor.MemoryProfiler; 3 | 4 | namespace MemoryProfilerWindow 5 | { 6 | static class ArrayTools 7 | { 8 | public static int ReadArrayLength(MemorySection[] heap, UInt64 address, TypeDescription arrayType, VirtualMachineInformation virtualMachineInformation) 9 | { 10 | var bo = heap.Find(address, virtualMachineInformation); 11 | 12 | var bounds = bo.Add(virtualMachineInformation.arrayBoundsOffsetInHeader).ReadPointer(); 13 | 14 | if (bounds == 0) 15 | #if UNITY_2017_2_OR_NEWER 16 | return (int)bo.Add(virtualMachineInformation.arraySizeOffsetInHeader).ReadPointer(); 17 | #else 18 | return bo.Add(virtualMachineInformation.arraySizeOffsetInHeader).ReadInt32(); 19 | #endif 20 | 21 | var cursor = heap.Find(bounds, virtualMachineInformation); 22 | int length = 1; 23 | for (int i = 0; i != arrayType.arrayRank; i++) 24 | { 25 | #if UNITY_2017_2_OR_NEWER 26 | length *= (int)cursor.ReadPointer(); 27 | cursor = cursor.Add(virtualMachineInformation.pointerSize == 4 ? 8 : 16); 28 | #else 29 | length *= cursor.ReadInt32(); 30 | cursor = cursor.Add(8); 31 | #endif 32 | } 33 | return length; 34 | } 35 | 36 | public static int ReadArrayObjectSizeInBytes(MemorySection[] heap, UInt64 address, TypeDescription arrayType, TypeDescription[] typeDescriptions, VirtualMachineInformation virtualMachineInformation) 37 | { 38 | var arrayLength = ArrayTools.ReadArrayLength(heap, address, arrayType, virtualMachineInformation); 39 | var elementType = typeDescriptions[arrayType.baseOrElementTypeIndex]; 40 | var elementSize = elementType.isValueType ? elementType.size : virtualMachineInformation.pointerSize; 41 | return virtualMachineInformation.arrayHeaderSize + elementSize * arrayLength; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/ArrayTools.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e20fa82f0247e497ca4a3d7727b24347 3 | timeCreated: 1445457365 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/BytesAndOffset.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEditor.MemoryProfiler; 3 | using UnityEngine; 4 | 5 | namespace MemoryProfilerWindow 6 | { 7 | internal struct BytesAndOffset 8 | { 9 | public byte[] bytes; 10 | public int offset; 11 | public int pointerSize; 12 | public bool IsValid { get { return bytes != null; }} 13 | 14 | public UInt64 ReadPointer() 15 | { 16 | if (pointerSize == 4) 17 | return BitConverter.ToUInt32(bytes, offset); 18 | if (pointerSize == 8) 19 | return BitConverter.ToUInt64(bytes, offset); 20 | throw new ArgumentException("Unexpected pointersize: " + pointerSize); 21 | } 22 | 23 | public Int32 ReadInt32() 24 | { 25 | return BitConverter.ToInt32(bytes, offset); 26 | } 27 | 28 | public Int64 ReadInt64() 29 | { 30 | return BitConverter.ToInt64(bytes, offset); 31 | } 32 | 33 | public BytesAndOffset Add(int add) 34 | { 35 | return new BytesAndOffset() {bytes = bytes, offset = offset + add, pointerSize = pointerSize}; 36 | } 37 | 38 | public void WritePointer(UInt64 value) 39 | { 40 | for (int i = 0; i < pointerSize; i++) 41 | { 42 | bytes[i + offset] = (byte)value; 43 | value >>= 8; 44 | } 45 | } 46 | 47 | public BytesAndOffset NextPointer() 48 | { 49 | return Add(pointerSize); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/BytesAndOffset.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 17dff322d0105c647a1ba2740c211d5d 3 | timeCreated: 1439890711 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/CrawledDataUnpacker.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using UnityEditor.MemoryProfiler; 4 | using System; 5 | using UnityEngine; 6 | 7 | namespace MemoryProfilerWindow 8 | { 9 | class CrawlDataUnpacker 10 | { 11 | public static CrawledMemorySnapshot Unpack(PackedCrawlerData packedCrawlerData) 12 | { 13 | var packedSnapshot = packedCrawlerData.packedMemorySnapshot; 14 | 15 | var result = new CrawledMemorySnapshot 16 | { 17 | nativeObjects = packedSnapshot.nativeObjects.Select(packedNativeUnityEngineObject => UnpackNativeUnityEngineObject(packedSnapshot, packedNativeUnityEngineObject)).ToArray(), 18 | managedObjects = packedCrawlerData.managedObjects.Select(pm => UnpackManagedObject(packedSnapshot, pm)).ToArray(), 19 | gcHandles = packedSnapshot.gcHandles.Select(pgc => UnpackGCHandle(packedSnapshot)).ToArray(), 20 | staticFields = packedSnapshot.typeDescriptions.Where(t => t.staticFieldBytes != null & t.staticFieldBytes.Length > 0).Select(t => UnpackStaticFields(t)).ToArray(), 21 | typeDescriptions = packedSnapshot.typeDescriptions, 22 | managedHeap = packedSnapshot.managedHeapSections, 23 | nativeTypes = packedSnapshot.nativeTypes, 24 | virtualMachineInformation = packedSnapshot.virtualMachineInformation 25 | }; 26 | 27 | result.FinishSnapshot(); 28 | 29 | var referencesLists = MakeTempLists(result.allObjects); 30 | var referencedByLists = MakeTempLists(result.allObjects); 31 | 32 | foreach (var connection in packedCrawlerData.connections) 33 | { 34 | referencesLists[connection.@from].Add(result.allObjects[connection.to]); 35 | referencedByLists[connection.to].Add(result.allObjects[connection.@from]); 36 | } 37 | 38 | for (var i = 0; i != result.allObjects.Length; i++) 39 | { 40 | result.allObjects[i].references = referencesLists[i].ToArray(); 41 | result.allObjects[i].referencedBy = referencedByLists[i].ToArray(); 42 | } 43 | 44 | return result; 45 | } 46 | 47 | static List[] MakeTempLists(ThingInMemory[] combined) 48 | { 49 | var referencesLists = new List[combined.Length]; 50 | for (int i = 0; i != referencesLists.Length; i++) 51 | referencesLists[i] = new List(4); 52 | return referencesLists; 53 | } 54 | 55 | static StaticFields UnpackStaticFields(TypeDescription typeDescription) 56 | { 57 | return new StaticFields() 58 | { 59 | typeDescription = typeDescription, 60 | caption = "static fields of " + typeDescription.name, 61 | size = typeDescription.staticFieldBytes.Length 62 | }; 63 | } 64 | 65 | static GCHandle UnpackGCHandle(PackedMemorySnapshot packedSnapshot) 66 | { 67 | return new GCHandle() { size = packedSnapshot.virtualMachineInformation.pointerSize, caption = "gchandle" }; 68 | } 69 | 70 | static ManagedObject UnpackManagedObject(PackedMemorySnapshot packedSnapshot, PackedManagedObject pm) 71 | { 72 | var typeDescription = packedSnapshot.typeDescriptions[pm.typeIndex]; 73 | return new ManagedObject() { address = pm.address, size = pm.size, typeDescription = typeDescription, caption = typeDescription.name }; 74 | } 75 | 76 | static NativeUnityEngineObject UnpackNativeUnityEngineObject(PackedMemorySnapshot packedSnapshot, PackedNativeUnityEngineObject packedNativeUnityEngineObject) 77 | { 78 | #if UNITY_5_6_OR_NEWER 79 | var classId = packedNativeUnityEngineObject.nativeTypeArrayIndex; 80 | #else 81 | var classId = packedNativeUnityEngineObject.classId; 82 | #endif 83 | var className = packedSnapshot.nativeTypes[classId].name; 84 | 85 | return new NativeUnityEngineObject() 86 | { 87 | instanceID = packedNativeUnityEngineObject.instanceId, 88 | classID = classId, 89 | className = className, 90 | name = packedNativeUnityEngineObject.name, 91 | caption = packedNativeUnityEngineObject.name + "(" + className + ")", 92 | size = packedNativeUnityEngineObject.size, 93 | isPersistent = packedNativeUnityEngineObject.isPersistent, 94 | isDontDestroyOnLoad = packedNativeUnityEngineObject.isDontDestroyOnLoad, 95 | isManager = packedNativeUnityEngineObject.isManager, 96 | hideFlags = packedNativeUnityEngineObject.hideFlags 97 | }; 98 | } 99 | } 100 | 101 | [System.Serializable] 102 | internal class PackedCrawlerData 103 | { 104 | public bool valid; 105 | public PackedMemorySnapshot packedMemorySnapshot; 106 | public StartIndices startIndices; 107 | public PackedManagedObject[] managedObjects; 108 | public TypeDescription[] typesWithStaticFields; 109 | public Connection[] connections; 110 | 111 | public PackedCrawlerData(PackedMemorySnapshot packedMemorySnapshot) 112 | { 113 | this.packedMemorySnapshot = packedMemorySnapshot; 114 | typesWithStaticFields = packedMemorySnapshot.typeDescriptions.Where(t => t.staticFieldBytes != null && t.staticFieldBytes.Length > 0).ToArray(); 115 | startIndices = new StartIndices(this.packedMemorySnapshot.gcHandles.Length, this.packedMemorySnapshot.nativeObjects.Length, typesWithStaticFields.Length); 116 | valid = true; 117 | } 118 | } 119 | 120 | [System.Serializable] 121 | internal class StartIndices 122 | { 123 | [SerializeField] 124 | private int _gcHandleCount; 125 | [SerializeField] 126 | private int _nativeObjectCount; 127 | [SerializeField] 128 | private int _staticFieldsCount; 129 | 130 | public StartIndices(int gcHandleCount, int nativeObjectCount, int staticFieldsCount) 131 | { 132 | _gcHandleCount = gcHandleCount; 133 | _nativeObjectCount = nativeObjectCount; 134 | _staticFieldsCount = staticFieldsCount; 135 | } 136 | 137 | public int OfFirstGCHandle { get { return 0; } } 138 | public int OfFirstNativeObject { get { return OfFirstGCHandle + _gcHandleCount; } } 139 | public int OfFirstStaticFields { get { return OfFirstNativeObject + _nativeObjectCount; } } 140 | public int OfFirstManagedObject { get { return OfFirstStaticFields + _staticFieldsCount; } } 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/CrawledDataUnpacker.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d52be8d081446344794efd95a14c273d 3 | timeCreated: 1439890712 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/Crawler.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ae07d627ccc258641a3258382d2c45c1 3 | timeCreated: 1439890712 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/HighLevelAPI.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEditor.MemoryProfiler; 3 | using UnityEngine; 4 | 5 | namespace MemoryProfilerWindow 6 | { 7 | using System.Linq; 8 | 9 | //this is the highest level dataformat. it can be unpacked from the PackedCrawledMemorySnapshot, which contains all the interesting information we want. The Packed format 10 | //however is designed to be serializable and relatively storage compact. This dataformat is designed to give a nice c# api experience. so while the packed version uses typeIndex, 11 | //this version has TypeReferences, and also uses references to ThingInObject, instead of the more obscure object indexing pattern that the packed format uses. 12 | public class CrawledMemorySnapshot 13 | { 14 | public NativeUnityEngineObject[] nativeObjects; 15 | public GCHandle[] gcHandles; 16 | public ManagedObject[] managedObjects; 17 | public StaticFields[] staticFields; 18 | 19 | //contains concatenation of nativeObjects, gchandles, managedobjects and staticfields 20 | public ThingInMemory[] allObjects { get; private set; } 21 | public long totalSize { get; private set; } 22 | 23 | public MemorySection[] managedHeap; 24 | public TypeDescription[] typeDescriptions; 25 | public PackedNativeType[] nativeTypes; 26 | public VirtualMachineInformation virtualMachineInformation; 27 | 28 | public void FinishSnapshot() 29 | { 30 | allObjects = new ThingInMemory[0].Concat(gcHandles).Concat(nativeObjects).Concat(staticFields).Concat(managedObjects).ToArray(); 31 | totalSize = allObjects != null ? allObjects.Sum(o => o.size) : 0; 32 | } 33 | } 34 | 35 | public class ThingInMemory 36 | { 37 | public long size; 38 | public string caption; 39 | public ThingInMemory[] references; 40 | public ThingInMemory[] referencedBy; 41 | } 42 | 43 | public class ManagedObject : ThingInMemory 44 | { 45 | public UInt64 address; 46 | public TypeDescription typeDescription; 47 | } 48 | 49 | public class NativeUnityEngineObject : ThingInMemory 50 | { 51 | public int instanceID; 52 | public int classID; 53 | public string className; 54 | public string name; 55 | public bool isPersistent; 56 | public bool isDontDestroyOnLoad; 57 | public bool isManager; 58 | public HideFlags hideFlags; 59 | } 60 | 61 | public class GCHandle : ThingInMemory 62 | { 63 | } 64 | 65 | public class StaticFields : ThingInMemory 66 | { 67 | public TypeDescription typeDescription; 68 | public byte[] storage; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/HighLevelAPI.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 21fba49b347b10745907bcceb882d245 3 | timeCreated: 1439890711 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/Inspector.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 672f532aba4334a09a58ce7e962e6fd6 3 | timeCreated: 1440674716 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/JsonDotNet20.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dba2f22229f460245b9f32498705a4d3 3 | folderAsset: yes 4 | timeCreated: 1489330402 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/JsonDotNet20/Newtonsoft.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertoardila/support-unity-memoryprofiler/12e57074757ec7fa09983e6a1752e02acc45ace4/Assets/Editor/MemoryProfiler/JsonDotNet20/Newtonsoft.Json.dll -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/JsonDotNet20/Newtonsoft.Json.dll.mdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertoardila/support-unity-memoryprofiler/12e57074757ec7fa09983e6a1752e02acc45ace4/Assets/Editor/MemoryProfiler/JsonDotNet20/Newtonsoft.Json.dll.mdb -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/JsonDotNet20/Newtonsoft.Json.dll.mdb.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 76edcd043f022e649b46f6a985ec0552 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/JsonDotNet20/Newtonsoft.Json.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e08242ffd6dd024438b76739bdfaafcf 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | isPreloaded: 0 9 | isOverridable: 0 10 | platformData: 11 | - first: 12 | Any: 13 | second: 14 | enabled: 0 15 | settings: {} 16 | - first: 17 | Editor: Editor 18 | second: 19 | enabled: 1 20 | settings: 21 | DefaultValueInitialized: true 22 | - first: 23 | Windows Store Apps: WindowsStoreApps 24 | second: 25 | enabled: 0 26 | settings: 27 | CPU: AnyCPU 28 | userData: 29 | assetBundleName: 30 | assetBundleVariant: 31 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/JsonDotNet20/Newtonsoft.Json.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertoardila/support-unity-memoryprofiler/12e57074757ec7fa09983e6a1752e02acc45ace4/Assets/Editor/MemoryProfiler/JsonDotNet20/Newtonsoft.Json.pdb -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/JsonDotNet20/Newtonsoft.Json.pdb.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d9f72a2d6324be0428e7d3b04f10bbb8 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/JsonDotNet20/Newtonsoft.Json.xml.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f3448b76a8c7d134b97c0e770eae6ccd 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/JsonDotNet20/license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2007 James Newton-King 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | software and associated documentation files (the "Software"), to deal in the Software 5 | without restriction, including without limitation the rights to use, copy, modify, 6 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | permit persons to whom the Software is furnished to do so, subject to the following 8 | conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all copies 11 | or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 14 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 15 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 16 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 17 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 18 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/JsonDotNet20/license.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 73b3de375a4be6943a787a1b16448963 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/JsonDotNet20/readme.txt: -------------------------------------------------------------------------------- 1 | Json.NET 2 | 3 | http://www.newtonsoft.com/json 4 | https://github.com/JamesNK/Newtonsoft.Json 5 | 6 | 7 | Description: 8 | 9 | Json.NET is a popular high-performance JSON framework for .NET 10 | 11 | -Flexible JSON serializer for converting between .NET objects and JSON 12 | -LINQ to JSON for manually reading and writing JSON 13 | -High performance, faster than .NET's built-in JSON serializers 14 | -Write indented, easy to read JSON 15 | -Convert JSON to and from XML 16 | -Supports .NET 2, .NET 3.5, .NET 4, .NET 4.5, Silverlight, Windows Phone and Windows 8 Store 17 | 18 | 19 | Documentation: 20 | 21 | http://www.newtonsoft.com/json/help/ 22 | 23 | 24 | Versions: 25 | 26 | Json.NET has different libraries for the various .NET Framework versions. 27 | 28 | -Net45: 29 | .NET latest (4.5) 30 | 31 | -Net40: 32 | .NET 4.0 33 | 34 | -Net35: 35 | .NET 3.5 36 | 37 | -Net20: 38 | .NET 2.0, Unity 39 | 40 | -Portable45: 41 | .NET 4.5, Windows Phone 8, Windows 8 Store, .NET Core 42 | 43 | -Portable40: 44 | .NET 4.0, Windows Phone 8, Windows 8 Store, Silverlight 5, MonoTouch, MonoDroid 45 | 46 | 47 | Notes: 48 | 49 | For a Compact Framework 3.5 and Silverlight 3.0 builds download Json.NET 3.5 50 | For a Silverlight 4.0 and Windows Phone 7 builds download Json.NET 5 -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/JsonDotNet20/readme.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1e524a96ef9bca44588d13daf7b5fa21 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/LowLevelAPI.cs: -------------------------------------------------------------------------------- 1 | //the idea is to only expose the very very lowest level data in the unity api. this data is uncrawled. 2 | //you get the raw heap bytes, you get typedescriptions, and an overview of native objects, and that's it. 3 | // 4 | //the crawler, the higher level "c# idiomy api", and the UI window that uses that api 5 | //we can develop in an opensource github project, and iterate 6 | //on outside of the unity release trains. 7 | 8 | /* 9 | using System; 10 | 11 | namespace UnityEditor.Profiler.Memory 12 | { 13 | [Serializable] //note: this snapshot is completely serializable by unity's serializer. 14 | public class PackedMemorySnapshot 15 | { 16 | public PackedNativeUnityEngineObject[] nativeObjects; 17 | public PackedGCHandle[] gcHandles; 18 | public Connection[] connections; 19 | 20 | public ManagedHeap managedHeap; 21 | public TypeDescription[] typeDescriptions; 22 | public string[] classIDNames; 23 | } 24 | 25 | [Serializable] 26 | public struct PackedNativeUnityEngineObject 27 | { 28 | public string name; 29 | public int instanceID; 30 | public int size; 31 | public int classID; 32 | } 33 | 34 | [Serializable] 35 | public struct PackedGCHandle 36 | { 37 | public UInt64 target; 38 | } 39 | 40 | [Serializable] 41 | public struct Connection 42 | { 43 | //these indices index into an imaginary array that is the concatenation of snapshot.nativeObject + snapshot.gcHandles snapshot. 44 | public int from; 45 | public int to; 46 | } 47 | 48 | [Serializable] 49 | public class ManagedHeap 50 | { 51 | public HeapSegment[] segments; 52 | public VirtualMachineInformation virtualMachineInformation; 53 | } 54 | 55 | [Serializable] 56 | public class HeapSegment 57 | { 58 | public byte[] bytes; 59 | public UInt64 startAddress; 60 | } 61 | 62 | [Serializable] 63 | public struct VirtualMachineInformation 64 | { 65 | public int pointerSize; 66 | public int objectHeaderSize; 67 | public int arrayHeaderSize; 68 | public int arrayBoundsOffsetInHeader; 69 | public int arraySizeOffsetInHeader; 70 | public int allocationGranularity; 71 | }; 72 | 73 | [Serializable] 74 | public class TypeDescription 75 | { 76 | public string name; 77 | public string fullname; 78 | public int @namespace; 79 | public int assembly; 80 | public FieldDescription[] fields; 81 | public byte[] staticFieldBytes; 82 | public int baseOrElementTypeIndex; 83 | public int size; 84 | public UInt64 typeInfoAddress; 85 | public int typeIndex; 86 | 87 | public bool IsValueType 88 | { 89 | get { return (flags & TypeFlags.kValueType) != 0; } 90 | } 91 | 92 | public bool IsArray 93 | { 94 | get { return (flags & TypeFlags.kArray) != 0; } 95 | } 96 | 97 | public int ArrayRank 98 | { 99 | get { return (int) (flags & TypeFlags.kArrayRankMask) >> 16; } 100 | } 101 | 102 | private TypeFlags flags; 103 | 104 | private enum TypeFlags 105 | { 106 | kNone = 0, 107 | kValueType = 1 << 0, 108 | kArray = 1 << 1, 109 | kArrayRankMask = unchecked((int) 0xFFFF0000) 110 | }; 111 | } 112 | 113 | [Serializable] 114 | public class FieldDescription 115 | { 116 | public string name; 117 | public int offset; 118 | public int typeIndex; 119 | public bool isStatic; 120 | } 121 | }*/ 122 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/LowLevelAPI.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 237ab36fcc3d4b94089b7a320ad1c713 3 | timeCreated: 1439890711 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/ManagedHeapExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEditor.MemoryProfiler; 3 | 4 | namespace MemoryProfilerWindow 5 | { 6 | static class ManagedHeapExtensions 7 | { 8 | public static BytesAndOffset Find(this MemorySection[] heap, UInt64 address, VirtualMachineInformation virtualMachineInformation) 9 | { 10 | foreach (var segment in heap) 11 | if (address >= segment.startAddress && address < (segment.startAddress + (ulong)segment.bytes.Length)) 12 | return new BytesAndOffset() { bytes = segment.bytes, offset = (int)(address - segment.startAddress), pointerSize = virtualMachineInformation.pointerSize }; 13 | 14 | return new BytesAndOffset(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/ManagedHeapExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4d35e96d7e653ea46abaa023f6dc6779 3 | timeCreated: 1439890712 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/MemoryProfilerWindow.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel; 3 | using System.Linq; 4 | using Assets.Editor.Treemap; 5 | using Treemap; 6 | using UnityEditor; 7 | using UnityEngine; 8 | using System; 9 | using System.Net; 10 | using NUnit.Framework.Constraints; 11 | using UnityEditor.MemoryProfiler; 12 | using Object = UnityEngine.Object; 13 | using System.IO; 14 | 15 | namespace MemoryProfilerWindow 16 | { 17 | public class MemoryProfilerWindow : EditorWindow 18 | { 19 | [NonSerialized] 20 | UnityEditor.MemoryProfiler.PackedMemorySnapshot _snapshot; 21 | 22 | [SerializeField] 23 | PackedCrawlerData _packedCrawled; 24 | 25 | [NonSerialized] 26 | CrawledMemorySnapshot _unpackedCrawl; 27 | 28 | Vector2 _scrollPosition; 29 | 30 | [NonSerialized] 31 | private bool _registered = false; 32 | public Inspector _inspector; 33 | TreeMapView _treeMapView; 34 | 35 | [MenuItem("Window/MemoryProfiler")] 36 | static void Create() 37 | { 38 | EditorWindow.GetWindow(); 39 | } 40 | 41 | [MenuItem("Window/MemoryProfilerInspect")] 42 | static void Inspect() 43 | { 44 | } 45 | 46 | public void OnDestroy() 47 | { 48 | UnityEditor.MemoryProfiler.MemorySnapshot.OnSnapshotReceived -= IncomingSnapshot; 49 | 50 | if (_treeMapView != null) 51 | _treeMapView.CleanupMeshes (); 52 | } 53 | 54 | public void Initialize() 55 | { 56 | if (_treeMapView == null) 57 | _treeMapView = new TreeMapView (); 58 | 59 | if (!_registered) 60 | { 61 | UnityEditor.MemoryProfiler.MemorySnapshot.OnSnapshotReceived += IncomingSnapshot; 62 | _registered = true; 63 | } 64 | 65 | if (_unpackedCrawl == null && _packedCrawled != null && _packedCrawled.valid) 66 | Unpack(); 67 | 68 | 69 | } 70 | 71 | void OnGUI() 72 | { 73 | Initialize(); 74 | 75 | GUILayout.BeginHorizontal(); 76 | if (GUILayout.Button("Take Snapshot")) 77 | { 78 | UnityEditor.EditorUtility.DisplayProgressBar("Take Snapshot", "Downloading Snapshot...", 0.0f); 79 | try 80 | { 81 | UnityEditor.MemoryProfiler.MemorySnapshot.RequestNewSnapshot(); 82 | } 83 | finally 84 | { 85 | EditorUtility.ClearProgressBar(); 86 | } 87 | } 88 | 89 | EditorGUI.BeginDisabledGroup(_snapshot == null); 90 | if (GUILayout.Button("Save Snapshot...")) 91 | { 92 | PackedMemorySnapshotUtility.SaveToFile(_snapshot); 93 | } 94 | EditorGUI.EndDisabledGroup(); 95 | 96 | if (GUILayout.Button("Load Snapshot...")) 97 | { 98 | PackedMemorySnapshot packedSnapshot = PackedMemorySnapshotUtility.LoadFromFile(); 99 | if(packedSnapshot != null) 100 | IncomingSnapshot(packedSnapshot); 101 | } 102 | 103 | if (_unpackedCrawl != null) 104 | { 105 | GUILayout.Label(string.Format("Total memory: {0}", EditorUtility.FormatBytes(_unpackedCrawl.totalSize))); 106 | } 107 | GUILayout.EndHorizontal(); 108 | if (_treeMapView != null) 109 | _treeMapView.Draw(); 110 | if (_inspector != null) 111 | _inspector.Draw(); 112 | 113 | //RenderDebugList(); 114 | } 115 | 116 | public void SelectThing(ThingInMemory thing) 117 | { 118 | _inspector.SelectThing(thing); 119 | _treeMapView.SelectThing(thing); 120 | } 121 | 122 | public void SelectGroup(Group group) 123 | { 124 | _treeMapView.SelectGroup(group); 125 | } 126 | 127 | private void RenderDebugList() 128 | { 129 | _scrollPosition = GUILayout.BeginScrollView(_scrollPosition); 130 | 131 | foreach (var thing in _unpackedCrawl.allObjects) 132 | { 133 | var mo = thing as ManagedObject; 134 | if (mo != null) 135 | GUILayout.Label("MO: " + mo.typeDescription.name); 136 | 137 | var gch = thing as GCHandle; 138 | if (gch != null) 139 | GUILayout.Label("GCH: " + gch.caption); 140 | 141 | var sf = thing as StaticFields; 142 | if (sf != null) 143 | GUILayout.Label("SF: " + sf.typeDescription.name); 144 | } 145 | 146 | GUILayout.EndScrollView(); 147 | } 148 | 149 | void Unpack() 150 | { 151 | _unpackedCrawl = CrawlDataUnpacker.Unpack(_packedCrawled); 152 | _inspector = new Inspector(this, _unpackedCrawl, _snapshot); 153 | 154 | if(_treeMapView != null) 155 | _treeMapView.Setup(this, _unpackedCrawl); 156 | } 157 | 158 | void IncomingSnapshot(PackedMemorySnapshot snapshot) 159 | { 160 | _snapshot = snapshot; 161 | 162 | UnityEditor.EditorUtility.DisplayProgressBar("Take Snapshot", "Crawling Snapshot...", 0.33f); 163 | try 164 | { 165 | _packedCrawled = new Crawler().Crawl(_snapshot); 166 | 167 | UnityEditor.EditorUtility.DisplayProgressBar("Take Snapshot", "Unpacking Snapshot...", 0.67f); 168 | 169 | Unpack(); 170 | } 171 | finally 172 | { 173 | UnityEditor.EditorUtility.ClearProgressBar(); 174 | } 175 | } 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/MemoryProfilerWindow.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e9b3c90455aa77e41a907149f43e2d87 3 | timeCreated: 1439890712 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/PackedManagedObject.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MemoryProfilerWindow 4 | { 5 | [Serializable] 6 | public class PackedManagedObject 7 | { 8 | public UInt64 address; 9 | public int typeIndex; 10 | public int size; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/PackedManagedObject.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 56505e613e7b9413db3e16e8764bd4f6 3 | timeCreated: 1440658182 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/PackedMemorySnapshotUtility.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using UnityEngine; 3 | using UnityEditor; 4 | using UnityEditor.MemoryProfiler; 5 | using Newtonsoft.Json; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System; 10 | using System.Reflection; 11 | using Newtonsoft.Json.Serialization; 12 | 13 | #if UNITY_5_5_OR_NEWER 14 | using Profiler = UnityEngine.Profiling.Profiler; 15 | #else 16 | using Profiler = UnityEngine.Profiler; 17 | #endif 18 | 19 | public static class PackedMemorySnapshotUtility 20 | { 21 | 22 | private static string previousDirectory = null; 23 | 24 | public static void SaveToFile(PackedMemorySnapshot snapshot) 25 | { 26 | var filePath = EditorUtility.SaveFilePanel("Save Snapshot", previousDirectory, "MemorySnapshot (" + DateTime.Now.ToString("dd-MM-yyyy hh-mm-ss") + ")", "memsnap3"); 27 | if(string.IsNullOrEmpty(filePath)) 28 | return; 29 | 30 | previousDirectory = Path.GetDirectoryName(filePath); 31 | SaveToFile(filePath, snapshot); 32 | } 33 | 34 | static void SaveToFile(string filePath, PackedMemorySnapshot snapshot) 35 | { 36 | // Saving snapshots using JsonUtility, instead of BinaryFormatter, is significantly faster. 37 | // I cancelled saving a memory snapshot that is saving using BinaryFormatter after 24 hours. 38 | // Saving the same memory snapshot using JsonUtility.ToJson took 20 seconds only. 39 | 40 | Debug.LogFormat("Saving..."); 41 | System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch(); 42 | Profiler.BeginSample("PackedMemorySnapshotUtility.SaveToFile"); 43 | stopwatch.Start(); 44 | 45 | string fileExtension = Path.GetExtension(filePath); 46 | if (string.Equals(fileExtension, ".memsnap", System.StringComparison.OrdinalIgnoreCase)) { 47 | System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); 48 | using (Stream stream = File.Open(filePath, FileMode.Create)) { 49 | bf.Serialize(stream, snapshot); 50 | } 51 | } else if (string.Equals(fileExtension, ".memsnap2", System.StringComparison.OrdinalIgnoreCase)) { 52 | var json = JsonUtility.ToJson(snapshot); 53 | File.WriteAllText(filePath, json); 54 | } else { // memsnap3 + default 55 | // Stream writing -- will not to exhaust memory (for large snapshots) 56 | using (TextWriter writer = File.CreateText(filePath)) { 57 | var errors = new List(); 58 | var serializer = getSerializer(errors); 59 | serializer.Serialize(writer, snapshot); 60 | logErrors(errors); 61 | } 62 | } 63 | 64 | stopwatch.Stop(); 65 | Profiler.EndSample(); 66 | Debug.LogFormat("Saving took {0}ms", stopwatch.ElapsedMilliseconds); 67 | } 68 | 69 | public static PackedMemorySnapshot LoadFromFile() 70 | { 71 | var filePath = EditorUtility.OpenFilePanelWithFilters("Load Snapshot", previousDirectory, new[] { "Snapshots", "memsnap3,memsnap2,memsnap" }); 72 | if(string.IsNullOrEmpty(filePath)) 73 | return null; 74 | 75 | previousDirectory = Path.GetDirectoryName(filePath); 76 | Debug.LogFormat("Loading \"{0}\"", filePath); 77 | var packedSnapshot = LoadFromFile(filePath); 78 | Debug.LogFormat("Completed loading \"{0}\"", filePath); 79 | return packedSnapshot; 80 | } 81 | 82 | static PackedMemorySnapshot LoadFromFile(string filePath) 83 | { 84 | Debug.LogFormat("Loading..."); 85 | System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch(); 86 | PackedMemorySnapshot result; 87 | string fileExtension = Path.GetExtension(filePath); 88 | 89 | if (string.Equals(fileExtension, ".memsnap3", System.StringComparison.OrdinalIgnoreCase)) { 90 | Profiler.BeginSample("PackedMemorySnapshotUtility.LoadFromFile(litjson)"); 91 | stopwatch.Start(); 92 | 93 | using (TextReader reader = File.OpenText(filePath)) { 94 | var errors = new List(); 95 | var serializer = getSerializer(errors); 96 | result = (PackedMemorySnapshot) serializer.Deserialize(reader, typeof(PackedMemorySnapshot)); 97 | logErrors(errors); 98 | } 99 | 100 | stopwatch.Stop(); 101 | Profiler.EndSample(); 102 | } 103 | else if(string.Equals(fileExtension, ".memsnap2", System.StringComparison.OrdinalIgnoreCase)) 104 | { 105 | Profiler.BeginSample("PackedMemorySnapshotUtility.LoadFromFile(json)"); 106 | stopwatch.Start(); 107 | 108 | var json = File.ReadAllText(filePath); 109 | result = JsonUtility.FromJson(json); 110 | 111 | stopwatch.Stop(); 112 | Profiler.EndSample(); 113 | } 114 | else if(string.Equals(fileExtension, ".memsnap", System.StringComparison.OrdinalIgnoreCase)) 115 | { 116 | Profiler.BeginSample("PackedMemorySnapshotUtility.LoadFromFile(binary)"); 117 | stopwatch.Start(); 118 | 119 | var binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); 120 | using(Stream stream = File.Open(filePath, FileMode.Open)) 121 | { 122 | result = binaryFormatter.Deserialize(stream) as PackedMemorySnapshot; 123 | } 124 | 125 | stopwatch.Stop(); 126 | Profiler.EndSample(); 127 | } 128 | else 129 | { 130 | Debug.LogErrorFormat("MemoryProfiler: Unrecognized memory snapshot format '{0}'.", filePath); 131 | result = null; 132 | } 133 | 134 | Debug.LogFormat("Loading took {0}ms", stopwatch.ElapsedMilliseconds); 135 | return result; 136 | } 137 | 138 | private static JsonSerializer getSerializer(List errors) { 139 | JsonSerializer serializer = new JsonSerializer(); 140 | serializer.ContractResolver = new MyContractResolver(); 141 | serializer.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor; 142 | serializer.MissingMemberHandling = MissingMemberHandling.Error; 143 | serializer.Error += (object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args) => { 144 | errors.Add(string.Format("'{1}' from '{0}'", sender, args.ErrorContext.Error.Message)); 145 | }; 146 | // Enable this to get detailed logging 147 | //serializer.TraceWriter = new FilteringTraceLogWriter("typeDescriptions"); 148 | return serializer; 149 | } 150 | 151 | private static void logErrors(List errors) { 152 | if (0 < errors.Count) { 153 | var last = Mathf.Min(20, errors.Count); // might be very large, just do the first 20 154 | var sb = new StringBuilder(); 155 | for (int i = 0; i < last; i++) { 156 | sb.AppendLine(errors[i]); 157 | } 158 | UnityEngine.Debug.Log(sb.ToString()); 159 | } 160 | } 161 | 162 | private sealed class MyContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver { 163 | 164 | public MyContractResolver() : base() { 165 | IgnoreSerializableAttribute = false; // Use SerializableAttribute to determine what to serialize! 166 | } 167 | 168 | } 169 | 170 | private class FilteringTraceLogWriter : Newtonsoft.Json.Serialization.ITraceWriter { 171 | 172 | private readonly string pattern; 173 | 174 | public FilteringTraceLogWriter() : this(null) { 175 | } 176 | 177 | public FilteringTraceLogWriter(string pattern) { 178 | this.pattern = pattern; 179 | } 180 | 181 | public System.Diagnostics.TraceLevel LevelFilter { 182 | get { return System.Diagnostics.TraceLevel.Verbose; } 183 | } 184 | 185 | private static readonly LogType[] logTypeFromTraceLevel = new LogType[] { 186 | LogType.Log, // off -- it's handled elsewhere 187 | LogType.Error, // error 188 | LogType.Warning, // warning 189 | LogType.Log, // info 190 | LogType.Log, // verbose 191 | }; 192 | 193 | public void Trace(System.Diagnostics.TraceLevel level, string message, Exception ex) { 194 | if (System.Diagnostics.TraceLevel.Off == level || null != pattern) { 195 | if (!message.Contains(pattern)) { // Skip if not pattern 196 | return; 197 | } 198 | } 199 | 200 | UnityEngine.Debug.unityLogger.Log(logTypeFromTraceLevel[(int) level], message); 201 | if (null != ex) { 202 | UnityEngine.Debug.LogException(ex); 203 | } 204 | } 205 | } 206 | 207 | } 208 | 209 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/PackedMemorySnapshotUtility.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1ed1494cc6c5f4849adee6d4fc844533 3 | timeCreated: 1488224384 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/PrimitiveValueReader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEditor.MemoryProfiler; 3 | using UnityEngine; 4 | 5 | namespace MemoryProfilerWindow 6 | { 7 | class PrimitiveValueReader 8 | { 9 | private readonly VirtualMachineInformation _virtualMachineInformation; 10 | private readonly MemorySection[] _heapSections; 11 | 12 | public PrimitiveValueReader(VirtualMachineInformation virtualMachineInformation, MemorySection[] heapSections) 13 | { 14 | _virtualMachineInformation = virtualMachineInformation; 15 | _heapSections = heapSections; 16 | } 17 | 18 | public System.Int32 ReadInt32(BytesAndOffset bo) 19 | { 20 | return BitConverter.ToInt32(bo.bytes, bo.offset); 21 | } 22 | 23 | public System.UInt32 ReadUInt32(BytesAndOffset bo) 24 | { 25 | return BitConverter.ToUInt32(bo.bytes, bo.offset); 26 | } 27 | 28 | public System.Int64 ReadInt64(BytesAndOffset bo) 29 | { 30 | return BitConverter.ToInt64(bo.bytes, bo.offset); 31 | } 32 | 33 | public System.UInt64 ReadUInt64(BytesAndOffset bo) 34 | { 35 | return BitConverter.ToUInt64(bo.bytes, bo.offset); 36 | } 37 | 38 | public System.Int16 ReadInt16(BytesAndOffset bo) 39 | { 40 | return BitConverter.ToInt16(bo.bytes, bo.offset); 41 | } 42 | 43 | public System.UInt16 ReadUInt16(BytesAndOffset bo) 44 | { 45 | return BitConverter.ToUInt16(bo.bytes, bo.offset); 46 | } 47 | 48 | public System.Byte ReadByte(BytesAndOffset bo) 49 | { 50 | return bo.bytes[bo.offset]; 51 | } 52 | 53 | public System.SByte ReadSByte(BytesAndOffset bo) 54 | { 55 | return (System.SByte)bo.bytes[bo.offset]; 56 | } 57 | 58 | public System.Boolean ReadBool(BytesAndOffset bo) 59 | { 60 | return ReadByte(bo) != 0; 61 | } 62 | 63 | public UInt64 ReadPointer(BytesAndOffset bo) 64 | { 65 | if (_virtualMachineInformation.pointerSize == 4) 66 | return ReadUInt32(bo); 67 | else 68 | return ReadUInt64(bo); 69 | } 70 | 71 | public UInt64 ReadPointer(UInt64 address) 72 | { 73 | return ReadPointer(_heapSections.Find(address, _virtualMachineInformation)); 74 | } 75 | 76 | public Char ReadChar(BytesAndOffset bytesAndOffset) 77 | { 78 | return System.Text.Encoding.Unicode.GetChars(bytesAndOffset.bytes, bytesAndOffset.offset, 2)[0]; 79 | } 80 | 81 | public System.Single ReadSingle(BytesAndOffset bytesAndOffset) 82 | { 83 | return BitConverter.ToSingle(bytesAndOffset.bytes, bytesAndOffset.offset); 84 | } 85 | 86 | public System.Double ReadDouble(BytesAndOffset bytesAndOffset) 87 | { 88 | return BitConverter.ToDouble(bytesAndOffset.bytes, bytesAndOffset.offset); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/PrimitiveValueReader.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5ec98effc9c754b9d9e8f69b179b4b7d 3 | timeCreated: 1445457365 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/ProfilerData.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 06cd6eebdfeba4d2795b2c78a90591f8 3 | folderAsset: yes 4 | timeCreated: 1489006064 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/ProfilerData/MemoryElement.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | using UnityEditor.TreeViewExamples; 4 | using Random = UnityEngine.Random; 5 | using MemoryProfilerWindow; 6 | 7 | namespace UnityEditor.MemoryProfiler2 8 | { 9 | // Type (Native Unity Engine Object, etc.), ClassName (Texture2D), InstanceID - id (700), size (10.7MB), Name (Textura1) 10 | [Serializable] 11 | class MemoryElement : TreeElement 12 | { 13 | [SerializeField] float m_Size; 14 | [SerializeField] string m_ClassName; 15 | [SerializeField] string m_Type; 16 | public ThingInMemory memData; 17 | 18 | public bool enabled; 19 | 20 | public MemoryElement (string name, int depth, int id, string className, string type, float size) : base (name, depth, id) 21 | { 22 | m_ClassName = className; 23 | m_Type = type; 24 | m_Size = size; 25 | enabled = true; 26 | } 27 | 28 | public float size 29 | { 30 | get { return m_Size; } set { m_Size = value; } 31 | } 32 | 33 | public string className 34 | { 35 | get { return m_ClassName; } set { m_ClassName = value; } 36 | } 37 | 38 | public string type 39 | { 40 | get { return m_Type; } set { m_Type = value; } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/ProfilerData/MemoryElement.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ecdd95f6d4edd4040b4f93d3f5c7f530 3 | timeCreated: 1489006104 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/ProfilerData/TreeViewWithTreeModel.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_5_6 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using UnityEditor.IMGUI.Controls; 6 | using UnityEngine; 7 | using UnityEditor.TreeViewExamples; 8 | 9 | namespace UnityEditor.MemoryProfiler2 10 | { 11 | 12 | internal class TreeViewItem : TreeViewItem where T : MemoryElement 13 | { 14 | public T data { get; set; } 15 | 16 | public TreeViewItem (int id, int depth, string displayName, T data) : base (id, depth, displayName) 17 | { 18 | this.data = data; 19 | } 20 | } 21 | 22 | internal class TreeViewWithTreeModel : TreeView where T : MemoryElement 23 | { 24 | TreeModel m_TreeModel; 25 | readonly List m_Rows = new List(100); 26 | public event Action treeChanged; 27 | 28 | public TreeModel treeModel { get { return m_TreeModel; } } 29 | public event Action> beforeDroppingDraggedItems; 30 | 31 | 32 | public TreeViewWithTreeModel (TreeViewState state, TreeModel model) : base (state) 33 | { 34 | Init (model); 35 | } 36 | 37 | public TreeViewWithTreeModel (TreeViewState state, MultiColumnHeader multiColumnHeader, TreeModel model) 38 | : base(state, multiColumnHeader) 39 | { 40 | Init (model); 41 | } 42 | 43 | void Init (TreeModel model) 44 | { 45 | m_TreeModel = model; 46 | m_TreeModel.modelChanged += ModelChanged; 47 | } 48 | 49 | void ModelChanged () 50 | { 51 | if (treeChanged != null) 52 | treeChanged (); 53 | 54 | Reload (); 55 | } 56 | 57 | protected override TreeViewItem BuildRoot() 58 | { 59 | int depthForHiddenRoot = -1; 60 | return new TreeViewItem(m_TreeModel.root.id, depthForHiddenRoot, m_TreeModel.root.name); 61 | } 62 | 63 | protected override IList BuildRows (TreeViewItem root) 64 | { 65 | if (m_TreeModel.root == null) 66 | { 67 | Debug.LogError ("tree model root is null. did you call SetData()?"); 68 | } 69 | 70 | m_Rows.Clear (); 71 | if (!string.IsNullOrEmpty(searchString)) 72 | { 73 | Search (m_TreeModel.root, searchString, m_Rows); 74 | } 75 | else 76 | { 77 | if (m_TreeModel.root.hasChildren) 78 | AddChildrenRecursive(m_TreeModel.root, 0, m_Rows); 79 | } 80 | 81 | // We still need to setup the child parent information for the rows since this 82 | // information is used by the TreeView internal logic (navigation, dragging etc) 83 | SetupParentsAndChildrenFromDepths (root, m_Rows); 84 | 85 | return m_Rows; 86 | } 87 | 88 | void AddChildrenRecursive (T parent, int depth, IList newRows) 89 | { 90 | foreach (T child in parent.children) 91 | { 92 | var item = new TreeViewItem(child.id, depth, child.name, child); 93 | newRows.Add(item); 94 | 95 | if (child.hasChildren) 96 | { 97 | if (IsExpanded(child.id)) 98 | { 99 | AddChildrenRecursive (child, depth + 1, newRows); 100 | } 101 | else 102 | { 103 | item.children = CreateChildListForCollapsedParent(); 104 | } 105 | } 106 | } 107 | } 108 | 109 | void Search(T searchFromThis, string search, List result) 110 | { 111 | if (string.IsNullOrEmpty(search)) 112 | throw new ArgumentException("Invalid search: cannot be null or empty", "search"); 113 | 114 | const int kItemDepth = 0; // tree is flattened when searching 115 | 116 | if (result == null) 117 | result = new List (); 118 | 119 | Stack stack = new Stack(); 120 | foreach (var element in searchFromThis.children) 121 | stack.Push((T)element); 122 | 123 | if (search.IndexOf (":") != -1) 124 | { 125 | search = search.Replace (": ", ":"); 126 | string[] strings = search.Split (' '); 127 | for (int i = 0; i < strings.Length; i++) 128 | { 129 | if (strings [i].IndexOf (":") == -1) 130 | { 131 | stack = SearchByName (strings [i], stack); 132 | continue; 133 | } 134 | 135 | string keyValue = strings [i].Substring (2); 136 | if (keyValue == string.Empty) 137 | continue; 138 | 139 | // Resource Name (Asset Name) 140 | if (strings [i].IndexOf ("n:") != -1) 141 | { 142 | stack = SearchByName (keyValue, stack); 143 | } 144 | // InstanceID 145 | else if (strings [i].IndexOf ("i:") != -1) 146 | { 147 | stack = SearchByInstanceId (keyValue, stack); 148 | } 149 | // ClassName (Texture2D) 150 | else if (strings [i].IndexOf ("c:") != -1) 151 | { 152 | stack = SearchByClassName (keyValue, stack); 153 | } 154 | // Type (NativeUnityObject) 155 | else if (strings [i].IndexOf ("t:") != -1) 156 | { 157 | stack = SearchByType (keyValue, stack); 158 | } 159 | // Size 160 | else if (strings [i].IndexOf ("s:") != -1) 161 | { 162 | stack = SearchBySize (keyValue, stack); 163 | } 164 | } 165 | } 166 | else 167 | { 168 | stack = SearchByName (search, stack); 169 | } 170 | 171 | while (stack.Count > 0) 172 | { 173 | T current = stack.Pop (); 174 | result.Add (new TreeViewItem (current.id, kItemDepth, current.name, current)); 175 | } 176 | 177 | SortSearchResult(result); 178 | } 179 | 180 | private Stack SearchBySize (string search, Stack stack) 181 | { 182 | Stack result = new Stack(); 183 | // 0 = equal, 1 = less_than, 2 = high_than 184 | int opperator = 0; 185 | 186 | if (search [0] == '<') 187 | opperator = 1; 188 | else if (search [0] == '>') 189 | opperator = 2; 190 | 191 | if (opperator != 0 && search.Length == 1) 192 | return result; 193 | 194 | Debug.Log ("Number: " + search.Substring (opperator == 0 ? 0 : 1)); 195 | float value = float.Parse (search.Substring ( opperator == 0 ? 0 : 1 )); 196 | while (stack.Count > 0) 197 | { 198 | T current = stack.Pop (); 199 | if (opperator == 0 && current.size == value) 200 | result.Push (current); 201 | else if (opperator == 1 && current.size <= value) 202 | result.Push (current); 203 | else if (opperator == 2 && current.size >= value) 204 | result.Push (current); 205 | } 206 | 207 | return result; 208 | } 209 | 210 | private Stack SearchByType (string search, Stack stack) 211 | { 212 | Stack result = new Stack(); 213 | while (stack.Count > 0) 214 | { 215 | T current = stack.Pop (); 216 | 217 | if (current.type.IndexOf (search, StringComparison.OrdinalIgnoreCase) >= 0) 218 | { 219 | result.Push(current); 220 | } 221 | } 222 | 223 | return result; 224 | } 225 | 226 | private Stack SearchByClassName (string search, Stack stack) 227 | { 228 | Stack result = new Stack(); 229 | while (stack.Count > 0) 230 | { 231 | T current = stack.Pop (); 232 | 233 | if (current.className.IndexOf (search, StringComparison.OrdinalIgnoreCase) >= 0) 234 | { 235 | result.Push(current); 236 | } 237 | } 238 | 239 | return result; 240 | } 241 | 242 | private Stack SearchByName (string search, Stack stack) 243 | { 244 | Stack result = new Stack(); 245 | while (stack.Count > 0) 246 | { 247 | T current = stack.Pop (); 248 | 249 | if (current.name.IndexOf (search, StringComparison.OrdinalIgnoreCase) >= 0) 250 | { 251 | result.Push(current); 252 | } 253 | } 254 | 255 | return result; 256 | } 257 | 258 | private Stack SearchByInstanceId (string search, Stack stack) 259 | { 260 | Stack result = new Stack(); 261 | while (stack.Count > 0) 262 | { 263 | T current = stack.Pop (); 264 | 265 | if (current.id.ToString().IndexOf (search, StringComparison.OrdinalIgnoreCase) >= 0) 266 | { 267 | //result.Add ( new TreeViewItem (current.id, 0, current.name, current)); 268 | result.Push ( current ); 269 | } 270 | } 271 | 272 | return result; 273 | } 274 | 275 | protected virtual void SortSearchResult (List rows) 276 | { 277 | rows.Sort (); // sort by displayName by default, can be overriden for multicolumn solutions 278 | } 279 | 280 | protected override IList GetAncestors (int id) 281 | { 282 | return m_TreeModel.GetAncestors(id); 283 | } 284 | 285 | protected override IList GetDescendantsThatHaveChildren (int id) 286 | { 287 | return m_TreeModel.GetDescendantsThatHaveChildren(id); 288 | } 289 | 290 | 291 | // Dragging 292 | //----------- 293 | 294 | const string k_GenericDragID = "GenericDragColumnDragging"; 295 | 296 | protected override bool CanStartDrag (CanStartDragArgs args) 297 | { 298 | return true; 299 | } 300 | 301 | protected override void SetupDragAndDrop(SetupDragAndDropArgs args) 302 | { 303 | if (hasSearch) 304 | return; 305 | 306 | DragAndDrop.PrepareStartDrag(); 307 | var draggedRows = GetRows().Where(item => args.draggedItemIDs.Contains(item.id)).ToList(); 308 | DragAndDrop.SetGenericData(k_GenericDragID, draggedRows); 309 | DragAndDrop.objectReferences = new UnityEngine.Object[] { }; // this IS required for dragging to work 310 | string title = draggedRows.Count == 1 ? draggedRows[0].displayName : "< Multiple >"; 311 | DragAndDrop.StartDrag (title); 312 | } 313 | 314 | protected override DragAndDropVisualMode HandleDragAndDrop (DragAndDropArgs args) 315 | { 316 | // Check if we can handle the current drag data (could be dragged in from other areas/windows in the editor) 317 | var draggedRows = DragAndDrop.GetGenericData(k_GenericDragID) as List; 318 | if (draggedRows == null) 319 | return DragAndDropVisualMode.None; 320 | 321 | // Parent item is null when dragging outside any tree view items. 322 | switch (args.dragAndDropPosition) 323 | { 324 | case DragAndDropPosition.UponItem: 325 | case DragAndDropPosition.BetweenItems: 326 | { 327 | bool validDrag = ValidDrag(args.parentItem, draggedRows); 328 | if (args.performDrop && validDrag) 329 | { 330 | T parentData = ((TreeViewItem)args.parentItem).data; 331 | OnDropDraggedElementsAtIndex(draggedRows, parentData, args.insertAtIndex == -1 ? 0 : args.insertAtIndex); 332 | } 333 | return validDrag ? DragAndDropVisualMode.Move : DragAndDropVisualMode.None; 334 | } 335 | 336 | case DragAndDropPosition.OutsideItems: 337 | { 338 | if (args.performDrop) 339 | OnDropDraggedElementsAtIndex(draggedRows, m_TreeModel.root, m_TreeModel.root.children.Count); 340 | 341 | return DragAndDropVisualMode.Move; 342 | } 343 | default: 344 | Debug.LogError("Unhandled enum " + args.dragAndDropPosition); 345 | return DragAndDropVisualMode.None; 346 | } 347 | } 348 | 349 | public virtual void OnDropDraggedElementsAtIndex (List draggedRows, T parent, int insertIndex) 350 | { 351 | if (beforeDroppingDraggedItems != null) 352 | beforeDroppingDraggedItems (draggedRows); 353 | 354 | var draggedElements = new List (); 355 | foreach (var x in draggedRows) 356 | draggedElements.Add (((TreeViewItem) x).data); 357 | 358 | var selectedIDs = draggedElements.Select (x => x.id).ToArray(); 359 | m_TreeModel.MoveElements (parent, insertIndex, draggedElements); 360 | SetSelection(selectedIDs, TreeViewSelectionOptions.RevealAndFrame); 361 | } 362 | 363 | 364 | bool ValidDrag(TreeViewItem parent, List draggedItems) 365 | { 366 | TreeViewItem currentParent = parent; 367 | while (currentParent != null) 368 | { 369 | if (draggedItems.Contains(currentParent)) 370 | return false; 371 | currentParent = currentParent.parent; 372 | } 373 | return true; 374 | } 375 | 376 | } 377 | 378 | } 379 | #endif -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/ProfilerData/TreeViewWithTreeModel.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 87458386c4d4944a48d1df4ae024306e 3 | timeCreated: 1489006130 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/ProfilerNodes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bde9e93ce8a420a4192cd3ec29201081 3 | folderAsset: yes 4 | timeCreated: 1489094901 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/ProfilerNodes/ProfilerNode.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2f370d62925bfa247a4eaa09bb4fa39b 3 | timeCreated: 1488941190 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/ProfilerNodes/ProfilerNodeObjectInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using MemoryProfilerWindow; 5 | 6 | namespace UnityEditor.MemoryProfiler2 7 | { 8 | public class ProfilerNodeObjectInfo 9 | { 10 | public string text; 11 | public int id; 12 | public Rect myAreaRect; 13 | public ThingInMemory memObject; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/ProfilerNodes/ProfilerNodeObjectInfo.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4db19435d2aeaa443bbb93923fd70dad 3 | timeCreated: 1488934051 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/ProfilerNodes/ProfilerNodeView.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 14fe78617afb112409bbf2cbf0e83f68 3 | timeCreated: 1488839562 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/ProfilerNodes/ProfilerNodeZoomArea.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | namespace UnityEditor.MemoryProfiler2 3 | { 4 | public static class RectExtensions 5 | { 6 | public static Vector2 TopLeft(this Rect rect) 7 | { 8 | return new Vector2(rect.xMin, rect.yMin); 9 | } 10 | public static Rect ScaleSizeBy(this Rect rect, float scale) 11 | { 12 | return rect.ScaleSizeBy(scale, rect.center); 13 | } 14 | public static Rect ScaleSizeBy(this Rect rect, float scale, Vector2 pivotPoint) 15 | { 16 | Rect result = rect; 17 | result.x -= pivotPoint.x; 18 | result.y -= pivotPoint.y; 19 | result.xMin *= scale; 20 | result.xMax *= scale; 21 | result.yMin *= scale; 22 | result.yMax *= scale; 23 | result.x += pivotPoint.x; 24 | result.y += pivotPoint.y; 25 | return result; 26 | } 27 | public static Rect ScaleSizeBy(this Rect rect, Vector2 scale) 28 | { 29 | return rect.ScaleSizeBy(scale, rect.center); 30 | } 31 | public static Rect ScaleSizeBy(this Rect rect, Vector2 scale, Vector2 pivotPoint) 32 | { 33 | Rect result = rect; 34 | result.x -= pivotPoint.x; 35 | result.y -= pivotPoint.y; 36 | result.xMin *= scale.x; 37 | result.xMax *= scale.x; 38 | result.yMin *= scale.y; 39 | result.yMax *= scale.y; 40 | result.x += pivotPoint.x; 41 | result.y += pivotPoint.y; 42 | return result; 43 | } 44 | } 45 | public class ProfilerNodeZoomArea 46 | { 47 | private const float kEditorWindowTabHeight = 21.0f; 48 | private static Matrix4x4 _prevGuiMatrix; 49 | 50 | public static Rect Begin(float zoomScale, Rect screenCoordsArea, float panX, float panY) 51 | { 52 | GUI.EndGroup(); 53 | 54 | Rect clippedArea = screenCoordsArea.ScaleSizeBy(1.0f / zoomScale*2, screenCoordsArea.TopLeft()); 55 | clippedArea.y += kEditorWindowTabHeight; 56 | GUI.BeginGroup(clippedArea); 57 | 58 | _prevGuiMatrix = GUI.matrix; 59 | //GUI.matrix = Matrix4x4.TRS(Vector2.zero + new Vector2(panX, panY), Quaternion.identity, Vector3.one); 60 | Matrix4x4 translation = Matrix4x4.TRS(clippedArea.TopLeft(), Quaternion.identity, Vector3.one); 61 | Matrix4x4 scale = Matrix4x4.Scale(new Vector3(zoomScale, zoomScale, 1.0f)); 62 | GUI.matrix = translation * scale * translation.inverse * GUI.matrix; 63 | 64 | return clippedArea; 65 | } 66 | 67 | public static void End(float panX, float panY) 68 | { 69 | GUI.matrix = _prevGuiMatrix; 70 | GUI.EndGroup(); 71 | GUI.BeginGroup(new Rect(0.0f, kEditorWindowTabHeight, Screen.width, Screen.height)); 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/ProfilerNodes/ProfilerNodeZoomArea.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7e9e1a07039cb734d96a9744e46ff401 3 | timeCreated: 1489121205 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/ProfilerTreeView.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_5_6_OR_NEWER 2 | using System; 3 | using System.Collections.Generic; 4 | using UnityEditor.IMGUI.Controls; 5 | using UnityEngine; 6 | using UnityEngine.Assertions; 7 | using UnityEditor.TreeViewExamples; 8 | 9 | 10 | namespace UnityEditor.MemoryProfiler2 11 | { 12 | 13 | internal class ProfilerTreeView : TreeViewWithTreeModel 14 | { 15 | const float kRowHeights = 20f; 16 | const float kToggleWidth = 18f; 17 | public bool showControls { get; set; } 18 | 19 | public System.Action doubleClickedCallback { get; set; } 20 | 21 | /*static Texture2D[] s_TestIcons = 22 | { 23 | EditorGUIUtility.FindTexture ("Folder Icon"), 24 | EditorGUIUtility.FindTexture ("AudioSource Icon"), 25 | EditorGUIUtility.FindTexture ("Camera Icon"), 26 | EditorGUIUtility.FindTexture ("Windzone Icon"), 27 | EditorGUIUtility.FindTexture ("GameObject Icon") 28 | 29 | };*/ 30 | 31 | // All columns 32 | // Type, ClassName, InstanceID, Size, Name 33 | enum MyColumns 34 | { 35 | Type, 36 | ClassName, 37 | InstanceID, 38 | Size, 39 | Name 40 | } 41 | 42 | public enum SortOption 43 | { 44 | Type, 45 | ClassName, 46 | InstanceID, 47 | Size, 48 | Name 49 | } 50 | 51 | // Sort options per column 52 | SortOption[] m_SortOptions = 53 | { 54 | SortOption.Type, 55 | SortOption.ClassName, 56 | SortOption.InstanceID, 57 | SortOption.Size, 58 | SortOption.Name 59 | }; 60 | 61 | public static void TreeToList (TreeViewItem root, IList result) 62 | { 63 | if (root == null) 64 | throw new NullReferenceException("root"); 65 | if (result == null) 66 | throw new NullReferenceException("result"); 67 | 68 | result.Clear(); 69 | 70 | if (root.children == null) 71 | return; 72 | 73 | Stack stack = new Stack(); 74 | for (int i = root.children.Count - 1; i >= 0; i--) 75 | stack.Push(root.children[i]); 76 | 77 | while (stack.Count > 0) 78 | { 79 | TreeViewItem current = stack.Pop(); 80 | result.Add(current); 81 | 82 | if (current.hasChildren && current.children[0] != null) 83 | { 84 | for (int i = current.children.Count - 1; i >= 0; i--) 85 | { 86 | stack.Push(current.children[i]); 87 | } 88 | } 89 | } 90 | } 91 | 92 | protected override void DoubleClickedItem(int id) 93 | { 94 | if (doubleClickedCallback != null) 95 | doubleClickedCallback (id); 96 | } 97 | 98 | public ProfilerTreeView (TreeViewState state, MultiColumnHeader multicolumnHeader, TreeModel model) : base (state, multicolumnHeader, model) 99 | { 100 | Assert.AreEqual(m_SortOptions.Length , Enum.GetValues(typeof(MyColumns)).Length, "Ensure number of sort options are in sync with number of MyColumns enum values"); 101 | 102 | // Custom setup 103 | rowHeight = kRowHeights; 104 | columnIndexForTreeFoldouts = 2; 105 | showAlternatingRowBackgrounds = true; 106 | showBorder = true; 107 | customFoldoutYOffset = (kRowHeights - EditorGUIUtility.singleLineHeight) * 0.5f; // center foldout in the row since we also center content. See RowGUI 108 | extraSpaceBeforeIconAndLabel = kToggleWidth; 109 | multicolumnHeader.sortingChanged += OnSortingChanged; 110 | 111 | Reload(); 112 | } 113 | 114 | 115 | // Note we We only build the visible rows, only the backend has the full tree information. 116 | // The treeview only creates info for the row list. 117 | protected override IList BuildRows(TreeViewItem root) 118 | { 119 | var rows = base.BuildRows (root); 120 | SortIfNeeded (root, rows); 121 | return rows; 122 | } 123 | 124 | void OnSortingChanged (MultiColumnHeader multiColumnHeader) 125 | { 126 | SortIfNeeded (rootItem, GetRows()); 127 | } 128 | 129 | void SortIfNeeded (TreeViewItem root, IList rows) 130 | { 131 | if (multiColumnHeader.sortedColumnIndex == -1) 132 | { 133 | return; // No column to sort for (just use the order the data are in) 134 | } 135 | 136 | SortOption sortOption = m_SortOptions[multiColumnHeader.sortedColumnIndex]; 137 | bool sortAscending = multiColumnHeader.IsSortedAscending(multiColumnHeader.sortedColumnIndex); 138 | 139 | // Sort the roots of the existing tree items 140 | SortVisibleRoots(sortOption, sortAscending); 141 | TreeToList(root, rows); 142 | Repaint(); 143 | } 144 | 145 | public void SortVisibleRoots (SortOption sortOption, bool sortedAscending) 146 | { 147 | int direction = sortedAscending ? 1 : -1; 148 | if (!rootItem.hasChildren) 149 | return; 150 | rootItem.children.Sort((x, y) => Compare(x, y, sortOption) * direction); 151 | } 152 | 153 | public int Compare (TreeViewItem x, TreeViewItem y, SortOption sortOption) 154 | { 155 | if (x == y) return 0; 156 | if (x == null) return -1; 157 | if (y == null) return 1; 158 | 159 | MemoryElement memoryElementX = ((TreeViewItem)x).data; 160 | MemoryElement memoryElementY = ((TreeViewItem)y).data; 161 | switch (sortOption) 162 | { 163 | case SortOption.Name: 164 | return EditorUtility.NaturalCompare(memoryElementX.name, memoryElementY.name); 165 | case SortOption.Type: 166 | return EditorUtility.NaturalCompare(memoryElementX.type, memoryElementY.type); 167 | //memoryElementX.floatValue1.CompareTo(memoryElementY.floatValue1); 168 | case SortOption.InstanceID: 169 | return memoryElementX.id.CompareTo(memoryElementY.id); 170 | case SortOption.Size: 171 | return memoryElementX.size.CompareTo(memoryElementY.size); 172 | case SortOption.ClassName: 173 | return EditorUtility.NaturalCompare(memoryElementX.className, memoryElementY.className); 174 | //memoryElementX.floatValue3.CompareTo(memoryElementY.floatValue3); 175 | } 176 | return 0; 177 | } 178 | 179 | /*int GetIcon1Index(TreeViewItem item) 180 | { 181 | return (int)(Mathf.Min(0.99f, item.data.floatValue1) * s_TestIcons.Length); 182 | } 183 | 184 | int GetIcon2Index (TreeViewItem item) 185 | { 186 | return Mathf.Min(item.data.text.Length, s_TestIcons.Length-1); 187 | }*/ 188 | 189 | protected override void RowGUI (RowGUIArgs args) 190 | { 191 | var item = (TreeViewItem) args.item; 192 | 193 | for (int i = 0; i < args.GetNumVisibleColumns (); ++i) 194 | { 195 | CellGUI(args.GetCellRect(i), item, (MyColumns)args.GetColumn(i), ref args); 196 | } 197 | } 198 | 199 | void CellGUI (Rect cellRect, TreeViewItem item, MyColumns column, ref RowGUIArgs args) 200 | { 201 | // Center cell rect vertically (makes it easier to place controls, icons etc in the cells) 202 | CenterRectUsingSingleLineHeight(ref cellRect); 203 | 204 | switch (column) 205 | { 206 | case MyColumns.Type: 207 | DefaultGUI.Label (cellRect, item.data.type, args.selected, args.focused); 208 | break; 209 | case MyColumns.ClassName: 210 | DefaultGUI.Label (cellRect, item.data.className, args.selected, args.focused); 211 | break; 212 | 213 | case MyColumns.InstanceID: 214 | DefaultGUI.LabelRightAligned (cellRect, item.data.id.ToString(), args.selected, args.focused); 215 | break; 216 | case MyColumns.Size: 217 | DefaultGUI.LabelRightAligned (cellRect, item.data.size.ToString("f2"), args.selected, args.focused); 218 | break; 219 | case MyColumns.Name: 220 | DefaultGUI.Label (cellRect, item.data.name, args.selected, args.focused); 221 | break; 222 | } 223 | } 224 | 225 | // Rename 226 | //-------- 227 | 228 | /*protected override bool CanRename(TreeViewItem item) 229 | { 230 | // Only allow rename if we can show the rename overlay with a certain width (label might be clipped by other columns) 231 | Rect renameRect = GetRenameRect (treeViewRect, 0, item); 232 | return renameRect.width > 30; 233 | } 234 | 235 | protected override void RenameEnded(RenameEndedArgs args) 236 | { 237 | // Set the backend name and reload the tree to reflect the new model 238 | if (args.acceptedRename) 239 | { 240 | var element = treeModel.Find(args.itemID); 241 | element.name = args.newName; 242 | Reload(); 243 | } 244 | } 245 | 246 | protected override Rect GetRenameRect (Rect rowRect, int row, TreeViewItem item) 247 | { 248 | Rect cellRect = GetCellRectForTreeFoldouts (rowRect); 249 | CenterRectUsingSingleLineHeight(ref cellRect); 250 | return base.GetRenameRect (cellRect, row, item); 251 | }*/ 252 | 253 | // Misc 254 | //-------- 255 | 256 | protected override bool CanMultiSelect (TreeViewItem item) 257 | { 258 | return true; 259 | } 260 | 261 | public static MultiColumnHeaderState CreateDefaultMultiColumnHeaderState(float treeViewWidth) 262 | { 263 | var columns = new[] 264 | { 265 | new MultiColumnHeaderState.Column 266 | { 267 | headerContent = new GUIContent("Type", "The type (Native|Managed|Static)"), 268 | headerTextAlignment = TextAlignment.Center, 269 | sortedAscending = true, 270 | sortingArrowAlignment = TextAlignment.Left, 271 | width = 120, 272 | minWidth = 120, 273 | //maxWidth = 120, 274 | autoResize = true, 275 | allowToggleVisibility = true 276 | }, 277 | new MultiColumnHeaderState.Column 278 | { 279 | headerContent = new GUIContent("ClassName", "The Class Name of the resource"), 280 | headerTextAlignment = TextAlignment.Center, 281 | sortedAscending = true, 282 | sortingArrowAlignment = TextAlignment.Left, 283 | width = 100, // adjusted below 284 | minWidth = 100, 285 | maxWidth = 100, 286 | autoResize = false, 287 | allowToggleVisibility = true 288 | }, 289 | new MultiColumnHeaderState.Column 290 | { 291 | headerContent = new GUIContent("InstanceID", "The Instance ID, it should be unique"), 292 | headerTextAlignment = TextAlignment.Center, 293 | sortedAscending = true, 294 | sortingArrowAlignment = TextAlignment.Right, 295 | width = 120, // adjusted below 296 | minWidth = 100, 297 | maxWidth = 120, 298 | autoResize = false, 299 | allowToggleVisibility = true 300 | }, 301 | new MultiColumnHeaderState.Column 302 | { 303 | headerContent = new GUIContent("Size (bytes)", "The size in bytes in memory."), 304 | headerTextAlignment = TextAlignment.Center, 305 | sortedAscending = true, 306 | sortingArrowAlignment = TextAlignment.Left, 307 | width = 60, 308 | minWidth = 60, 309 | autoResize = false, 310 | allowToggleVisibility = true 311 | }, 312 | new MultiColumnHeaderState.Column 313 | { 314 | headerContent = new GUIContent("Name", "Resource name (if exists!)"), 315 | headerTextAlignment = TextAlignment.Center, 316 | sortedAscending = true, 317 | sortingArrowAlignment = TextAlignment.Left, 318 | width = 60, 319 | minWidth = 60, 320 | autoResize = true 321 | } 322 | }; 323 | 324 | Assert.AreEqual(columns.Length, Enum.GetValues(typeof(MyColumns)).Length, "Number of columns should match number of enum values: You probably forgot to update one of them."); 325 | 326 | // Set name column width (flexible) 327 | int nameColumn = (int)MyColumns.Name; 328 | columns[nameColumn].width = treeViewWidth - GUI.skin.verticalScrollbar.fixedWidth; 329 | for (int i = 0; i < columns.Length; ++i) 330 | if (i != nameColumn) 331 | columns[nameColumn].width -= columns[i].width; 332 | 333 | if (columns[nameColumn].width < 60f) 334 | columns[nameColumn].width = 60f; 335 | 336 | var state = new MultiColumnHeaderState(columns); 337 | return state; 338 | } 339 | } 340 | } 341 | #endif -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/ProfilerTreeView.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1e26827a3c6574badbfa415d63c4ba84 3 | timeCreated: 1489007669 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/ProfilerWindow.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 76ab5975fc5b44794b850761b903d31e 3 | timeCreated: 1489007652 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/ShortestPathToRootFinder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using MemoryProfilerWindow; 6 | using UnityEditor.MemoryProfiler; 7 | using UnityEngine; 8 | 9 | namespace MemoryProfilerWindow 10 | { 11 | class ShortestPathToRootFinder 12 | { 13 | private readonly CrawledMemorySnapshot _snapshot; 14 | 15 | public ShortestPathToRootFinder(CrawledMemorySnapshot snapshot) 16 | { 17 | _snapshot = snapshot; 18 | } 19 | 20 | public ThingInMemory[] FindFor(ThingInMemory thing) 21 | { 22 | var seen = new HashSet(); 23 | var queue = new Queue>(); 24 | queue.Enqueue(new List { thing}); 25 | 26 | while (queue.Any()) 27 | { 28 | var pop = queue.Dequeue(); 29 | var tip = pop.Last(); 30 | 31 | string reason; 32 | if (IsRoot(tip, out reason)) 33 | return pop.ToArray(); 34 | 35 | foreach (var next in tip.referencedBy) 36 | { 37 | if (seen.Contains(next)) 38 | continue; 39 | seen.Add(next); 40 | var dupe = new List(pop) {next}; 41 | queue.Enqueue(dupe); 42 | } 43 | } 44 | return null; 45 | } 46 | 47 | public bool IsRoot(ThingInMemory thing, out string reason) 48 | { 49 | reason = null; 50 | if (thing is StaticFields) 51 | { 52 | reason = "Static fields are global variables. Anything they reference will not be unloaded."; 53 | return true; 54 | } 55 | if (thing is ManagedObject) 56 | return false; 57 | if (thing is GCHandle) 58 | return false; 59 | 60 | var nativeObject = thing as NativeUnityEngineObject; 61 | if (nativeObject == null) 62 | { 63 | // throw new ArgumentException("Unknown type: " + thing.GetType()); 64 | return false; 65 | } 66 | if (nativeObject.isManager) 67 | { 68 | reason = "this is an internal unity'manager' style object, which is a global object that will never be unloaded"; 69 | return true; 70 | } 71 | if (nativeObject.isDontDestroyOnLoad) 72 | { 73 | reason = "DontDestroyOnLoad() was called on this object, so it will never be unloaded"; 74 | return true; 75 | } 76 | 77 | if ((nativeObject.hideFlags & HideFlags.DontUnloadUnusedAsset) != 0) 78 | { 79 | reason = "the DontUnloadUnusedAsset hideflag is set on this object. Unity's builtin resources set this flag. Users can also set the flag themselves"; 80 | return true; 81 | } 82 | 83 | if (nativeObject.isPersistent) 84 | return false; 85 | 86 | if (IsComponent(nativeObject.classID)) 87 | { 88 | reason = "this is a component, living on a gameobject, that is either part of the loaded scene, or was generated by script. It will be unloaded on next scene load."; 89 | return true; 90 | } 91 | 92 | if (IsGameObject(nativeObject.classID)) 93 | { 94 | reason = "this is a gameobject, that is either part of the loaded scene, or was generated by script. It will be unloaded on next scene load if nobody is referencing it"; 95 | return true; 96 | } 97 | 98 | if (IsAssetBundle(nativeObject.classID)) 99 | { 100 | reason = "this object is an assetbundle, which is never unloaded automatically, but only through an explicit .Unload() call."; 101 | return true; 102 | } 103 | 104 | reason = "This object is a root, but the memory profiler UI does not yet understand why"; 105 | return true; 106 | } 107 | 108 | private bool IsGameObject(int classID) 109 | { 110 | return _snapshot.nativeTypes[classID].name == "GameObject"; 111 | } 112 | 113 | private bool IsAssetBundle(int classID) 114 | { 115 | return _snapshot.nativeTypes[classID].name == "AssetBundle"; 116 | } 117 | 118 | private bool IsComponent(int classID) 119 | { 120 | var packedNativeType = _snapshot.nativeTypes[classID]; 121 | 122 | if (packedNativeType.name == "Component") 123 | return true; 124 | 125 | #if UNITY_5_6_OR_NEWER 126 | var baseClassID = packedNativeType.nativeBaseTypeArrayIndex; 127 | #else 128 | var baseClassID = packedNativeType.baseClassId; 129 | #endif 130 | 131 | return baseClassID != -1 && IsComponent(baseClassID); 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/ShortestPathToRootFinder.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 020e1b97e9c2846de88e22e467a8c339 3 | timeCreated: 1440658182 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/StringTools.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEditor.MemoryProfiler; 3 | 4 | namespace MemoryProfilerWindow 5 | { 6 | static class StringTools 7 | { 8 | public static string ReadString(BytesAndOffset bo, VirtualMachineInformation virtualMachineInformation) 9 | { 10 | var lengthPointer = bo.Add(virtualMachineInformation.objectHeaderSize); 11 | var length = lengthPointer.ReadInt32(); 12 | var firstChar = lengthPointer.Add(4); 13 | 14 | return System.Text.Encoding.Unicode.GetString(firstChar.bytes, firstChar.offset, length * 2); 15 | } 16 | 17 | public static int ReadStringObjectSizeInBytes(BytesAndOffset bo, VirtualMachineInformation virtualMachineInformation) 18 | { 19 | var lengthPointer = bo.Add(virtualMachineInformation.objectHeaderSize); 20 | var length = lengthPointer.ReadInt32(); 21 | 22 | return virtualMachineInformation.objectHeaderSize + /*lengthfield*/ 1 + (length * /*utf16=2bytes per char*/ 2) + /*2 zero terminators*/ 2; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/StringTools.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f5fcc7268b81743ccaca45ff1e568b9a 3 | timeCreated: 1445457366 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TreeAsset 1.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9063dd32c1d9b470db85a6a45eda60d4 3 | timeCreated: 1489001986 4 | licenseType: Pro 5 | NativeFormatImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TreeDataModel.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e793a8ef4de7045eba5b4fec4fd0e456 3 | folderAsset: yes 4 | timeCreated: 1489001961 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TreeDataModel/TreeElement.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | 6 | namespace UnityEditor.TreeViewExamples 7 | { 8 | 9 | [Serializable] 10 | public class TreeElement 11 | { 12 | [SerializeField] int m_ID; 13 | [SerializeField] string m_Name; 14 | [SerializeField] int m_Depth; 15 | [NonSerialized] TreeElement m_Parent; 16 | [NonSerialized] List m_Children; 17 | 18 | public int depth 19 | { 20 | get { return m_Depth; } 21 | set { m_Depth = value; } 22 | } 23 | 24 | public TreeElement parent 25 | { 26 | get { return m_Parent; } 27 | set { m_Parent = value; } 28 | } 29 | 30 | public List children 31 | { 32 | get { return m_Children; } 33 | set { m_Children = value; } 34 | } 35 | 36 | public bool hasChildren 37 | { 38 | get { return children != null && children.Count > 0; } 39 | } 40 | 41 | public string name 42 | { 43 | get { return m_Name; } set { m_Name = value; } 44 | } 45 | 46 | public int id 47 | { 48 | get { return m_ID; } set { m_ID = value; } 49 | } 50 | 51 | public TreeElement () 52 | { 53 | } 54 | 55 | public TreeElement (string name, int depth, int id) 56 | { 57 | m_Name = name; 58 | m_ID = id; 59 | m_Depth = depth; 60 | } 61 | } 62 | 63 | } 64 | 65 | 66 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TreeDataModel/TreeElement.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 69be32fe4d27dde489209c5885c1e5dc 3 | timeCreated: 1472024155 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TreeDataModel/TreeElementUtility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | //using NUnit.Framework; 5 | 6 | 7 | namespace UnityEditor.TreeViewExamples 8 | { 9 | 10 | // TreeElementUtility and TreeElement are useful helper classes for backend tree data structures. 11 | // See tests at the bottom for examples of how to use. 12 | 13 | public static class TreeElementUtility 14 | { 15 | public static void TreeToList(T root, IList result) where T : TreeElement 16 | { 17 | if (result == null) 18 | throw new NullReferenceException("The input 'IList result' list is null"); 19 | result.Clear(); 20 | 21 | Stack stack = new Stack(); 22 | stack.Push(root); 23 | 24 | while (stack.Count > 0) 25 | { 26 | T current = stack.Pop(); 27 | result.Add(current); 28 | 29 | if (current.children != null && current.children.Count > 0) 30 | { 31 | for (int i = current.children.Count - 1; i >= 0; i--) 32 | { 33 | stack.Push((T)current.children[i]); 34 | } 35 | } 36 | } 37 | } 38 | 39 | // Returns the root of the tree parsed from the list (always the first element). 40 | // Important: the first item and is required to have a depth value of -1. 41 | // The rest of the items should have depth >= 0. 42 | public static T ListToTree(IList list) where T : TreeElement 43 | { 44 | // Validate input 45 | ValidateDepthValues (list); 46 | 47 | // Clear old states 48 | foreach (var element in list) 49 | { 50 | element.parent = null; 51 | element.children = null; 52 | } 53 | 54 | // Set child and parent references using depth info 55 | for (int parentIndex = 0; parentIndex < list.Count; parentIndex++) 56 | { 57 | var parent = list[parentIndex]; 58 | bool alreadyHasValidChildren = parent.children != null; 59 | if (alreadyHasValidChildren) 60 | continue; 61 | 62 | int parentDepth = parent.depth; 63 | int childCount = 0; 64 | 65 | // Count children based depth value, we are looking at children until it's the same depth as this object 66 | for (int i = parentIndex + 1; i < list.Count; i++) 67 | { 68 | if (list[i].depth == parentDepth + 1) 69 | childCount++; 70 | if (list[i].depth <= parentDepth) 71 | break; 72 | } 73 | 74 | // Fill child array 75 | List childList = null; 76 | if (childCount != 0) 77 | { 78 | childList = new List(childCount); // Allocate once 79 | childCount = 0; 80 | for (int i = parentIndex + 1; i < list.Count; i++) 81 | { 82 | if (list[i].depth == parentDepth + 1) 83 | { 84 | list[i].parent = parent; 85 | childList.Add(list[i]); 86 | childCount++; 87 | } 88 | 89 | if (list[i].depth <= parentDepth) 90 | break; 91 | } 92 | } 93 | 94 | parent.children = childList; 95 | } 96 | 97 | return list[0]; 98 | } 99 | 100 | // Check state of input list 101 | public static void ValidateDepthValues(IList list) where T : TreeElement 102 | { 103 | if (list.Count == 0) 104 | throw new ArgumentException("list should have items, count is 0, check before calling ValidateDepthValues", "list"); 105 | 106 | if (list[0].depth != -1) 107 | throw new ArgumentException("list item at index 0 should have a depth of -1 (since this should be the hidden root of the tree). Depth is: " + list[0].depth, "list"); 108 | 109 | for (int i = 0; i < list.Count - 1; i++) 110 | { 111 | int depth = list[i].depth; 112 | int nextDepth = list[i + 1].depth; 113 | if (nextDepth > depth && nextDepth - depth > 1) 114 | throw new ArgumentException(string.Format("Invalid depth info in input list. Depth cannot increase more than 1 per row. Index {0} has depth {1} while index {2} has depth {3}", i, depth, i + 1, nextDepth)); 115 | } 116 | 117 | for (int i = 1; i < list.Count; ++i) 118 | if (list[i].depth < 0) 119 | throw new ArgumentException("Invalid depth value for item at index " + i + ". Only the first item (the root) should have depth below 0."); 120 | 121 | if (list.Count > 1 && list[1].depth != 0) 122 | throw new ArgumentException("Input list item at index 1 is assumed to have a depth of 0", "list"); 123 | } 124 | 125 | 126 | // For updating depth values below any given element e.g after reparenting elements 127 | public static void UpdateDepthValues(T root) where T : TreeElement 128 | { 129 | if (root == null) 130 | throw new ArgumentNullException("root", "The root is null"); 131 | 132 | if (!root.hasChildren) 133 | return; 134 | 135 | Stack stack = new Stack(); 136 | stack.Push(root); 137 | while (stack.Count > 0) 138 | { 139 | TreeElement current = stack.Pop(); 140 | if (current.children != null) 141 | { 142 | foreach (var child in current.children) 143 | { 144 | child.depth = current.depth + 1; 145 | stack.Push(child); 146 | } 147 | } 148 | } 149 | } 150 | 151 | // Returns true if there is an ancestor of child in the elements list 152 | static bool IsChildOf(T child, IList elements) where T : TreeElement 153 | { 154 | while (child != null) 155 | { 156 | child = (T)child.parent; 157 | if (elements.Contains(child)) 158 | return true; 159 | } 160 | return false; 161 | } 162 | 163 | public static IList FindCommonAncestorsWithinList(IList elements) where T : TreeElement 164 | { 165 | if (elements.Count == 1) 166 | return new List(elements); 167 | 168 | List result = new List(elements); 169 | result.RemoveAll(g => IsChildOf(g, elements)); 170 | return result; 171 | } 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TreeDataModel/TreeElementUtility.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fd65e8f324e17a344a97ddcf5a8d89d2 3 | timeCreated: 1471616285 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TreeDataModel/TreeModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | 6 | namespace UnityEditor.TreeViewExamples 7 | { 8 | // The TreeModel is a utility class working on a list of serializable TreeElements where the order and the depth of each TreeElement define 9 | // the tree structure. Note that the TreeModel itself is not serializable (in Unity we are currently limited to serializing lists/arrays) but the 10 | // input list is. 11 | // The tree representation (parent and children references) are then build internally using TreeElementUtility.ListToTree (using depth 12 | // values of the elements). 13 | // The first element of the input list is required to have depth == -1 (the hiddenroot) and the rest to have 14 | // depth >= 0 (otherwise an exception will be thrown) 15 | 16 | public class TreeModel where T : TreeElement 17 | { 18 | IList m_Data; 19 | T m_Root; 20 | int m_MaxID; 21 | 22 | public T root { get { return m_Root; } set { m_Root = value; } } 23 | public event Action modelChanged; 24 | public int numberOfDataElements 25 | { 26 | get { return m_Data.Count; } 27 | } 28 | 29 | public TreeModel (IList data) 30 | { 31 | SetData (data); 32 | } 33 | 34 | public T Find (int id) 35 | { 36 | return m_Data.FirstOrDefault (element => element.id == id); 37 | } 38 | 39 | public void SetData (IList data) 40 | { 41 | Init (data); 42 | } 43 | 44 | void Init (IList data) 45 | { 46 | if (data == null) 47 | throw new ArgumentNullException("data", "Input data is null. Ensure input is a non-null list."); 48 | 49 | m_Data = data; 50 | if (m_Data.Count > 0) 51 | m_Root = TreeElementUtility.ListToTree(data); 52 | 53 | m_MaxID = m_Data.Max(e => e.id); 54 | } 55 | 56 | public int GenerateUniqueID () 57 | { 58 | return ++m_MaxID; 59 | } 60 | 61 | public IList GetAncestors (int id) 62 | { 63 | var parents = new List(); 64 | TreeElement T = Find(id); 65 | if (T != null) 66 | { 67 | while (T.parent != null) 68 | { 69 | parents.Add(T.parent.id); 70 | T = T.parent; 71 | } 72 | } 73 | return parents; 74 | } 75 | 76 | public IList GetDescendantsThatHaveChildren (int id) 77 | { 78 | T searchFromThis = Find(id); 79 | if (searchFromThis != null) 80 | { 81 | return GetParentsBelowStackBased(searchFromThis); 82 | } 83 | return new List(); 84 | } 85 | 86 | IList GetParentsBelowStackBased(TreeElement searchFromThis) 87 | { 88 | Stack stack = new Stack(); 89 | stack.Push(searchFromThis); 90 | 91 | var parentsBelow = new List(); 92 | while (stack.Count > 0) 93 | { 94 | TreeElement current = stack.Pop(); 95 | if (current.hasChildren) 96 | { 97 | parentsBelow.Add(current.id); 98 | foreach (var T in current.children) 99 | { 100 | stack.Push(T); 101 | } 102 | } 103 | } 104 | 105 | return parentsBelow; 106 | } 107 | 108 | public void RemoveElements (IList elementIDs) 109 | { 110 | IList elements = m_Data.Where (element => elementIDs.Contains (element.id)).ToArray (); 111 | RemoveElements (elements); 112 | } 113 | 114 | public void RemoveElements (IList elements) 115 | { 116 | foreach (var element in elements) 117 | if (element == m_Root) 118 | throw new ArgumentException("It is not allowed to remove the root element"); 119 | 120 | var commonAncestors = TreeElementUtility.FindCommonAncestorsWithinList (elements); 121 | 122 | foreach (var element in commonAncestors) 123 | { 124 | element.parent.children.Remove (element); 125 | element.parent = null; 126 | } 127 | 128 | TreeElementUtility.TreeToList(m_Root, m_Data); 129 | 130 | Changed(); 131 | } 132 | 133 | public void AddElements (IList elements, TreeElement parent, int insertPosition) 134 | { 135 | if (elements == null) 136 | throw new ArgumentNullException("elements", "elements is null"); 137 | if (elements.Count == 0) 138 | throw new ArgumentNullException("elements", "elements Count is 0: nothing to add"); 139 | if (parent == null) 140 | throw new ArgumentNullException("parent", "parent is null"); 141 | 142 | if (parent.children == null) 143 | parent.children = new List(); 144 | 145 | parent.children.InsertRange(insertPosition, elements.Cast ()); 146 | foreach (var element in elements) 147 | { 148 | element.parent = parent; 149 | element.depth = parent.depth + 1; 150 | TreeElementUtility.UpdateDepthValues(element); 151 | } 152 | 153 | TreeElementUtility.TreeToList(m_Root, m_Data); 154 | 155 | Changed(); 156 | } 157 | 158 | public void AddRoot (T root) 159 | { 160 | if (root == null) 161 | throw new ArgumentNullException("root", "root is null"); 162 | 163 | if (m_Data == null) 164 | throw new InvalidOperationException("Internal Error: data list is null"); 165 | 166 | if (m_Data.Count != 0) 167 | throw new InvalidOperationException("AddRoot is only allowed on empty data list"); 168 | 169 | root.id = GenerateUniqueID (); 170 | root.depth = -1; 171 | m_Data.Add (root); 172 | } 173 | 174 | public void AddElement (T element, TreeElement parent, int insertPosition) 175 | { 176 | if (element == null) 177 | throw new ArgumentNullException("element", "element is null"); 178 | if (parent == null) 179 | throw new ArgumentNullException("parent", "parent is null"); 180 | 181 | if (parent.children == null) 182 | parent.children = new List (); 183 | 184 | parent.children.Insert (insertPosition, element); 185 | element.parent = parent; 186 | 187 | TreeElementUtility.UpdateDepthValues(parent); 188 | TreeElementUtility.TreeToList(m_Root, m_Data); 189 | 190 | Changed (); 191 | } 192 | 193 | public void MoveElements(TreeElement parentElement, int insertionIndex, List elements) 194 | { 195 | if (insertionIndex < 0) 196 | throw new ArgumentException("Invalid input: insertionIndex is -1, client needs to decide what index elements should be reparented at"); 197 | 198 | // Invalid reparenting input 199 | if (parentElement == null) 200 | return; 201 | 202 | // We are moving items so we adjust the insertion index to accomodate that any items above the insertion index is removed before inserting 203 | if (insertionIndex > 0) 204 | insertionIndex -= parentElement.children.GetRange(0, insertionIndex).Count(elements.Contains); 205 | 206 | // Remove draggedItems from their parents 207 | foreach (var draggedItem in elements) 208 | { 209 | draggedItem.parent.children.Remove(draggedItem); // remove from old parent 210 | draggedItem.parent = parentElement; // set new parent 211 | } 212 | 213 | if (parentElement.children == null) 214 | parentElement.children = new List(); 215 | 216 | // Insert dragged items under new parent 217 | parentElement.children.InsertRange(insertionIndex, elements); 218 | 219 | TreeElementUtility.UpdateDepthValues (root); 220 | TreeElementUtility.TreeToList (m_Root, m_Data); 221 | 222 | Changed (); 223 | } 224 | 225 | void Changed () 226 | { 227 | if (modelChanged != null) 228 | modelChanged (); 229 | } 230 | } 231 | } 232 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TreeDataModel/TreeModel.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6f9fab1cf2636a6439c644bf08108abb 3 | timeCreated: 1472122507 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TreeMapView.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 913a835c52dcc4c299f8a63ab0aadff3 3 | timeCreated: 1440675886 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TreeViewExamples.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c39f0ef8f846c40bfb9d5287c4802538 3 | folderAsset: yes 4 | timeCreated: 1489001965 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TreeViewExamples/BackendData.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 352ae18c571bea34092dc22719650ab6 3 | folderAsset: yes 4 | timeCreated: 1472023475 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TreeViewExamples/BackendData/MyTreeAsset.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | namespace UnityEditor.TreeViewExamples 5 | { 6 | 7 | [CreateAssetMenu (fileName = "TreeDataAsset", menuName = "Tree Asset", order = 1)] 8 | public class MyTreeAsset : ScriptableObject 9 | { 10 | [SerializeField] List m_TreeElements = new List (); 11 | 12 | internal List treeElements 13 | { 14 | get { return m_TreeElements; } 15 | set { m_TreeElements = value; } 16 | } 17 | 18 | void Awake () 19 | { 20 | if (m_TreeElements.Count == 0) 21 | m_TreeElements = MyTreeElementGenerator.GenerateRandomTree(160); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TreeViewExamples/BackendData/MyTreeAsset.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 13981b66f67204744891820795ef4230 3 | timeCreated: 1471259818 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TreeViewExamples/BackendData/MyTreeAssetEditor.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_5_6 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEditor.IMGUI.Controls; 5 | 6 | 7 | namespace UnityEditor.TreeViewExamples 8 | { 9 | 10 | [CustomEditor (typeof(MyTreeAsset))] 11 | public class MyTreeAssetEditor : Editor 12 | { 13 | MyTreeView m_TreeView; 14 | const string kSessionStateKeyPrefix = "TVS"; 15 | 16 | MyTreeAsset asset 17 | { 18 | get { return (MyTreeAsset) target; } 19 | } 20 | 21 | void OnEnable () 22 | { 23 | Undo.undoRedoPerformed += OnUndoRedoPerformed; 24 | 25 | var treeViewState = new TreeViewState (); 26 | var jsonState = SessionState.GetString (kSessionStateKeyPrefix + asset.GetInstanceID (), ""); 27 | if (!string.IsNullOrEmpty (jsonState)) 28 | JsonUtility.FromJsonOverwrite (jsonState, treeViewState); 29 | var treeModel = new TreeModel (asset.treeElements); 30 | m_TreeView = new MyTreeView(treeViewState, treeModel); 31 | m_TreeView.beforeDroppingDraggedItems += OnBeforeDroppingDraggedItems; 32 | m_TreeView.Reload (); 33 | } 34 | 35 | 36 | void OnDisable () 37 | { 38 | Undo.undoRedoPerformed -= OnUndoRedoPerformed; 39 | 40 | SessionState.SetString (kSessionStateKeyPrefix + asset.GetInstanceID (), JsonUtility.ToJson (m_TreeView.state)); 41 | } 42 | 43 | void OnUndoRedoPerformed () 44 | { 45 | if (m_TreeView != null) 46 | { 47 | m_TreeView.treeModel.SetData (asset.treeElements); 48 | m_TreeView.Reload (); 49 | } 50 | } 51 | 52 | void OnBeforeDroppingDraggedItems (IList draggedRows) 53 | { 54 | Undo.RecordObject (asset, string.Format ("Moving {0} Item{1}", draggedRows.Count, draggedRows.Count > 1 ? "s" : "")); 55 | } 56 | 57 | public override void OnInspectorGUI () 58 | { 59 | GUILayout.Space (5f); 60 | ToolBar (); 61 | GUILayout.Space (3f); 62 | 63 | const float topToolbarHeight = 20f; 64 | const float spacing = 2f; 65 | float totalHeight = m_TreeView.totalHeight + topToolbarHeight + 2 * spacing; 66 | Rect rect = GUILayoutUtility.GetRect (0, 10000, 0, totalHeight); 67 | Rect toolbarRect = new Rect (rect.x, rect.y, rect.width, topToolbarHeight); 68 | Rect multiColumnTreeViewRect = new Rect (rect.x, rect.y + topToolbarHeight + spacing, rect.width, rect.height - topToolbarHeight - 2 * spacing); 69 | SearchBar (toolbarRect); 70 | DoTreeView (multiColumnTreeViewRect); 71 | } 72 | 73 | void SearchBar (Rect rect) 74 | { 75 | m_TreeView.searchString = SearchField.OnGUI (rect, m_TreeView.searchString); 76 | } 77 | 78 | void DoTreeView (Rect rect) 79 | { 80 | m_TreeView.OnGUI (rect); 81 | } 82 | 83 | void ToolBar () 84 | { 85 | using (new EditorGUILayout.HorizontalScope ()) 86 | { 87 | var style = "miniButton"; 88 | if (GUILayout.Button ("Expand All", style)) 89 | { 90 | m_TreeView.ExpandAll (); 91 | } 92 | 93 | if (GUILayout.Button ("Collapse All", style)) 94 | { 95 | m_TreeView.CollapseAll (); 96 | } 97 | 98 | GUILayout.FlexibleSpace (); 99 | 100 | if (GUILayout.Button ("Add Item", style)) 101 | { 102 | Undo.RecordObject (asset, "Add Item To Asset"); 103 | 104 | // Add item as child of selection 105 | var selection = m_TreeView.GetSelection (); 106 | TreeElement parent = (selection.Count == 1 ? m_TreeView.treeModel.Find (selection[0]) : null) ?? m_TreeView.treeModel.root; 107 | int depth = parent != null ? parent.depth + 1 : 0; 108 | int id = m_TreeView.treeModel.GenerateUniqueID (); 109 | var element = new MyTreeElement ("Item " + id, depth, id); 110 | m_TreeView.treeModel.AddElement(element, parent, 0); 111 | 112 | // Select newly created element 113 | m_TreeView.SetSelection (new[] {id}, TreeViewSelectionOptions.RevealAndFrame); 114 | } 115 | 116 | if (GUILayout.Button ("Remove Item", style)) 117 | { 118 | Undo.RecordObject (asset, "Remove Item From Asset"); 119 | var selection = m_TreeView.GetSelection (); 120 | m_TreeView.treeModel.RemoveElements (selection); 121 | } 122 | } 123 | } 124 | 125 | 126 | class MyTreeView : TreeViewWithTreeModel 127 | { 128 | public MyTreeView(TreeViewState state, TreeModel model) 129 | : base(state, model) 130 | { 131 | showBorder = true; 132 | showAlternatingRowBackgrounds = true; 133 | } 134 | } 135 | } 136 | } 137 | #endif -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TreeViewExamples/BackendData/MyTreeAssetEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7489aa2dcfff17d49bc0775cfcc18578 3 | timeCreated: 1479133171 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TreeViewExamples/BackendData/MyTreeElement.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | using Random = UnityEngine.Random; 4 | 5 | 6 | namespace UnityEditor.TreeViewExamples 7 | { 8 | 9 | [Serializable] 10 | internal class MyTreeElement : TreeElement 11 | { 12 | public float floatValue1, floatValue2, floatValue3; 13 | public Material material; 14 | public string text = ""; 15 | public bool enabled; 16 | 17 | public MyTreeElement (string name, int depth, int id) : base (name, depth, id) 18 | { 19 | floatValue1 = Random.value; 20 | floatValue2 = Random.value; 21 | floatValue3 = Random.value; 22 | enabled = true; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TreeViewExamples/BackendData/MyTreeElement.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f1bafad60d37c484dab3ce5b74c04a6a 3 | timeCreated: 1472024032 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TreeViewExamples/BackendData/MyTreeElementGenerator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Random = UnityEngine.Random; 3 | 4 | 5 | namespace UnityEditor.TreeViewExamples 6 | { 7 | 8 | static class MyTreeElementGenerator 9 | { 10 | static int IDCounter; 11 | static int minNumChildren = 5; 12 | static int maxNumChildren = 10; 13 | static float probabilityOfBeingLeaf = 0.5f; 14 | 15 | public static List GenerateRandomTree(int numTotalElements) 16 | { 17 | int numRootChildren = numTotalElements / 4; 18 | IDCounter = 0; 19 | var treeElements = new List(numTotalElements); 20 | 21 | var root = new MyTreeElement("Root", -1, IDCounter); 22 | treeElements.Add(root); 23 | for (int i = 0; i < numRootChildren; ++i) 24 | { 25 | int allowedDepth = 6; 26 | AddChildrenRecursive(root, Random.Range(minNumChildren, maxNumChildren), true, numTotalElements, ref allowedDepth, treeElements); 27 | } 28 | 29 | return treeElements; 30 | } 31 | static void AddChildrenRecursive(TreeElement element, int numChildren, bool force, int numTotalElements, ref int allowedDepth, List treeElements) 32 | { 33 | if (element.depth >= allowedDepth) 34 | { 35 | allowedDepth = 0; 36 | return; 37 | } 38 | 39 | for (int i = 0; i < numChildren; ++i) 40 | { 41 | if (IDCounter > numTotalElements) 42 | return; 43 | 44 | var child = new MyTreeElement("Element " + IDCounter, element.depth + 1, ++IDCounter); 45 | treeElements.Add(child); 46 | 47 | if (!force && Random.value < probabilityOfBeingLeaf) 48 | continue; 49 | 50 | AddChildrenRecursive(child, Random.Range(minNumChildren, maxNumChildren), false, numTotalElements, ref allowedDepth, treeElements); 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TreeViewExamples/BackendData/MyTreeElementGenerator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: be52582de2246c741b4ce116b33eca27 3 | timeCreated: 1479294126 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TreeViewExamples/BackendData/TreeViewWithTreeModel.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_5_6_OR_NEWER 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using UnityEditor.IMGUI.Controls; 6 | using UnityEngine; 7 | 8 | 9 | namespace UnityEditor.TreeViewExamples 10 | { 11 | 12 | internal class TreeViewItem : TreeViewItem where T : TreeElement 13 | { 14 | public T data { get; set; } 15 | 16 | public TreeViewItem (int id, int depth, string displayName, T data) : base (id, depth, displayName) 17 | { 18 | this.data = data; 19 | } 20 | } 21 | 22 | internal class TreeViewWithTreeModel : TreeView where T : TreeElement 23 | { 24 | TreeModel m_TreeModel; 25 | readonly List m_Rows = new List(100); 26 | public event Action treeChanged; 27 | 28 | public TreeModel treeModel { get { return m_TreeModel; } } 29 | public event Action> beforeDroppingDraggedItems; 30 | 31 | 32 | public TreeViewWithTreeModel (TreeViewState state, TreeModel model) : base (state) 33 | { 34 | Init (model); 35 | } 36 | 37 | public TreeViewWithTreeModel (TreeViewState state, MultiColumnHeader multiColumnHeader, TreeModel model) 38 | : base(state, multiColumnHeader) 39 | { 40 | Init (model); 41 | } 42 | 43 | void Init (TreeModel model) 44 | { 45 | m_TreeModel = model; 46 | m_TreeModel.modelChanged += ModelChanged; 47 | } 48 | 49 | void ModelChanged () 50 | { 51 | if (treeChanged != null) 52 | treeChanged (); 53 | 54 | Reload (); 55 | } 56 | 57 | protected override TreeViewItem BuildRoot() 58 | { 59 | int depthForHiddenRoot = -1; 60 | return new TreeViewItem(m_TreeModel.root.id, depthForHiddenRoot, m_TreeModel.root.name); 61 | } 62 | 63 | protected override IList BuildRows (TreeViewItem root) 64 | { 65 | if (m_TreeModel.root == null) 66 | { 67 | Debug.LogError ("tree model root is null. did you call SetData()?"); 68 | } 69 | 70 | m_Rows.Clear (); 71 | if (!string.IsNullOrEmpty(searchString)) 72 | { 73 | Search (m_TreeModel.root, searchString, m_Rows); 74 | } 75 | else 76 | { 77 | if (m_TreeModel.root.hasChildren) 78 | AddChildrenRecursive(m_TreeModel.root, 0, m_Rows); 79 | } 80 | 81 | // We still need to setup the child parent information for the rows since this 82 | // information is used by the TreeView internal logic (navigation, dragging etc) 83 | SetupParentsAndChildrenFromDepths (root, m_Rows); 84 | 85 | return m_Rows; 86 | } 87 | 88 | void AddChildrenRecursive (T parent, int depth, IList newRows) 89 | { 90 | foreach (T child in parent.children) 91 | { 92 | var item = new TreeViewItem(child.id, depth, child.name, child); 93 | newRows.Add(item); 94 | 95 | if (child.hasChildren) 96 | { 97 | if (IsExpanded(child.id)) 98 | { 99 | AddChildrenRecursive (child, depth + 1, newRows); 100 | } 101 | else 102 | { 103 | item.children = CreateChildListForCollapsedParent(); 104 | } 105 | } 106 | } 107 | } 108 | 109 | void Search(T searchFromThis, string search, List result) 110 | { 111 | if (string.IsNullOrEmpty(search)) 112 | throw new ArgumentException("Invalid search: cannot be null or empty", "search"); 113 | 114 | const int kItemDepth = 0; // tree is flattened when searching 115 | 116 | Stack stack = new Stack(); 117 | foreach (var element in searchFromThis.children) 118 | stack.Push((T)element); 119 | while (stack.Count > 0) 120 | { 121 | T current = stack.Pop(); 122 | // Matches search? 123 | if (current.name.IndexOf(search, StringComparison.OrdinalIgnoreCase) >= 0) 124 | { 125 | result.Add(new TreeViewItem(current.id, kItemDepth, current.name, current)); 126 | } 127 | 128 | if (current.children != null && current.children.Count > 0) 129 | { 130 | foreach (var element in current.children) 131 | { 132 | stack.Push((T)element); 133 | } 134 | } 135 | } 136 | SortSearchResult(result); 137 | } 138 | 139 | protected virtual void SortSearchResult (List rows) 140 | { 141 | rows.Sort (); // sort by displayName by default, can be overriden for multicolumn solutions 142 | } 143 | 144 | protected override IList GetAncestors (int id) 145 | { 146 | return m_TreeModel.GetAncestors(id); 147 | } 148 | 149 | protected override IList GetDescendantsThatHaveChildren (int id) 150 | { 151 | return m_TreeModel.GetDescendantsThatHaveChildren(id); 152 | } 153 | 154 | 155 | // Dragging 156 | //----------- 157 | 158 | const string k_GenericDragID = "GenericDragColumnDragging"; 159 | 160 | protected override bool CanStartDrag (CanStartDragArgs args) 161 | { 162 | return true; 163 | } 164 | 165 | protected override void SetupDragAndDrop(SetupDragAndDropArgs args) 166 | { 167 | if (hasSearch) 168 | return; 169 | 170 | DragAndDrop.PrepareStartDrag(); 171 | var draggedRows = GetRows().Where(item => args.draggedItemIDs.Contains(item.id)).ToList(); 172 | DragAndDrop.SetGenericData(k_GenericDragID, draggedRows); 173 | DragAndDrop.objectReferences = new UnityEngine.Object[] { }; // this IS required for dragging to work 174 | string title = draggedRows.Count == 1 ? draggedRows[0].displayName : "< Multiple >"; 175 | DragAndDrop.StartDrag (title); 176 | } 177 | 178 | protected override DragAndDropVisualMode HandleDragAndDrop (DragAndDropArgs args) 179 | { 180 | // Check if we can handle the current drag data (could be dragged in from other areas/windows in the editor) 181 | var draggedRows = DragAndDrop.GetGenericData(k_GenericDragID) as List; 182 | if (draggedRows == null) 183 | return DragAndDropVisualMode.None; 184 | 185 | // Parent item is null when dragging outside any tree view items. 186 | switch (args.dragAndDropPosition) 187 | { 188 | case DragAndDropPosition.UponItem: 189 | case DragAndDropPosition.BetweenItems: 190 | { 191 | bool validDrag = ValidDrag(args.parentItem, draggedRows); 192 | if (args.performDrop && validDrag) 193 | { 194 | T parentData = ((TreeViewItem)args.parentItem).data; 195 | OnDropDraggedElementsAtIndex(draggedRows, parentData, args.insertAtIndex == -1 ? 0 : args.insertAtIndex); 196 | } 197 | return validDrag ? DragAndDropVisualMode.Move : DragAndDropVisualMode.None; 198 | } 199 | 200 | case DragAndDropPosition.OutsideItems: 201 | { 202 | if (args.performDrop) 203 | OnDropDraggedElementsAtIndex(draggedRows, m_TreeModel.root, m_TreeModel.root.children.Count); 204 | 205 | return DragAndDropVisualMode.Move; 206 | } 207 | default: 208 | Debug.LogError("Unhandled enum " + args.dragAndDropPosition); 209 | return DragAndDropVisualMode.None; 210 | } 211 | } 212 | 213 | public virtual void OnDropDraggedElementsAtIndex (List draggedRows, T parent, int insertIndex) 214 | { 215 | if (beforeDroppingDraggedItems != null) 216 | beforeDroppingDraggedItems (draggedRows); 217 | 218 | var draggedElements = new List (); 219 | foreach (var x in draggedRows) 220 | draggedElements.Add (((TreeViewItem) x).data); 221 | 222 | var selectedIDs = draggedElements.Select (x => x.id).ToArray(); 223 | m_TreeModel.MoveElements (parent, insertIndex, draggedElements); 224 | SetSelection(selectedIDs, TreeViewSelectionOptions.RevealAndFrame); 225 | } 226 | 227 | 228 | bool ValidDrag(TreeViewItem parent, List draggedItems) 229 | { 230 | TreeViewItem currentParent = parent; 231 | while (currentParent != null) 232 | { 233 | if (draggedItems.Contains(currentParent)) 234 | return false; 235 | currentParent = currentParent.parent; 236 | } 237 | return true; 238 | } 239 | 240 | } 241 | 242 | } 243 | #endif -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TreeViewExamples/BackendData/TreeViewWithTreeModel.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 68fe63fd42552e7418aac450b41b8afb 3 | timeCreated: 1472481611 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TreeViewExamples/MultiColumnTreeView.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e00d20ba7c1f4d446a34ea24d8b82c4e 3 | timeCreated: 1464348051 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TreeViewExamples/MultiColumnWindow.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_5_6 2 | using System; 3 | using System.Collections.Generic; 4 | using UnityEditor.Callbacks; 5 | using UnityEditor.IMGUI.Controls; 6 | using UnityEngine; 7 | 8 | 9 | namespace UnityEditor.TreeViewExamples 10 | { 11 | 12 | class MultiColumnWindow : EditorWindow 13 | { 14 | [NonSerialized] bool m_Initialized; 15 | [SerializeField] TreeViewState m_TreeViewState; // Serialized in the window layout file so it survives assembly reloading 16 | [SerializeField] MultiColumnHeaderState m_MultiColumnHeaderState; 17 | MultiColumnTreeView m_TreeView; 18 | MyTreeAsset m_MyTreeAsset; 19 | 20 | [MenuItem("TreeView Examples/Multi Columns")] 21 | public static MultiColumnWindow GetWindow () 22 | { 23 | var window = GetWindow(); 24 | window.titleContent = new GUIContent("Multi Columns"); 25 | window.Focus(); 26 | window.Repaint(); 27 | return window; 28 | } 29 | 30 | [OnOpenAsset] 31 | public static bool OnOpenAsset (int instanceID, int line) 32 | { 33 | var myTreeAsset = EditorUtility.InstanceIDToObject (instanceID) as MyTreeAsset; 34 | if (myTreeAsset != null) 35 | { 36 | var window = GetWindow (); 37 | window.SetTreeAsset(myTreeAsset); 38 | return true; 39 | } 40 | return false; // we did not handle the open 41 | } 42 | 43 | void SetTreeAsset (MyTreeAsset myTreeAsset) 44 | { 45 | m_MyTreeAsset = myTreeAsset; 46 | m_Initialized = false; 47 | } 48 | 49 | Rect multiColumnTreeViewRect 50 | { 51 | get { return new Rect(20, 30, position.width-40, position.height-60); } 52 | } 53 | 54 | Rect toolbarRect 55 | { 56 | get { return new Rect (20f, 10f, position.width-40f, 20f); } 57 | } 58 | 59 | Rect bottomToolbarRect 60 | { 61 | get { return new Rect(20f, position.height - 18f, position.width - 40f, 16f); } 62 | } 63 | 64 | public MultiColumnTreeView treeView 65 | { 66 | get { return m_TreeView; } 67 | } 68 | 69 | void InitIfNeeded () 70 | { 71 | if (!m_Initialized) 72 | { 73 | // Check if it already exists (deserialized from window layout file or scriptable object) 74 | if (m_TreeViewState == null) 75 | m_TreeViewState = new TreeViewState(); 76 | 77 | var headerState = MultiColumnTreeView.CreateDefaultMultiColumnHeaderState(multiColumnTreeViewRect.width); 78 | if (MultiColumnHeaderState.CanOverwriteSerializedFields(m_MultiColumnHeaderState, headerState)) 79 | MultiColumnHeaderState.OverwriteSerializedFields(m_MultiColumnHeaderState, headerState); 80 | m_MultiColumnHeaderState = headerState; 81 | 82 | var multiColumnHeader = new MyMultiColumnHeader(headerState); 83 | var treeModel = new TreeModel(GetData()); 84 | m_TreeView = new MultiColumnTreeView(m_TreeViewState, multiColumnHeader, treeModel); 85 | 86 | m_Initialized = true; 87 | } 88 | } 89 | 90 | IList GetData () 91 | { 92 | if (m_MyTreeAsset != null && m_MyTreeAsset.treeElements != null && m_MyTreeAsset.treeElements.Count > 0) 93 | return m_MyTreeAsset.treeElements; 94 | 95 | // generate some test data 96 | return MyTreeElementGenerator.GenerateRandomTree(130); 97 | } 98 | 99 | void OnSelectionChange () 100 | { 101 | if (!m_Initialized) 102 | return; 103 | 104 | var myTreeAsset = Selection.activeObject as MyTreeAsset; 105 | if (myTreeAsset != null && myTreeAsset != m_MyTreeAsset) 106 | { 107 | m_MyTreeAsset = myTreeAsset; 108 | m_TreeView.treeModel.SetData (GetData ()); 109 | m_TreeView.Reload (); 110 | } 111 | } 112 | 113 | void OnGUI () 114 | { 115 | InitIfNeeded(); 116 | 117 | SearchBar (toolbarRect); 118 | DoTreeView (multiColumnTreeViewRect); 119 | BottomToolBar (bottomToolbarRect); 120 | } 121 | 122 | void SearchBar (Rect rect) 123 | { 124 | treeView.searchString = SearchField.OnGUI(rect, treeView.searchString); 125 | } 126 | 127 | void DoTreeView (Rect rect) 128 | { 129 | m_TreeView.OnGUI(rect); 130 | } 131 | 132 | void BottomToolBar (Rect rect) 133 | { 134 | GUILayout.BeginArea (rect); 135 | 136 | using (new EditorGUILayout.HorizontalScope ()) 137 | { 138 | 139 | var style = "miniButton"; 140 | if (GUILayout.Button("Expand All", style)) 141 | { 142 | treeView.ExpandAll (); 143 | } 144 | 145 | if (GUILayout.Button("Collapse All", style)) 146 | { 147 | treeView.CollapseAll (); 148 | } 149 | 150 | GUILayout.FlexibleSpace(); 151 | 152 | GUILayout.Label (m_MyTreeAsset != null ? AssetDatabase.GetAssetPath (m_MyTreeAsset) : string.Empty); 153 | 154 | GUILayout.FlexibleSpace (); 155 | 156 | GUILayout.Label ("Header: ", "minilabel"); 157 | if (GUILayout.Button("Large", style)) 158 | { 159 | var myColumnHeader = (MyMultiColumnHeader) treeView.multiColumnHeader; 160 | myColumnHeader.mode = MyMultiColumnHeader.Mode.LargeHeader; 161 | } 162 | if (GUILayout.Button("Default", style)) 163 | { 164 | var myColumnHeader = (MyMultiColumnHeader)treeView.multiColumnHeader; 165 | myColumnHeader.mode = MyMultiColumnHeader.Mode.DefaultHeader; 166 | } 167 | if (GUILayout.Button("No sort", style)) 168 | { 169 | var myColumnHeader = (MyMultiColumnHeader)treeView.multiColumnHeader; 170 | myColumnHeader.mode = MyMultiColumnHeader.Mode.MinimumHeaderWithoutSorting; 171 | } 172 | 173 | GUILayout.Space (10); 174 | 175 | if (GUILayout.Button("values <-> controls", style)) 176 | { 177 | treeView.showControls = !treeView.showControls; 178 | } 179 | } 180 | 181 | GUILayout.EndArea(); 182 | } 183 | } 184 | 185 | 186 | class MyMultiColumnHeader : MultiColumnHeader 187 | { 188 | Mode m_Mode; 189 | 190 | public enum Mode 191 | { 192 | LargeHeader, 193 | DefaultHeader, 194 | MinimumHeaderWithoutSorting 195 | } 196 | 197 | public MyMultiColumnHeader(MultiColumnHeaderState state) 198 | : base(state) 199 | { 200 | mode = Mode.DefaultHeader; 201 | } 202 | 203 | public Mode mode 204 | { 205 | get 206 | { 207 | return m_Mode; 208 | } 209 | set 210 | { 211 | m_Mode = value; 212 | switch (m_Mode) 213 | { 214 | case Mode.LargeHeader: 215 | canSort = true; 216 | height = 37f; 217 | break; 218 | case Mode.DefaultHeader: 219 | canSort = true; 220 | height = DefaultGUI.defaultHeight; 221 | break; 222 | case Mode.MinimumHeaderWithoutSorting: 223 | canSort = false; 224 | height = DefaultGUI.minimumHeight; 225 | break; 226 | } 227 | } 228 | } 229 | 230 | protected override void ColumnHeaderGUI (MultiColumnHeaderState.Column column, Rect headerRect, int columnIndex) 231 | { 232 | // Default column header gui 233 | base.ColumnHeaderGUI(column, headerRect, columnIndex); 234 | 235 | // Add additional info for large header 236 | if (mode == Mode.LargeHeader) 237 | { 238 | // Show example overlay stuff on some of the columns 239 | if (columnIndex > 2) 240 | { 241 | headerRect.xMax -= 3f; 242 | var oldAlignment = EditorStyles.largeLabel.alignment; 243 | EditorStyles.largeLabel.alignment = TextAnchor.UpperRight; 244 | GUI.Label(headerRect, 36 + columnIndex + "%", EditorStyles.largeLabel); 245 | EditorStyles.largeLabel.alignment = oldAlignment; 246 | } 247 | } 248 | } 249 | } 250 | 251 | 252 | internal static class SearchField 253 | { 254 | static class Styles 255 | { 256 | public static GUIStyle searchField = "SearchTextField"; 257 | public static GUIStyle searchFieldCancelButton = "SearchCancelButton"; 258 | public static GUIStyle searchFieldCancelButtonEmpty = "SearchCancelButtonEmpty"; 259 | } 260 | 261 | public static string OnGUI(Rect position, string text) 262 | { 263 | // Search field 264 | Rect textRect = position; 265 | textRect.width -= 15; 266 | text = EditorGUI.TextField(textRect, GUIContent.none, text, Styles.searchField); 267 | 268 | // Cancel button 269 | Rect buttonRect = position; 270 | buttonRect.x += position.width - 15; 271 | buttonRect.width = 15; 272 | if (GUI.Button(buttonRect, GUIContent.none, text != "" ? Styles.searchFieldCancelButton : Styles.searchFieldCancelButtonEmpty) && text != "") 273 | { 274 | text = ""; 275 | GUIUtility.keyboardControl = 0; 276 | } 277 | return text; 278 | } 279 | } 280 | 281 | } 282 | #endif -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TreeViewExamples/MultiColumnWindow.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c3cf55b48c197bb40a09696dead1d7c2 3 | timeCreated: 1467106475 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TreeViewExamples/SimpleTreeView.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_5_6 2 | using System.Collections.Generic; 3 | using UnityEditor.IMGUI.Controls; 4 | 5 | 6 | namespace UnityEditor.TreeViewExamples 7 | { 8 | class SimpleTreeView : TreeView 9 | { 10 | public SimpleTreeView(TreeViewState treeViewState) 11 | : base(treeViewState) 12 | { 13 | Reload(); 14 | } 15 | 16 | protected override TreeViewItem BuildRoot () 17 | { 18 | // BuildRoot is called every time Reload is called to ensure that TreeViewItems 19 | // are created from data. Here we just create a fixed set of items, in a real world example 20 | // a data model should be passed into the TreeView and the items created from the model. 21 | 22 | // This section illustrates that IDs should be unique and that the root item is required to 23 | // have a depth of -1 and the rest of the items increment from that. 24 | var root = new TreeViewItem {id = 0, depth = -1, displayName = "Root"}; 25 | var allItems = new List 26 | { 27 | new TreeViewItem {id = 1, depth = 0, displayName = "Animals"}, 28 | new TreeViewItem {id = 2, depth = 1, displayName = "Mammals"}, 29 | new TreeViewItem {id = 3, depth = 2, displayName = "Tiger"}, 30 | new TreeViewItem {id = 4, depth = 2, displayName = "Elephant"}, 31 | new TreeViewItem {id = 5, depth = 2, displayName = "Okapi"}, 32 | new TreeViewItem {id = 6, depth = 2, displayName = "Armadillo"}, 33 | new TreeViewItem {id = 7, depth = 1, displayName = "Reptiles"}, 34 | new TreeViewItem {id = 8, depth = 2, displayName = "Crocodile"}, 35 | new TreeViewItem {id = 9, depth = 2, displayName = "Lizard"}, 36 | }; 37 | 38 | // Utility method that initializes the TreeViewItem.children and -parent for all items. 39 | SetupParentsAndChildrenFromDepths (root, allItems); 40 | 41 | // Return root of the tree 42 | return root; 43 | } 44 | } 45 | } 46 | #endif 47 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TreeViewExamples/SimpleTreeView.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c6ec9339cdd18884083a3b02329a12ca 3 | timeCreated: 1471507965 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TreeViewExamples/SimpleTreeViewWindow.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_5_6 2 | using UnityEngine; 3 | using UnityEditor.IMGUI.Controls; 4 | 5 | 6 | namespace UnityEditor.TreeViewExamples 7 | { 8 | class SimpleTreeViewWindow : EditorWindow 9 | { 10 | // We are using SerializeField here to make sure view state is written to the window 11 | // layout file. This means that the state survives restarting Unity as long as the window 12 | // is not closed. If omitting the attribute then the state just survives assembly reloading 13 | // (i.e. it still gets serialized/deserialized) 14 | [SerializeField] TreeViewState m_TreeViewState; 15 | 16 | // The TreeView is not serializable it should be reconstructed from the tree data. 17 | SimpleTreeView m_SimpleTreeView; 18 | 19 | void OnEnable () 20 | { 21 | // Check if we already had a serialized view state (state 22 | // that survived assembly reloading) 23 | if (m_TreeViewState == null) 24 | m_TreeViewState = new TreeViewState (); 25 | 26 | m_SimpleTreeView = new SimpleTreeView(m_TreeViewState); 27 | } 28 | 29 | void OnGUI () 30 | { 31 | m_SimpleTreeView.OnGUI(new Rect(0, 0, position.width, position.height)); 32 | } 33 | 34 | // Add menu named "My Window" to the Window menu 35 | [MenuItem ("TreeView Examples/Simple Tree Window")] 36 | static void ShowWindow () 37 | { 38 | // Get existing open window or if none, make a new one: 39 | var window = GetWindow (); 40 | window.titleContent = new GUIContent ("My Window"); 41 | window.Show (); 42 | } 43 | } 44 | } 45 | #endif -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TreeViewExamples/SimpleTreeViewWindow.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 55ce904866ab5b74f98c6fbff125c69b 3 | timeCreated: 1471510735 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TreeViewExamples/TransformsTreeView.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_5_6 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using UnityEditor.IMGUI.Controls; 6 | using UnityEngine; 7 | using UnityEngine.SceneManagement; 8 | using UnityObject = UnityEngine.Object; 9 | 10 | 11 | namespace UnityEditor.TreeViewExamples 12 | { 13 | 14 | class TransformTreeView : TreeView 15 | { 16 | public TransformTreeView (TreeViewState state) 17 | : base (state) 18 | { 19 | Reload (); 20 | } 21 | 22 | protected override TreeViewItem BuildRoot() 23 | { 24 | return new TreeViewItem {id = 0, depth = -1}; 25 | } 26 | 27 | protected override IList BuildRows(TreeViewItem root) 28 | { 29 | var rows = GetRows () ?? new List (200); 30 | 31 | Scene scene = SceneManager.GetSceneAt (0); 32 | 33 | // We use the GameObject instanceIDs as ids for items as we want to 34 | // select the game objects and not the transform components. 35 | rows.Clear (); 36 | var gameObjectRoots = scene.GetRootGameObjects (); 37 | foreach (var gameObject in gameObjectRoots) 38 | { 39 | var item = CreateTreeViewItemForGameObject (gameObject); 40 | root.AddChild (item); 41 | rows.Add (item); 42 | if (gameObject.transform.childCount > 0) 43 | { 44 | if (IsExpanded (item.id)) 45 | { 46 | AddChildrenRecursive (gameObject, item, rows); 47 | } 48 | else 49 | { 50 | item.children = CreateChildListForCollapsedParent (); 51 | } 52 | } 53 | } 54 | 55 | SetupDepthsFromParentsAndChildren (root); 56 | return rows; 57 | } 58 | 59 | void AddChildrenRecursive (GameObject go, TreeViewItem item, IList rows) 60 | { 61 | int childCount = go.transform.childCount; 62 | 63 | item.children = new List (childCount); 64 | for (int i = 0; i < childCount; ++i) 65 | { 66 | var childTransform = go.transform.GetChild (i); 67 | var childItem = CreateTreeViewItemForGameObject (childTransform.gameObject); 68 | item.AddChild (childItem); 69 | rows.Add (childItem); 70 | 71 | if (childTransform.childCount > 0) 72 | { 73 | if (IsExpanded (childItem.id)) 74 | { 75 | AddChildrenRecursive (childTransform.gameObject, childItem, rows); 76 | } 77 | else 78 | { 79 | childItem.children = CreateChildListForCollapsedParent (); 80 | } 81 | } 82 | } 83 | } 84 | 85 | static TreeViewItem CreateTreeViewItemForGameObject (GameObject gameObject) 86 | { 87 | // We can use the GameObject instanceID for TreeViewItem id, as it ensured to be unique among other items in the tree. 88 | // To optimize reload time we could delay fetching the transform.name until it used for rendering (prevents allocating strings 89 | // for items not rendered in large trees) 90 | // We just set depth to -1 here and then call SetupDepthsFromParentsAndChildren at the end of BuildRootAndRows to set the depths. 91 | return new TreeViewItem(gameObject.GetInstanceID(), -1, gameObject.name); 92 | } 93 | 94 | protected override IList GetAncestors (int id) 95 | { 96 | // The backend needs to provide us with this info since the item with id 97 | // may not be present in the rows 98 | var transform = GetGameObject(id).transform; 99 | 100 | List ancestors = new List (); 101 | while (transform.parent != null) 102 | { 103 | ancestors.Add (transform.parent.gameObject.GetInstanceID ()); 104 | transform = transform.parent; 105 | } 106 | 107 | return ancestors; 108 | } 109 | 110 | protected override IList GetDescendantsThatHaveChildren (int id) 111 | { 112 | Stack stack = new Stack (); 113 | 114 | var start = GetGameObject(id).transform; 115 | stack.Push (start); 116 | 117 | var parents = new List (); 118 | while (stack.Count > 0) 119 | { 120 | Transform current = stack.Pop (); 121 | parents.Add (current.gameObject.GetInstanceID ()); 122 | for (int i = 0; i < current.childCount; ++i) 123 | { 124 | if (current.childCount > 0) 125 | stack.Push (current.GetChild (i)); 126 | } 127 | } 128 | 129 | return parents; 130 | } 131 | 132 | GameObject GetGameObject (int instanceID) 133 | { 134 | return (GameObject)EditorUtility.InstanceIDToObject(instanceID); 135 | } 136 | 137 | // Custom GUI 138 | 139 | protected override void RowGUI (RowGUIArgs args) 140 | { 141 | Event evt = Event.current; 142 | extraSpaceBeforeIconAndLabel = 18f; 143 | 144 | // GameObject isStatic toggle 145 | var gameObject = GetGameObject(args.item.id); 146 | if (gameObject == null) 147 | return; 148 | 149 | Rect toggleRect = args.rowRect; 150 | toggleRect.x += GetContentIndent(args.item); 151 | toggleRect.width = 16f; 152 | 153 | // Ensure row is selected before using the toggle (usability) 154 | if (evt.type == EventType.MouseDown && toggleRect.Contains(evt.mousePosition)) 155 | SelectionClick(args.item, false); 156 | 157 | EditorGUI.BeginChangeCheck (); 158 | bool isStatic = EditorGUI.Toggle(toggleRect, gameObject.isStatic); 159 | if (EditorGUI.EndChangeCheck ()) 160 | gameObject.isStatic = isStatic; 161 | 162 | // Text 163 | base.RowGUI(args); 164 | } 165 | 166 | // Selection 167 | 168 | protected override void SelectionChanged (IList selectedIds) 169 | { 170 | Selection.instanceIDs = selectedIds.ToArray(); 171 | } 172 | 173 | // Reordering 174 | 175 | protected override bool CanStartDrag (CanStartDragArgs args) 176 | { 177 | return true; 178 | } 179 | 180 | protected override void SetupDragAndDrop (SetupDragAndDropArgs args) 181 | { 182 | DragAndDrop.PrepareStartDrag (); 183 | 184 | var sortedDraggedIDs = SortItemIDsInRowOrder (args.draggedItemIDs); 185 | 186 | List objList = new List (sortedDraggedIDs.Count); 187 | foreach (var id in sortedDraggedIDs) 188 | { 189 | UnityObject obj = EditorUtility.InstanceIDToObject (id); 190 | if (obj != null) 191 | objList.Add (obj); 192 | } 193 | 194 | DragAndDrop.objectReferences = objList.ToArray (); 195 | 196 | string title = objList.Count > 1 ? "" : objList[0].name; 197 | DragAndDrop.StartDrag (title); 198 | } 199 | 200 | protected override DragAndDropVisualMode HandleDragAndDrop (DragAndDropArgs args) 201 | { 202 | // First check if the dragged objects are GameObjects 203 | var draggedObjects = DragAndDrop.objectReferences; 204 | var transforms = new List (draggedObjects.Length); 205 | foreach (var obj in draggedObjects) 206 | { 207 | var go = obj as GameObject; 208 | if (go == null) 209 | { 210 | return DragAndDropVisualMode.None; 211 | } 212 | 213 | transforms.Add (go.transform); 214 | } 215 | 216 | // Filter out any unnecessary transforms before the reparent operation 217 | RemoveItemsThatAreDescendantsFromOtherItems (transforms); 218 | 219 | // Reparent 220 | if (args.performDrop) 221 | { 222 | switch (args.dragAndDropPosition) 223 | { 224 | case DragAndDropPosition.UponItem: 225 | case DragAndDropPosition.BetweenItems: 226 | Transform parent = args.parentItem != null ? GetGameObject (args.parentItem.id).transform : null; 227 | 228 | if (!IsValidReparenting (parent, transforms)) 229 | return DragAndDropVisualMode.None; 230 | 231 | foreach (var trans in transforms) 232 | trans.SetParent (parent); 233 | 234 | if (args.dragAndDropPosition == DragAndDropPosition.BetweenItems) 235 | { 236 | int insertIndex = args.insertAtIndex; 237 | for (int i = transforms.Count - 1; i >= 0; i--) 238 | { 239 | var transform = transforms[i]; 240 | insertIndex = GetAdjustedInsertIndex (parent, transform, insertIndex); 241 | transform.SetSiblingIndex (insertIndex); 242 | } 243 | } 244 | break; 245 | 246 | case DragAndDropPosition.OutsideItems: 247 | foreach (var trans in transforms) 248 | { 249 | trans.SetParent (null); // make root when dragged to empty space in treeview 250 | } 251 | break; 252 | default: 253 | throw new ArgumentOutOfRangeException (); 254 | } 255 | 256 | Reload (); 257 | SetSelection (transforms.Select (t => t.gameObject.GetInstanceID ()).ToList (), TreeViewSelectionOptions.RevealAndFrame); 258 | } 259 | 260 | return DragAndDropVisualMode.Move; 261 | } 262 | 263 | int GetAdjustedInsertIndex (Transform parent, Transform transformToInsert, int insertIndex) 264 | { 265 | if (transformToInsert.parent == parent && transformToInsert.GetSiblingIndex () < insertIndex) 266 | return --insertIndex; 267 | return insertIndex; 268 | } 269 | 270 | bool IsValidReparenting (Transform parent, List transformsToMove) 271 | { 272 | if (parent == null) 273 | return true; 274 | 275 | foreach (var transformToMove in transformsToMove) 276 | { 277 | if (transformToMove == parent) 278 | return false; 279 | 280 | if (IsHoveredAChildOfDragged (parent, transformToMove)) 281 | return false; 282 | } 283 | 284 | return true; 285 | } 286 | 287 | 288 | bool IsHoveredAChildOfDragged (Transform hovered, Transform dragged) 289 | { 290 | Transform t = hovered.parent; 291 | while (t) 292 | { 293 | if (t == dragged) 294 | return true; 295 | t = t.parent; 296 | } 297 | return false; 298 | } 299 | 300 | 301 | // Returns true if there is an ancestor of transform in the transforms list 302 | static bool IsDescendantOf (Transform transform, List transforms) 303 | { 304 | while (transform != null) 305 | { 306 | transform = transform.parent; 307 | if (transforms.Contains (transform)) 308 | return true; 309 | } 310 | return false; 311 | } 312 | 313 | static void RemoveItemsThatAreDescendantsFromOtherItems (List transforms) 314 | { 315 | transforms.RemoveAll (t => IsDescendantOf (t, transforms)); 316 | } 317 | } 318 | } 319 | #endif -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TreeViewExamples/TransformsTreeView.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d43a0b261d587eb40a8a53f44b0b78de 3 | timeCreated: 1474880986 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TreeViewExamples/TransformsTreeViewWindow.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_5_6 2 | using UnityEngine; 3 | using UnityEditor.IMGUI.Controls; 4 | 5 | 6 | namespace UnityEditor.TreeViewExamples 7 | { 8 | 9 | class TransformTreeWindow : EditorWindow 10 | { 11 | [SerializeField] TreeViewState m_TreeViewState; 12 | 13 | TreeView m_TreeView; 14 | 15 | [MenuItem("TreeView Examples/Transform Hierarchy")] 16 | static void ShowWindow() 17 | { 18 | var window = GetWindow(); 19 | window.titleContent = new GUIContent("My Hierarchy"); 20 | window.Show(); 21 | } 22 | 23 | void OnEnable () 24 | { 25 | if (m_TreeViewState == null) 26 | m_TreeViewState = new TreeViewState (); 27 | 28 | m_TreeView = new TransformTreeView (m_TreeViewState); 29 | } 30 | 31 | void OnSelectionChange () 32 | { 33 | if (m_TreeView != null) 34 | m_TreeView.SetSelection (Selection.instanceIDs); 35 | Repaint (); 36 | } 37 | 38 | void OnHierarchyChange() 39 | { 40 | if (m_TreeView != null) 41 | m_TreeView.Reload(); 42 | Repaint (); 43 | } 44 | 45 | void OnGUI () 46 | { 47 | DoToolbar (); 48 | DoTreeView (); 49 | 50 | } 51 | 52 | void DoTreeView () 53 | { 54 | Rect rect = GUILayoutUtility.GetRect (0, 100000, 0, 100000); 55 | m_TreeView.OnGUI(rect); 56 | } 57 | 58 | void DoToolbar() 59 | { 60 | GUILayout.BeginHorizontal(EditorStyles.toolbar); 61 | GUILayout.FlexibleSpace (); 62 | GUILayout.EndHorizontal(); 63 | } 64 | } 65 | } 66 | #endif -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TreeViewExamples/TransformsTreeViewWindow.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 69a3f5517e7b1a248a1a374189b1ba7b 3 | timeCreated: 1471510735 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/Treemap.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d920f113b272aeb458461ce1ddc647b6 3 | folderAsset: yes 4 | timeCreated: 1439479925 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/Treemap/Group.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Assets.Editor.Treemap; 6 | using MemoryProfilerWindow; 7 | using UnityEditor; 8 | using UnityEngine; 9 | 10 | namespace Treemap 11 | { 12 | public class Group : IComparable, ITreemapRenderable 13 | { 14 | public string _name; 15 | public Rect _position; 16 | public List _items; 17 | private float _totalMemorySize = -1; 18 | 19 | public float totalMemorySize 20 | { 21 | get 22 | { 23 | if (_totalMemorySize != -1) 24 | return _totalMemorySize; 25 | 26 | long result = 0; 27 | foreach (Item item in _items) 28 | { 29 | result += item.memorySize; 30 | } 31 | _totalMemorySize = result; 32 | return result; 33 | } 34 | } 35 | 36 | public float[] memorySizes 37 | { 38 | get 39 | { 40 | float[] result = new float[_items.Count]; 41 | for (int i = 0; i < _items.Count; i++) 42 | { 43 | result[i] = _items[i].memorySize; 44 | } 45 | return result; 46 | } 47 | } 48 | 49 | public Color color 50 | { 51 | get { return Utility.GetColorForName(_name); } 52 | } 53 | 54 | public int CompareTo(Group other) 55 | { 56 | return (int)(other.totalMemorySize - totalMemorySize); 57 | } 58 | 59 | public Color GetColor() 60 | { 61 | return color; 62 | } 63 | 64 | public Rect GetPosition() 65 | { 66 | return _position; 67 | } 68 | 69 | public string GetLabel() 70 | { 71 | string row1 = string.Format("{0} ({1})", _name, _items != null ? _items.Count : 0); 72 | string row2 = EditorUtility.FormatBytes((long)totalMemorySize); 73 | return row1 + "\n" + row2; 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/Treemap/Group.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e0b6c9ac7c2131b41b61f5edeac7fc75 3 | timeCreated: 1439890712 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/Treemap/ITreemapRenderable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using UnityEditor.Graphs; 6 | using UnityEngine; 7 | 8 | namespace Assets.Editor.Treemap 9 | { 10 | interface ITreemapRenderable 11 | { 12 | Color GetColor(); 13 | Rect GetPosition(); 14 | string GetLabel(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/Treemap/ITreemapRenderable.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 12002ec55883de249bd51b714c983743 3 | timeCreated: 1458809711 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/Treemap/Item.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using MemoryProfilerWindow; 6 | using Treemap; 7 | using UnityEditor; 8 | using UnityEditor.Graphs; 9 | using UnityEngine; 10 | 11 | namespace Assets.Editor.Treemap 12 | { 13 | public class Item : IComparable, ITreemapRenderable 14 | { 15 | public Group _group; 16 | public Rect _position; 17 | public int _index; 18 | 19 | public ThingInMemory _thingInMemory; 20 | 21 | public long memorySize { get { return _thingInMemory.size; } } 22 | public string name { get { return _thingInMemory.caption; } } 23 | public Color color { get { return _group.color; } } 24 | 25 | public Item(ThingInMemory thingInMemory, Group group) 26 | { 27 | _thingInMemory = thingInMemory; 28 | _group = group; 29 | } 30 | 31 | public int CompareTo(Item other) 32 | { 33 | return (int)(_group != other._group ? other._group.totalMemorySize - _group.totalMemorySize : other.memorySize - memorySize); 34 | } 35 | 36 | public Color GetColor() 37 | { 38 | return _group.color; 39 | } 40 | 41 | public Rect GetPosition() 42 | { 43 | return _position; 44 | } 45 | 46 | public string GetLabel() 47 | { 48 | string row1 = _group._name; 49 | string row2 = EditorUtility.FormatBytes(memorySize); 50 | return row1 + "\n" + row2; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/Treemap/Item.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1a02ee1f4fc387048a67581d2415d83d 3 | timeCreated: 1439890711 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/Treemap/Tests.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: efcc1b8fe2e199a4fbbee067dd0cc96f 3 | folderAsset: yes 4 | timeCreated: 1458809711 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/Treemap/Tests/TreemapTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NUnit.Framework; 3 | using UnityEngine; 4 | using System.Collections.Generic; 5 | using System.Collections; 6 | using System.Linq; 7 | 8 | namespace Treemap 9 | { 10 | [TestFixture] 11 | public class TreemapTests 12 | { 13 | static readonly Rect s_Rect = new UnityEngine.Rect (0, 0, 100, 100); 14 | 15 | [Test] 16 | public void Empty() 17 | { 18 | Assert.Throws(() => Utility.GetTreemapRects (new float[0], s_Rect)); 19 | } 20 | 21 | [Test] 22 | public void One() 23 | { 24 | var result = Utility.GetTreemapRects (new [] { 1.0f }, s_Rect); 25 | Assert.AreEqual (1, result.Length); 26 | Assert.AreEqual (s_Rect, result[0]); 27 | } 28 | 29 | [Test] 30 | public void TwoEquallySized() 31 | { 32 | var result = Utility.GetTreemapRects (new [] { 1.0f, 1.0f }, s_Rect); 33 | Assert.AreEqual (2, result.Length); 34 | 35 | Assert.AreEqual (new Rect (0, 0, 100, 50), result [0]); 36 | Assert.AreEqual (new Rect (0, 50, 100, 50), result [1]); 37 | } 38 | 39 | [Test] 40 | public void Zero() 41 | { 42 | Assert.Throws(() => Utility.GetTreemapRects (new [] { 0f }, s_Rect)); 43 | } 44 | 45 | [Test] 46 | public void NegativeNumber() 47 | { 48 | Assert.Throws(() => Utility.GetTreemapRects (new [] { -3f }, s_Rect)); 49 | } 50 | 51 | [Test, TestCaseSource("InterestingDataSets")] 52 | public void ResultRectsHaveCorrectArea(float[] floats) 53 | { 54 | var results = Utility.GetTreemapRects (floats, s_Rect); 55 | Assert.AreEqual (floats.Length, results.Length); 56 | 57 | var sum = floats.Sum (); 58 | var totalSize = s_Rect.width * s_Rect.height; 59 | 60 | for(int i =0; i!= floats.Length; i++) 61 | { 62 | var f = floats [i]; 63 | var r = results [i]; 64 | 65 | var size = r.width * r.height; 66 | var ratio = size / totalSize; 67 | 68 | UnityEngine.Assertions.Assert.AreApproximatelyEqual (f / sum, ratio); 69 | } 70 | } 71 | 72 | [Test, TestCaseSource("InterestingDataSets")] 73 | public void ResultRectsDoNotOverlap(float[] floats) 74 | { 75 | var results = Utility.GetTreemapRects (floats, s_Rect); 76 | Assert.AreEqual (floats.Length, results.Length); 77 | 78 | for(int i1 =0; i1!= floats.Length; i1++) 79 | { 80 | var rect1 = results [i1]; 81 | for (int i2 = i1 + 1; i2 != floats.Length; i2++) { 82 | var rect2 = results [i2]; 83 | 84 | float overlapSize = SizeOfOverlappingRectOf(rect1, rect2); 85 | 86 | const float tolerance = 0.000001f; 87 | if (overlapSize > tolerance * rect1.width * rect1.height || overlapSize > tolerance * rect2.width * rect2.height) 88 | throw new AssertionException ("too big overlap. overlapSize: " + overlapSize + " rect1:" + rect1 + " rect2: " + rect2); 89 | } 90 | } 91 | } 92 | 93 | private static Rect RectIntersect(Rect a, Rect b) 94 | { 95 | float xMin = Mathf.Max(a.x, b.x); 96 | float xMax = Mathf.Min(a.x + a.width, b.x + b.width); 97 | float yMin = Mathf.Max(a.y, b.y); 98 | float yMax = Mathf.Min(a.y + a.height, b.y + b.height); 99 | if (xMax >= xMin && yMax >= yMin) 100 | return new Rect(xMin, yMin, xMax - xMin, yMax - yMin); 101 | return new Rect(0f, 0f, 0f, 0f); 102 | } 103 | 104 | static float SizeOfOverlappingRectOf(Rect rect1, Rect rect2) 105 | { 106 | var result = RectIntersect (rect1, rect2); 107 | return result.width * result.height; 108 | } 109 | 110 | static IEnumerable InterestingDataSets() 111 | { 112 | yield return new TestCaseData (Enumerable.Range (100, 10).Select (i => (float)i).ToArray ()).SetName ("1000 floats counting up"); 113 | yield return new TestCaseData (Enumerable.Repeat (10, 100).Select (i => (float)i).ToArray ()).SetName ("100 identical floats"); 114 | } 115 | } 116 | } 117 | 118 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/Treemap/Tests/TreemapTests.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2c601d2f0652d464eb4ac5109f071975 3 | timeCreated: 1458809711 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/Treemap/Utility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using UnityEngine; 6 | 7 | namespace Treemap 8 | { 9 | public class Utility 10 | { 11 | public static Rect[] GetTreemapRects(float[] values, Rect targetRect) 12 | { 13 | if (values.Length == 0) 14 | throw new ArgumentException ("You need to at least pass in one valid value", "values"); 15 | 16 | Rect[] result = new Rect[values.Length]; 17 | 18 | float totalInputArea = 0f; 19 | for (int i = 0; i < values.Length; i++) 20 | totalInputArea += values[i]; 21 | 22 | float totalOutputArea = targetRect.width * targetRect.height; 23 | bool vertical = targetRect.width > targetRect.height; 24 | 25 | var unfinishedRects = new List(); 26 | 27 | for (int index = 0; index < values.Length; index++) 28 | { 29 | bool lastItem = index == values.Length - 1; 30 | 31 | float currentInputValue = values[index]; 32 | 33 | if (currentInputValue < 0f) 34 | throw new ArgumentException ("only positive float values are supported. found: " + currentInputValue); 35 | 36 | float currentOutputArea = currentInputValue * totalOutputArea / totalInputArea; 37 | unfinishedRects = AddRect(unfinishedRects, currentOutputArea, targetRect, vertical); 38 | float currentAspect = GetAverageAspect(unfinishedRects); 39 | 40 | float nextInputValue = lastItem ? 0f : values[index + 1]; 41 | float nextOutputArea = nextInputValue * totalOutputArea / totalInputArea; 42 | float nextAspect = GetNextAspect(unfinishedRects, nextOutputArea, targetRect, vertical); 43 | 44 | if (Mathf.Abs(1f - currentAspect) < Mathf.Abs(1f - nextAspect) || lastItem) 45 | { 46 | int resultIndex = index - unfinishedRects.Count + 1; 47 | for (int rectIndex = 0; rectIndex < unfinishedRects.Count; rectIndex++) 48 | { 49 | result[resultIndex++] = unfinishedRects[rectIndex]; 50 | } 51 | 52 | targetRect = GetNewTarget(unfinishedRects, targetRect, vertical); 53 | vertical = !vertical; 54 | unfinishedRects.Clear(); 55 | } 56 | } 57 | 58 | return result; 59 | } 60 | 61 | private static List AddRect(List existing, float area, Rect space, bool vertical) 62 | { 63 | List result = new List(); 64 | if (vertical) 65 | { 66 | if (existing.Count == 0) 67 | { 68 | result.Add(new Rect(space.xMin, space.yMin, area / space.height, space.height)); 69 | } 70 | else 71 | { 72 | float totalSize = GetArea(existing) + area; 73 | float width = totalSize / space.height; 74 | float yPosition = space.yMin; 75 | foreach (Rect old in existing) 76 | { 77 | float itemArea = GetArea(old); 78 | result.Add(new Rect(old.xMin, yPosition, width, itemArea / width)); 79 | yPosition += itemArea / width; 80 | } 81 | result.Add(new Rect(space.xMin, yPosition, width, area / width)); 82 | } 83 | } 84 | else 85 | { 86 | if (existing.Count == 0) 87 | { 88 | result.Add(new Rect(space.xMin, space.yMin, space.width, area / space.width)); 89 | } 90 | else 91 | { 92 | float totalSize = GetArea(existing) + area; 93 | float height = totalSize / space.width; 94 | float xPosition = space.xMin; 95 | foreach (Rect old in existing) 96 | { 97 | float itemArea = GetArea(old); 98 | result.Add(new Rect(xPosition, old.yMin, itemArea / height, height)); 99 | xPosition += itemArea / height; 100 | } 101 | result.Add(new Rect(xPosition, space.yMin, area / height, height)); 102 | } 103 | } 104 | return result; 105 | } 106 | 107 | private static Rect GetNewTarget(List unfinished, Rect oldTarget, bool vertical) 108 | { 109 | if (vertical) 110 | { 111 | return new Rect(oldTarget.xMin + unfinished[0].width, oldTarget.yMin, oldTarget.width - unfinished[0].width, oldTarget.height); 112 | } 113 | else 114 | { 115 | return new Rect(oldTarget.xMin, oldTarget.yMin + unfinished[0].height, oldTarget.width, oldTarget.height - unfinished[0].height); 116 | } 117 | } 118 | 119 | private static float GetNextAspect(List existing, float area, Rect space, bool vertical) 120 | { 121 | List newExisting = AddRect(existing, area, space, vertical); 122 | return newExisting[newExisting.Count - 1].height / newExisting[newExisting.Count - 1].width; 123 | } 124 | 125 | private static float GetAverageAspect(List rects) 126 | { 127 | float aspect = 0f; 128 | foreach (Rect r in rects) 129 | { 130 | aspect += r.height / r.width; 131 | } 132 | return aspect / rects.Count; 133 | } 134 | 135 | private static float GetArea(Rect rect) 136 | { 137 | return rect.width * rect.height; 138 | } 139 | 140 | private static float GetArea(List rects) 141 | { 142 | return rects.Sum(x => GetArea(x)); 143 | } 144 | 145 | public static Color GetColorForName(string name) 146 | { 147 | int r = 0, g = 0, b = 0; 148 | 149 | for (int i = 0; i < name.Length; i++) 150 | { 151 | if (i % 3 == 0) 152 | { 153 | r += (int)name[i]; 154 | } 155 | else if (i % 3 == 1) 156 | { 157 | g += (int)name[i]; 158 | } 159 | else 160 | { 161 | b += (int)name[i]; 162 | } 163 | } 164 | 165 | r %= 128; 166 | g %= 128; 167 | b %= 128; 168 | 169 | return new Color32((byte)(r + 96), (byte)(g + 96), (byte)(b + 96), 255); 170 | } 171 | 172 | public static bool IsInside(Rect lhs, Rect rhs) 173 | { 174 | return lhs.xMax > rhs.xMin && lhs.xMin < rhs.xMax && lhs.yMax > rhs.yMin && lhs.yMin < rhs.yMax; 175 | } 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/Treemap/Utility.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e217672946467af49a6588617364cee2 3 | timeCreated: 1439890712 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TypeTools.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEditor.MemoryProfiler; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | 6 | namespace MemoryProfilerWindow 7 | { 8 | static class TypeTools 9 | { 10 | public enum FieldFindOptions 11 | { 12 | OnlyInstance, 13 | OnlyStatic 14 | } 15 | 16 | static public IEnumerable AllFieldsOf (TypeDescription typeDescription, TypeDescription[] typeDescriptions, FieldFindOptions findOptions) 17 | { 18 | if (typeDescription.isArray) 19 | yield break; 20 | 21 | if (findOptions != FieldFindOptions.OnlyStatic && typeDescription.baseOrElementTypeIndex != -1 && !typeDescription.isValueType) 22 | { 23 | var baseTypeDescription = typeDescriptions [typeDescription.baseOrElementTypeIndex]; 24 | foreach(var field in AllFieldsOf(baseTypeDescription, typeDescriptions, findOptions)) 25 | yield return field; 26 | } 27 | 28 | foreach (var field in typeDescription.fields) 29 | { 30 | if (!FieldMatchesOptions(field, findOptions)) 31 | continue; 32 | 33 | if (field.typeIndex == typeDescription.typeIndex && typeDescription.isValueType) 34 | { 35 | // this happens in primitive types like System.Single, which is a weird type that has a field of its own type. 36 | continue; 37 | } 38 | 39 | if (field.offset == -1) 40 | { 41 | // this is how we encode TLS fields. We don't support TLS fields yet. 42 | continue; 43 | } 44 | 45 | yield return field; 46 | } 47 | } 48 | 49 | static bool FieldMatchesOptions(FieldDescription field, FieldFindOptions options) 50 | { 51 | if (field.isStatic && options == FieldFindOptions.OnlyStatic) 52 | return true; 53 | if (!field.isStatic && options == FieldFindOptions.OnlyInstance) 54 | return true; 55 | 56 | return false; 57 | 58 | } 59 | } 60 | } 61 | 62 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/TypeTools.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 11edf27c974c04e7696cba79b5366467 3 | timeCreated: 1445458621 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor/MemoryProfiler/ZoomArea.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 846123fbd1b854036887619ac359740c 3 | timeCreated: 1443368932 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Resources.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 21ab526b31d640f4193ddb3947e83897 3 | folderAsset: yes 4 | timeCreated: 1489188986 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Resources/MemoryProfiler_Resources.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d1450949209754e4db45fa3c345aff4d 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Resources/MemoryProfiler_Resources/MemoryProfiler_Background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertoardila/support-unity-memoryprofiler/12e57074757ec7fa09983e6a1752e02acc45ace4/Assets/Resources/MemoryProfiler_Resources/MemoryProfiler_Background.png -------------------------------------------------------------------------------- /Assets/Resources/MemoryProfiler_Resources/MemoryProfiler_Background.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1cb37b74067b34141b335adbcb588c48 3 | timeCreated: 1489189003 4 | licenseType: Pro 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 4 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | sRGBTexture: 1 12 | linearTexture: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 6 25 | cubemapConvolution: 0 26 | seamlessCubemap: 0 27 | textureFormat: 1 28 | maxTextureSize: 2048 29 | textureSettings: 30 | filterMode: -1 31 | aniso: -1 32 | mipBias: -1 33 | wrapMode: -1 34 | nPOTScale: 1 35 | lightmap: 0 36 | compressionQuality: 50 37 | spriteMode: 0 38 | spriteExtrude: 1 39 | spriteMeshType: 1 40 | alignment: 0 41 | spritePivot: {x: 0.5, y: 0.5} 42 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 43 | spritePixelsToUnits: 100 44 | alphaUsage: 1 45 | alphaIsTransparency: 0 46 | spriteTessellationDetail: -1 47 | textureType: 0 48 | textureShape: 1 49 | maxTextureSizeSet: 0 50 | compressionQualitySet: 0 51 | textureFormatSet: 0 52 | platformSettings: 53 | - buildTarget: DefaultTexturePlatform 54 | maxTextureSize: 2048 55 | textureFormat: -1 56 | textureCompression: 1 57 | compressionQuality: 50 58 | crunchedCompression: 0 59 | allowsAlphaSplitting: 0 60 | overridden: 0 61 | spriteSheet: 62 | serializedVersion: 2 63 | sprites: [] 64 | outline: [] 65 | spritePackingTag: 66 | userData: 67 | assetBundleName: 68 | assetBundleVariant: 69 | -------------------------------------------------------------------------------- /Documentation/Images/HeapView.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertoardila/support-unity-memoryprofiler/12e57074757ec7fa09983e6a1752e02acc45ace4/Documentation/Images/HeapView.jpg -------------------------------------------------------------------------------- /Documentation/Images/PlainData.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertoardila/support-unity-memoryprofiler/12e57074757ec7fa09983e6a1752e02acc45ace4/Documentation/Images/PlainData.jpg -------------------------------------------------------------------------------- /Documentation/Images/TreeView.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertoardila/support-unity-memoryprofiler/12e57074757ec7fa09983e6a1752e02acc45ace4/Documentation/Images/TreeView.jpg -------------------------------------------------------------------------------- /Documentation/Images/memoryProfiler.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertoardila/support-unity-memoryprofiler/12e57074757ec7fa09983e6a1752e02acc45ace4/Documentation/Images/memoryProfiler.jpg -------------------------------------------------------------------------------- /Documentation/Images/memoryProfiler1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertoardila/support-unity-memoryprofiler/12e57074757ec7fa09983e6a1752e02acc45ace4/Documentation/Images/memoryProfiler1.jpg -------------------------------------------------------------------------------- /Documentation/Images/memoryProfiler2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertoardila/support-unity-memoryprofiler/12e57074757ec7fa09983e6a1752e02acc45ace4/Documentation/Images/memoryProfiler2.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Unity Support Colombia: Memory Profiler Extension 2 | Extension for the existing Unity memory profiler project, this is a WIP project made by the Unity Support Team in Colombia, which uses as a base the Memory Profiler project found in https://bitbucket.org/Unity-Technologies/memoryprofiler and uses the new memory profiler API introduced in Unity5.3a4, adding filters and search options with a node viewer for the objects and their references. 3 | 4 | In order to use it, copy the files in your project, then you will see a new Editor menu called: Support Memory Tools from which you can take,load, save and analyze memory snapshots 5 | 6 | * Requires Unity 5.6 or newer in order to use the filters and table views 7 | * For checking the Heap Memory Information and also for export objects list data to external .csv files (for example the list of all managed or native Objects) you could use any version of Unity that supports the API: (e.g 5.3,5.4,5.5,5.6,2017) 8 | * Requires a IL2CPP build 9 | * It uses the same snapshots taken with the Memory Profiler project from bitbucket (You can use as an example memory snapshot which is included in the repository) 10 | * It's recommended to read snapshots taken from the same Unity version (for example analyse 5.6 snapshots using 5.6 editor,etc) 11 | * In the Node View you can zoom in / zoom out with the mouse wheel, use the mouse middle button to pan, and the left button to move each nodes, use the mouse right button to clear the graph 12 | * You only can expand Nodes from Native Objects 13 | * You can search though a existing snapshot by using the following search options in the Tree/Node View Panel (You can also combine them to create complex filters): 14 | 15 | i: string filter by InstanceID 16 | 17 | n: string filter by resource name 18 | 19 | t: string filter by type (managed, native, static, etc). 20 | 21 | s: string filter by size (for example s: 10.7 will wind all the 10.7MB elements) 22 | 23 | s:< string filter by less or equal size 24 | 25 | s:> string filter by greater or equal size 26 | 27 | c: string filter by class name 28 | 29 | 30 | ![Alt text](/Documentation/Images/TreeView.jpg?raw=true "Memory Profiler Tree/Node Window") 31 | ![Alt text](/Documentation/Images/HeapView.jpg?raw=true "Memory Profiler Heap Window") 32 | ![Alt text](/Documentation/Images/PlainData.jpg?raw=true "Memory Profiler Plain Data Window") 33 | 34 | --------------------------------------------------------------------------------