├── .gitignore ├── Assets ├── Examples.meta ├── Examples │ ├── CollectionsExamples.cs │ ├── CollectionsExamples.cs.meta │ ├── ExampleScene.unity │ └── ExampleScene.unity.meta ├── GameObject.prefab ├── GameObject.prefab.meta ├── Serializable Collections Settings.asset ├── Serializable Collections Settings.asset.meta ├── Tests.meta └── Tests │ ├── DictionaryTests.cs │ ├── DictionaryTests.cs.meta │ ├── HashSetTests.cs │ ├── HashSetTests.cs.meta │ ├── LinkedListTests.cs │ ├── LinkedListTests.cs.meta │ ├── ListTests.cs │ ├── ListTests.cs.meta │ ├── QueueTests.cs │ ├── QueueTests.cs.meta │ ├── SortedDictionaryTests.cs │ ├── SortedDictionaryTests.cs.meta │ ├── SortedListTests.cs │ ├── SortedListTests.cs.meta │ ├── SortedSetTests.cs │ ├── SortedSetTests.cs.meta │ ├── StackTests.cs │ ├── StackTests.cs.meta │ ├── Tests Assembly.asmdef │ └── Tests Assembly.asmdef.meta ├── LICENSE.MD ├── Packages ├── SerializableCollections │ ├── Scripts.meta │ ├── Scripts │ │ ├── Dictionary.cs │ │ ├── Dictionary.cs.meta │ │ ├── GUI.meta │ │ ├── GUI │ │ │ ├── CollectionDisplay.cs │ │ │ ├── CollectionDisplay.cs.meta │ │ │ ├── CollectionDrawer.cs │ │ │ ├── CollectionDrawer.cs.meta │ │ │ ├── CustomCollectionAdd.cs │ │ │ ├── CustomCollectionAdd.cs.meta │ │ │ ├── DictionaryDisplay.cs │ │ │ ├── DictionaryDisplay.cs.meta │ │ │ ├── DictionaryDrawer.cs │ │ │ ├── DictionaryDrawer.cs.meta │ │ │ ├── DisplayState.cs │ │ │ ├── DisplayState.cs.meta │ │ │ ├── DisplayType.cs │ │ │ ├── DisplayType.cs.meta │ │ │ ├── DrawerState.cs │ │ │ ├── DrawerState.cs.meta │ │ │ ├── HashSetDrawer.cs │ │ │ ├── HashSetDrawer.cs.meta │ │ │ ├── LinkedListDrawer.cs │ │ │ ├── LinkedListDrawer.cs.meta │ │ │ ├── ListDrawer.cs │ │ │ ├── ListDrawer.cs.meta │ │ │ ├── ReorderableCollection.cs │ │ │ ├── ReorderableCollection.cs.meta │ │ │ ├── SerializationReflection.cs │ │ │ ├── SerializationReflection.cs.meta │ │ │ ├── UsePropertyDrawer.cs │ │ │ └── UsePropertyDrawer.cs.meta │ │ ├── HashSet.cs │ │ ├── HashSet.cs.meta │ │ ├── LinkedList.cs │ │ ├── LinkedList.cs.meta │ │ ├── List.cs │ │ ├── List.cs.meta │ │ ├── PackageSettings.cs │ │ ├── PackageSettings.cs.meta │ │ ├── Queue.cs │ │ ├── Queue.cs.meta │ │ ├── SerializableCollection.cs │ │ ├── SerializableCollection.cs.meta │ │ ├── SortedCollection.cs │ │ ├── SortedCollection.cs.meta │ │ ├── SortedDictionary.cs │ │ ├── SortedDictionary.cs.meta │ │ ├── SortedList.cs │ │ ├── SortedList.cs.meta │ │ ├── SortedSet.cs │ │ ├── SortedSet.cs.meta │ │ ├── Stack.cs │ │ └── Stack.cs.meta │ ├── Serializable Collections Assembly.asmdef │ ├── Serializable Collections Assembly.asmdef.meta │ ├── package.json │ └── package.json.meta └── manifest.json ├── ProjectSettings ├── AudioManager.asset ├── ClusterInputManager.asset ├── DynamicsManager.asset ├── EditorBuildSettings.asset ├── EditorSettings.asset ├── GraphicsSettings.asset ├── InputManager.asset ├── NavMeshAreas.asset ├── NetworkManager.asset ├── Physics2DSettings.asset ├── PresetManager.asset ├── ProjectSettings.asset ├── ProjectVersion.txt ├── QualitySettings.asset ├── TagManager.asset ├── TimeManager.asset ├── UnityConnectSettings.asset ├── VFXManager.asset └── XRSettings.asset ├── README.MD └── UserSettings └── EditorUserSettings.asset /.gitignore: -------------------------------------------------------------------------------- 1 | Library/ 2 | .vs/ 3 | Temp/ 4 | Build/ 5 | obj/ 6 | Logs/ 7 | Tests.csproj 8 | SerializableCollections.sln 9 | SerializableCollections.csproj 10 | Runtime.csproj 11 | GUIAssembly.csproj 12 | Assembly-CSharp.csproj 13 | -------------------------------------------------------------------------------- /Assets/Examples.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: be720e6db35627d45954564c43a270f8 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Examples/CollectionsExamples.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace SerializableCollections.Examples 5 | { 6 | public class CollectionsExamples : MonoBehaviour 7 | { 8 | [Serializable] 9 | public class StringIntDictionary : Dictionary { } 10 | [SerializeField] 11 | private StringIntDictionary dictionary = new StringIntDictionary(); 12 | 13 | [Serializable] 14 | public class IntSet : HashSet { } 15 | [SerializeField] 16 | private IntSet hashSet = new IntSet(); 17 | 18 | [Serializable] 19 | public class IntList : List { } 20 | [SerializeField] 21 | private IntList list = new IntList(); 22 | 23 | [Serializable] 24 | public class StringLinkedList : LinkedList { } 25 | [SerializeField] 26 | private StringLinkedList linkedList = new StringLinkedList(); 27 | 28 | [Serializable] 29 | public class SortedStringListList : List {} 30 | [Serializable] 31 | public class SortedListSet : HashSet { } 32 | [SerializeField] 33 | private SortedListSet nestedCollections = new SortedListSet(); 34 | 35 | [Serializable] 36 | public class StringQueue : Queue { } 37 | [SerializeField] 38 | private StringQueue queue = new StringQueue(); 39 | 40 | [Serializable] 41 | public class IntMonoSortedDictionary : SortedDictionary { } 42 | [SerializeField] 43 | private IntMonoSortedDictionary sortedDictionary = new IntMonoSortedDictionary(); 44 | 45 | [Serializable] 46 | public class SortedStringList : SortedList { } 47 | [SerializeField] 48 | private SortedStringList sortedList = new SortedStringList(); 49 | 50 | [Serializable] 51 | public class StringSortedSet : SortedSet { } 52 | [SerializeField] 53 | private StringSortedSet sortedSet = new StringSortedSet(); 54 | 55 | [Serializable] 56 | public class IntStack : Stack { } 57 | [SerializeField] 58 | private IntStack stack = new IntStack(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Assets/Examples/CollectionsExamples.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 847187f44c3236441aa1261b28e60069 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Examples/ExampleScene.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 9 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 3 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &3 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 11 47 | m_GIWorkflowMode: 1 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 0 55 | m_EnableRealtimeLightmaps: 0 56 | m_LightmapEditorSettings: 57 | serializedVersion: 12 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_AtlasSize: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_ExtractAmbientOcclusion: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 2 75 | m_BakeBackend: 0 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 500 79 | m_PVRBounces: 2 80 | m_PVREnvironmentSampleCount: 500 81 | m_PVREnvironmentReferencePointCount: 2048 82 | m_PVRFilteringMode: 2 83 | m_PVRDenoiserTypeDirect: 0 84 | m_PVRDenoiserTypeIndirect: 0 85 | m_PVRDenoiserTypeAO: 0 86 | m_PVRFilterTypeDirect: 0 87 | m_PVRFilterTypeIndirect: 0 88 | m_PVRFilterTypeAO: 0 89 | m_PVREnvironmentMIS: 0 90 | m_PVRCulling: 1 91 | m_PVRFilteringGaussRadiusDirect: 1 92 | m_PVRFilteringGaussRadiusIndirect: 5 93 | m_PVRFilteringGaussRadiusAO: 2 94 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 95 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 96 | m_PVRFilteringAtrousPositionSigmaAO: 1 97 | m_ExportTrainingData: 0 98 | m_TrainingDataDestination: TrainingData 99 | m_LightProbeSampleCountMultiplier: 4 100 | m_LightingDataAsset: {fileID: 0} 101 | m_UseShadowmask: 1 102 | --- !u!196 &4 103 | NavMeshSettings: 104 | serializedVersion: 2 105 | m_ObjectHideFlags: 0 106 | m_BuildSettings: 107 | serializedVersion: 2 108 | agentTypeID: 0 109 | agentRadius: 0.5 110 | agentHeight: 2 111 | agentSlope: 45 112 | agentClimb: 0.4 113 | ledgeDropHeight: 0 114 | maxJumpAcrossDistance: 0 115 | minRegionArea: 2 116 | manualCellSize: 0 117 | cellSize: 0.16666667 118 | manualTileSize: 0 119 | tileSize: 256 120 | accuratePlacement: 0 121 | debug: 122 | m_Flags: 0 123 | m_NavMeshData: {fileID: 0} 124 | --- !u!1 &508247165 125 | GameObject: 126 | m_ObjectHideFlags: 0 127 | m_CorrespondingSourceObject: {fileID: 0} 128 | m_PrefabInstance: {fileID: 0} 129 | m_PrefabAsset: {fileID: 0} 130 | serializedVersion: 6 131 | m_Component: 132 | - component: {fileID: 508247167} 133 | - component: {fileID: 508247166} 134 | m_Layer: 0 135 | m_Name: GameObject 136 | m_TagString: Untagged 137 | m_Icon: {fileID: 0} 138 | m_NavMeshLayer: 0 139 | m_StaticEditorFlags: 0 140 | m_IsActive: 1 141 | --- !u!114 &508247166 142 | MonoBehaviour: 143 | m_ObjectHideFlags: 0 144 | m_CorrespondingSourceObject: {fileID: 0} 145 | m_PrefabInstance: {fileID: 0} 146 | m_PrefabAsset: {fileID: 0} 147 | m_GameObject: {fileID: 508247165} 148 | m_Enabled: 1 149 | m_EditorHideFlags: 0 150 | m_Script: {fileID: 11500000, guid: 847187f44c3236441aa1261b28e60069, type: 3} 151 | m_Name: 152 | m_EditorClassIdentifier: 153 | dictionary: 154 | keys: [] 155 | values: 156 | key: 157 | value: 0 158 | hasLostValue: 0 159 | hashSet: 160 | values: 161 | value: 0 162 | hasLostValue: 0 163 | list: 164 | values: 165 | linkedList: 166 | values: [] 167 | value: 168 | nestedCollections: 169 | values: 170 | - values: 171 | - keys: 172 | values: [] 173 | key: 0 174 | value: 175 | hasLostValue: 0 176 | - values: 177 | - keys: 0100000002000000 178 | values: 179 | - 180 | - 181 | key: 0 182 | value: 183 | hasLostValue: 0 184 | - values: 185 | - keys: 00000000 186 | values: 187 | - 188 | key: 0 189 | value: 190 | hasLostValue: 0 191 | - keys: 00000000 192 | values: 193 | - 194 | key: 1 195 | value: 196 | hasLostValue: 0 197 | value: 198 | values: [] 199 | hasLostValue: 0 200 | queue: 201 | values: [] 202 | value: 203 | sortedDictionary: 204 | keys: 205 | values: [] 206 | key: 0 207 | value: {fileID: 0} 208 | hasLostValue: 0 209 | sortedList: 210 | keys: 211 | values: [] 212 | key: 0 213 | value: 214 | hasLostValue: 0 215 | sortedSet: 216 | values: [] 217 | value: 218 | hasLostValue: 0 219 | stack: 220 | values: 221 | value: 0 222 | --- !u!4 &508247167 223 | Transform: 224 | m_ObjectHideFlags: 0 225 | m_CorrespondingSourceObject: {fileID: 0} 226 | m_PrefabInstance: {fileID: 0} 227 | m_PrefabAsset: {fileID: 0} 228 | m_GameObject: {fileID: 508247165} 229 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 230 | m_LocalPosition: {x: 0, y: 0, z: 0} 231 | m_LocalScale: {x: 1, y: 1, z: 1} 232 | m_Children: [] 233 | m_Father: {fileID: 0} 234 | m_RootOrder: 1 235 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 236 | --- !u!1 &519420028 237 | GameObject: 238 | m_ObjectHideFlags: 0 239 | m_CorrespondingSourceObject: {fileID: 0} 240 | m_PrefabInstance: {fileID: 0} 241 | m_PrefabAsset: {fileID: 0} 242 | serializedVersion: 6 243 | m_Component: 244 | - component: {fileID: 519420032} 245 | - component: {fileID: 519420031} 246 | m_Layer: 0 247 | m_Name: Main Camera 248 | m_TagString: MainCamera 249 | m_Icon: {fileID: 0} 250 | m_NavMeshLayer: 0 251 | m_StaticEditorFlags: 0 252 | m_IsActive: 1 253 | --- !u!20 &519420031 254 | Camera: 255 | m_ObjectHideFlags: 0 256 | m_CorrespondingSourceObject: {fileID: 0} 257 | m_PrefabInstance: {fileID: 0} 258 | m_PrefabAsset: {fileID: 0} 259 | m_GameObject: {fileID: 519420028} 260 | m_Enabled: 1 261 | serializedVersion: 2 262 | m_ClearFlags: 2 263 | m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 1} 264 | m_projectionMatrixMode: 1 265 | m_GateFitMode: 2 266 | m_FOVAxisMode: 0 267 | m_SensorSize: {x: 36, y: 24} 268 | m_LensShift: {x: 0, y: 0} 269 | m_FocalLength: 50 270 | m_NormalizedViewPortRect: 271 | serializedVersion: 2 272 | x: 0 273 | y: 0 274 | width: 1 275 | height: 1 276 | near clip plane: 0.3 277 | far clip plane: 1000 278 | field of view: 60 279 | orthographic: 1 280 | orthographic size: 5 281 | m_Depth: -1 282 | m_CullingMask: 283 | serializedVersion: 2 284 | m_Bits: 0 285 | m_RenderingPath: -1 286 | m_TargetTexture: {fileID: 0} 287 | m_TargetDisplay: 0 288 | m_TargetEye: 0 289 | m_HDR: 1 290 | m_AllowMSAA: 0 291 | m_AllowDynamicResolution: 0 292 | m_ForceIntoRT: 0 293 | m_OcclusionCulling: 0 294 | m_StereoConvergence: 10 295 | m_StereoSeparation: 0.022 296 | --- !u!4 &519420032 297 | Transform: 298 | m_ObjectHideFlags: 0 299 | m_CorrespondingSourceObject: {fileID: 0} 300 | m_PrefabInstance: {fileID: 0} 301 | m_PrefabAsset: {fileID: 0} 302 | m_GameObject: {fileID: 519420028} 303 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 304 | m_LocalPosition: {x: 0, y: 0, z: -10} 305 | m_LocalScale: {x: 1, y: 1, z: 1} 306 | m_Children: [] 307 | m_Father: {fileID: 0} 308 | m_RootOrder: 0 309 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 310 | --- !u!1 &1328767629 311 | GameObject: 312 | m_ObjectHideFlags: 0 313 | m_CorrespondingSourceObject: {fileID: 0} 314 | m_PrefabInstance: {fileID: 0} 315 | m_PrefabAsset: {fileID: 0} 316 | serializedVersion: 6 317 | m_Component: 318 | - component: {fileID: 1328767630} 319 | m_Layer: 0 320 | m_Name: GameObject (2) 321 | m_TagString: Untagged 322 | m_Icon: {fileID: 0} 323 | m_NavMeshLayer: 0 324 | m_StaticEditorFlags: 0 325 | m_IsActive: 1 326 | --- !u!4 &1328767630 327 | Transform: 328 | m_ObjectHideFlags: 0 329 | m_CorrespondingSourceObject: {fileID: 0} 330 | m_PrefabInstance: {fileID: 0} 331 | m_PrefabAsset: {fileID: 0} 332 | m_GameObject: {fileID: 1328767629} 333 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 334 | m_LocalPosition: {x: 0, y: 0, z: 0} 335 | m_LocalScale: {x: 1, y: 1, z: 1} 336 | m_Children: [] 337 | m_Father: {fileID: 0} 338 | m_RootOrder: 3 339 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 340 | --- !u!1 &1837467137 341 | GameObject: 342 | m_ObjectHideFlags: 0 343 | m_CorrespondingSourceObject: {fileID: 0} 344 | m_PrefabInstance: {fileID: 0} 345 | m_PrefabAsset: {fileID: 0} 346 | serializedVersion: 6 347 | m_Component: 348 | - component: {fileID: 1837467138} 349 | m_Layer: 0 350 | m_Name: GameObject (1) 351 | m_TagString: Untagged 352 | m_Icon: {fileID: 0} 353 | m_NavMeshLayer: 0 354 | m_StaticEditorFlags: 0 355 | m_IsActive: 1 356 | --- !u!4 &1837467138 357 | Transform: 358 | m_ObjectHideFlags: 0 359 | m_CorrespondingSourceObject: {fileID: 0} 360 | m_PrefabInstance: {fileID: 0} 361 | m_PrefabAsset: {fileID: 0} 362 | m_GameObject: {fileID: 1837467137} 363 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 364 | m_LocalPosition: {x: 0, y: 0, z: 0} 365 | m_LocalScale: {x: 1, y: 1, z: 1} 366 | m_Children: [] 367 | m_Father: {fileID: 0} 368 | m_RootOrder: 2 369 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 370 | -------------------------------------------------------------------------------- /Assets/Examples/ExampleScene.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2cda990e2423bbf4892e6590ba056729 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/GameObject.prefab: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1 &8747043569515166769 4 | GameObject: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | serializedVersion: 6 10 | m_Component: 11 | - component: {fileID: 8747043569515166771} 12 | - component: {fileID: 8747043569515166770} 13 | m_Layer: 0 14 | m_Name: GameObject 15 | m_TagString: Untagged 16 | m_Icon: {fileID: 0} 17 | m_NavMeshLayer: 0 18 | m_StaticEditorFlags: 0 19 | m_IsActive: 1 20 | --- !u!4 &8747043569515166771 21 | Transform: 22 | m_ObjectHideFlags: 0 23 | m_CorrespondingSourceObject: {fileID: 0} 24 | m_PrefabInstance: {fileID: 0} 25 | m_PrefabAsset: {fileID: 0} 26 | m_GameObject: {fileID: 8747043569515166769} 27 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 28 | m_LocalPosition: {x: 0, y: 0, z: 0} 29 | m_LocalScale: {x: 1, y: 1, z: 1} 30 | m_Children: [] 31 | m_Father: {fileID: 0} 32 | m_RootOrder: 0 33 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 34 | --- !u!114 &8747043569515166770 35 | MonoBehaviour: 36 | m_ObjectHideFlags: 0 37 | m_CorrespondingSourceObject: {fileID: 0} 38 | m_PrefabInstance: {fileID: 0} 39 | m_PrefabAsset: {fileID: 0} 40 | m_GameObject: {fileID: 8747043569515166769} 41 | m_Enabled: 1 42 | m_EditorHideFlags: 0 43 | m_Script: {fileID: 11500000, guid: 847187f44c3236441aa1261b28e60069, type: 3} 44 | m_Name: 45 | m_EditorClassIdentifier: 46 | dictionaryTest: 47 | keys: [] 48 | values: 49 | key: 50 | value: 0 51 | hasLostValue: 0 52 | sortedDictionaryTest: 53 | keys: 54 | values: [] 55 | key: 0 56 | value: {fileID: 0} 57 | hasLostValue: 0 58 | hashSetTest: 59 | values: 60 | value: 0 61 | hasLostValue: 0 62 | sortedSetTest: 63 | values: [] 64 | value: 65 | hasLostValue: 0 66 | listTest: 67 | values: 68 | queueTest: 69 | values: [] 70 | value: 71 | sortedStringList: 72 | keys: 73 | values: [] 74 | key: 0 75 | value: 76 | hasLostValue: 0 77 | sortedListSet: 78 | values: 79 | - keys: 00000000 80 | values: 81 | - 82 | key: 0 83 | value: 84 | hasLostValue: 0 85 | value: 86 | keys: 87 | values: [] 88 | key: 0 89 | value: 90 | hasLostValue: 0 91 | hasLostValue: 0 92 | -------------------------------------------------------------------------------- /Assets/GameObject.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 97443d6880a8dc8448f2f218a10206a4 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/Serializable Collections Settings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!114 &11400000 4 | MonoBehaviour: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_GameObject: {fileID: 0} 10 | m_Enabled: 1 11 | m_EditorHideFlags: 0 12 | m_Script: {fileID: 11500000, guid: a46a3d68b2b260b45b177b010eba5aa9, type: 3} 13 | m_Name: Serializable Collections Settings 14 | m_EditorClassIdentifier: 15 | defaultListSettings: 16 | color: {r: 1, g: 1, b: 1, a: 1} 17 | usePages: 1 18 | itemsPerPage: 10 19 | keyLabel: 20 | valueLabel: 21 | listViewSettings: 22 | keys: 23 | - SerializableCollections.RuntimeTests.CollectionsTests.dictionaryTest.values 24 | - SerializableCollections.RuntimeTests.CollectionsTests.listTest.values 25 | - SerializableCollections.PackageSettings.listViewSettings.values 26 | - SerializableCollections.RuntimeTests.CollectionsTests.hashSetTest.values 27 | - SerializableCollections.RuntimeTests.CollectionsTests.nestedCollections.values.Array.data[2].values.Array.data[1].values 28 | - SerializableCollections.RuntimeTests.CollectionsTests.nestedCollections.values.Array.data[2].values 29 | - SerializableCollections.RuntimeTests.CollectionsTests.nestedCollections.values.Array.data[1].values 30 | - SerializableCollections.RuntimeTests.CollectionsTests.nestedCollections.values 31 | - SerializableCollections.RuntimeTests.CollectionsTests.sortedDictionaryTest.values 32 | - SerializableCollections.RuntimeTests.CollectionsTests.nestedCollections.values.Array.data[2].values.Array.data[0].values 33 | - SerializableCollections.RuntimeTests.CollectionsTests.nestedCollections.values.Array.data[1].values.Array.data[0].values 34 | - SerializableCollections.Examples.CollectionsExamples.nestedCollections.values.Array.data[1].values 35 | values: 36 | - color: {r: 0.7862104, g: 1, b: 0.7783019, a: 1} 37 | usePages: 1 38 | itemsPerPage: 5 39 | keyLabel: 40 | valueLabel: 41 | - color: {r: 1, g: 0.7783019, b: 0.7783019, a: 1} 42 | usePages: 1 43 | itemsPerPage: 10 44 | keyLabel: 45 | valueLabel: 46 | - color: {r: 0.8254717, g: 0.98495835, b: 1, a: 1} 47 | usePages: 1 48 | itemsPerPage: 10 49 | keyLabel: 50 | valueLabel: 51 | - color: {r: 1, g: 1, b: 1, a: 1} 52 | usePages: 1 53 | itemsPerPage: 10 54 | keyLabel: 55 | valueLabel: 56 | - color: {r: 1, g: 0.6933962, b: 0.6933962, a: 1} 57 | usePages: 1 58 | itemsPerPage: 10 59 | keyLabel: 60 | valueLabel: 61 | - color: {r: 0.8349056, g: 0.85937256, b: 1, a: 1} 62 | usePages: 1 63 | itemsPerPage: 10 64 | keyLabel: 65 | valueLabel: 66 | - color: {r: 1, g: 0.9198113, b: 0.9198113, a: 1} 67 | usePages: 1 68 | itemsPerPage: 10 69 | keyLabel: 70 | valueLabel: 71 | - color: {r: 0.9876306, g: 1, b: 0.8537736, a: 1} 72 | usePages: 1 73 | itemsPerPage: 10 74 | keyLabel: 75 | valueLabel: 76 | - color: {r: 1, g: 1, b: 1, a: 1} 77 | usePages: 1 78 | itemsPerPage: 5 79 | keyLabel: 80 | valueLabel: 81 | - color: {r: 1, g: 0.7877358, b: 0.7877358, a: 1} 82 | usePages: 1 83 | itemsPerPage: 10 84 | keyLabel: 85 | valueLabel: 86 | - color: {r: 0.79607844, g: 0.89389825, b: 1, a: 1} 87 | usePages: 1 88 | itemsPerPage: 1 89 | keyLabel: 90 | valueLabel: 91 | - color: {r: 1, g: 0.6462264, b: 0.6462264, a: 1} 92 | usePages: 1 93 | itemsPerPage: 10 94 | keyLabel: 95 | valueLabel: 96 | key: 97 | value: 98 | color: {r: 1, g: 1, b: 1, a: 1} 99 | usePages: 0 100 | itemsPerPage: 10 101 | keyLabel: 102 | valueLabel: 103 | hasLostValue: 0 104 | -------------------------------------------------------------------------------- /Assets/Serializable Collections Settings.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cfedbcddab29f6743946e8937531aedb 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 11400000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Tests.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 62d9bc3c555117149969ffd77676cdc8 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Tests/DictionaryTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NUnit.Framework; 3 | 4 | namespace SerializableCollections.Tests 5 | { 6 | public class DictionaryTests 7 | { 8 | [Serializable] 9 | public class StringIntDictionary : Dictionary { } 10 | 11 | private StringIntDictionary CreateTestDictionary() 12 | { 13 | var dictionary = new StringIntDictionary(); 14 | for (var i = 0; i < 25; i++) 15 | { 16 | string key = new string((char)('a' + i), 1); 17 | dictionary.Add(key, i); 18 | } 19 | return dictionary; 20 | } 21 | 22 | [Test] 23 | public void Add() 24 | { 25 | var dictionary = new StringIntDictionary(); 26 | dictionary.Add(new System.Collections.Generic.KeyValuePair("a", 1)); 27 | dictionary.Add("b", 2); 28 | Assert.AreEqual(dictionary["a"], 1); 29 | Assert.AreEqual(dictionary["b"], 2); 30 | } 31 | 32 | [Test] 33 | public void Clear() 34 | { 35 | var dictionary = CreateTestDictionary(); 36 | dictionary.Clear(); 37 | Assert.Zero(dictionary.Count); 38 | } 39 | 40 | [Test] 41 | public void ContainsKey() 42 | { 43 | var dictionary = CreateTestDictionary(); 44 | Assert.IsTrue(dictionary.ContainsKey("a")); 45 | } 46 | 47 | [Test] 48 | public void ContainsValue() 49 | { 50 | var dictionary = CreateTestDictionary(); 51 | Assert.IsTrue(dictionary.ContainsValue(1)); 52 | } 53 | 54 | [Test] 55 | public void Count() 56 | { 57 | var dictionary = CreateTestDictionary(); 58 | Assert.AreEqual(dictionary.Count, 25); 59 | } 60 | 61 | [Test] 62 | public void Contains() 63 | { 64 | var dictionary = CreateTestDictionary(); 65 | System.Collections.Generic.KeyValuePair value = new System.Collections.Generic.KeyValuePair("asdf", 5); 66 | dictionary.Add(value); 67 | Assert.Contains(value, dictionary); 68 | } 69 | 70 | [Test] 71 | public void Remove() 72 | { 73 | var dictionary = CreateTestDictionary(); 74 | dictionary.Remove("a"); 75 | Assert.IsFalse(dictionary.ContainsKey("a")); 76 | } 77 | 78 | [Test] 79 | public void Enumeration_Works_Correctly() 80 | { 81 | var dictionary = CreateTestDictionary(); 82 | int count = 0; 83 | foreach (var kvp in dictionary) 84 | { 85 | count++; 86 | } 87 | Assert.True(count == 25); 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /Assets/Tests/DictionaryTests.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f1d4a667953161b488ed3ec9874387c1 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Tests/HashSetTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NUnit.Framework; 3 | 4 | namespace SerializableCollections.Tests 5 | { 6 | public class HashSetTests 7 | { 8 | [Serializable] 9 | public class IntSet : HashSet { } 10 | 11 | private IntSet CreateTestHashSet() 12 | { 13 | var hashSet = new IntSet(); 14 | for (var i = 0; i < 25; i++) 15 | { 16 | hashSet.Add(i); 17 | } 18 | return hashSet; 19 | } 20 | 21 | [Test] 22 | public void Add() 23 | { 24 | IntSet hashSet = CreateTestHashSet(); 25 | Assert.Contains(1, hashSet); 26 | } 27 | 28 | [Test] 29 | public void Clear() 30 | { 31 | IntSet hashSet = CreateTestHashSet(); 32 | hashSet.Clear(); 33 | Assert.Zero(hashSet.Count); 34 | } 35 | 36 | [Test] 37 | public void Count() 38 | { 39 | IntSet hashSet = CreateTestHashSet(); 40 | Assert.AreEqual(hashSet.Count, 25); 41 | } 42 | 43 | [Test] 44 | public void Contains() 45 | { 46 | IntSet hashSet = CreateTestHashSet(); 47 | Assert.IsTrue(hashSet.Contains(1)); 48 | } 49 | 50 | [Test] 51 | public void Remove() 52 | { 53 | IntSet hashSet = CreateTestHashSet(); 54 | hashSet.Remove(1); 55 | Assert.IsFalse(hashSet.Contains(1)); 56 | } 57 | 58 | [Test] 59 | public void Enumeration_Works_Correctly() 60 | { 61 | IntSet hashSet = CreateTestHashSet(); 62 | int count = 0; 63 | foreach (var item in hashSet) 64 | count++; 65 | 66 | Assert.True(count == 25); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Assets/Tests/HashSetTests.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 55b555ad50dac46409578939cb203b92 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Tests/LinkedListTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NUnit.Framework; 3 | 4 | namespace SerializableCollections.Tests 5 | { 6 | public class LinkedListTests 7 | { 8 | [Serializable] 9 | public class StringLinkedList : LinkedList { } 10 | 11 | private StringLinkedList CreateTestLinkedList() 12 | { 13 | var linkedList = new StringLinkedList(); 14 | for (var i = 0; i < 25; i++) 15 | { 16 | linkedList.Add(new string((char)('a' + i), 1)); 17 | } 18 | return linkedList; 19 | } 20 | 21 | [Test] 22 | public void Add() 23 | { 24 | var linkedList = CreateTestLinkedList(); 25 | Assert.Contains("a", linkedList); 26 | } 27 | 28 | [Test] 29 | public void Clear() 30 | { 31 | var linkedList = CreateTestLinkedList(); 32 | linkedList.Clear(); 33 | Assert.Zero(linkedList.Count); 34 | } 35 | 36 | [Test] 37 | public void Count() 38 | { 39 | var linkedList = CreateTestLinkedList(); 40 | Assert.AreEqual(linkedList.Count, 25); 41 | } 42 | 43 | [Test] 44 | public void Contains() 45 | { 46 | var linkedList = CreateTestLinkedList(); 47 | Assert.IsTrue(linkedList.Contains("a")); 48 | } 49 | 50 | [Test] 51 | public void Remove() 52 | { 53 | var linkedList = CreateTestLinkedList(); 54 | linkedList.Remove("a"); 55 | Assert.IsFalse(linkedList.Contains("a")); 56 | } 57 | 58 | [Test] 59 | public void Enumeration_Works_Correctly() 60 | { 61 | var linkedList = CreateTestLinkedList(); 62 | int count = 0; 63 | foreach (var item in linkedList) 64 | count++; 65 | 66 | Assert.True(count == 25); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Assets/Tests/LinkedListTests.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8dbd5445238f197458361ea06dbb07e2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Tests/ListTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NUnit.Framework; 3 | 4 | namespace SerializableCollections.Tests 5 | { 6 | public class ListTests 7 | { 8 | [Serializable] 9 | public class IntList : List { } 10 | 11 | private IntList CreateTestList() 12 | { 13 | var list = new IntList(); 14 | for (var i = 0; i < 25; i++) 15 | { 16 | list.Add(i); 17 | } 18 | 19 | return list; 20 | } 21 | 22 | [Test] 23 | public void Add() 24 | { 25 | var list = CreateTestList(); 26 | Assert.Contains(1, list); 27 | } 28 | 29 | [Test] 30 | public void Clear() 31 | { 32 | var list = CreateTestList(); 33 | list.Clear(); 34 | Assert.Zero(list.Count); 35 | } 36 | 37 | [Test] 38 | public void Count() 39 | { 40 | var list = CreateTestList(); 41 | Assert.AreEqual(list.Count, 25); 42 | } 43 | 44 | [Test] 45 | public void Contains() 46 | { 47 | var list = CreateTestList(); 48 | Assert.IsTrue(list.Contains(1)); 49 | } 50 | 51 | [Test] 52 | public void Remove() 53 | { 54 | var list = CreateTestList(); 55 | list.Remove(1); 56 | Assert.IsFalse(list.Contains(1)); 57 | } 58 | 59 | [Test] 60 | public void Enumeration_Works_Correctly() 61 | { 62 | var list = CreateTestList(); 63 | int count = 0; 64 | foreach (var item in list) 65 | count++; 66 | 67 | Assert.True(count == 25); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Assets/Tests/ListTests.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c791bcb75f094574281c5a8ce18b7726 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Tests/QueueTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NUnit.Framework; 3 | 4 | namespace SerializableCollections.Tests 5 | { 6 | public class QueueTests 7 | { 8 | [Serializable] 9 | public class StringQueue : Queue { } 10 | 11 | private StringQueue CreateTestQueue() 12 | { 13 | var queue = new StringQueue(); 14 | for (var i = 0; i < 25; i++) 15 | { 16 | queue.Enqueue(new string((char)('a' + i), 1)); 17 | } 18 | 19 | return queue; 20 | } 21 | 22 | [Test] 23 | public void Add() 24 | { 25 | var queue = new StringQueue(); 26 | queue.Enqueue("a"); 27 | Assert.Contains("a", queue); 28 | } 29 | 30 | [Test] 31 | public void Clear() 32 | { 33 | var queue = CreateTestQueue(); 34 | queue.Clear(); 35 | Assert.Zero(queue.Count); 36 | } 37 | 38 | [Test] 39 | public void Count() 40 | { 41 | var queue = CreateTestQueue(); 42 | Assert.AreEqual(queue.Count, 25); 43 | } 44 | 45 | [Test] 46 | public void Contains() 47 | { 48 | var queue = CreateTestQueue(); 49 | Assert.IsTrue(queue.Contains("a")); 50 | } 51 | 52 | [Test] 53 | public void Dequeue() 54 | { 55 | var queue = CreateTestQueue(); 56 | string dequeue = queue.Dequeue(); 57 | Assert.AreEqual("a", dequeue); 58 | } 59 | 60 | [Test] 61 | public void Enumeration_Works_Correctly() 62 | { 63 | var queue = CreateTestQueue(); 64 | int count = 0; 65 | foreach (var item in queue) 66 | count++; 67 | 68 | Assert.IsTrue(count == 25); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Assets/Tests/QueueTests.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 57cc61d00e781c140acbf9385748f2c7 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Tests/SortedDictionaryTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NUnit.Framework; 3 | 4 | namespace SerializableCollections.Tests 5 | { 6 | public class SortedDictionaryTests 7 | { 8 | [Serializable] 9 | private class IntIntSortDic : SortedDictionary { } 10 | 11 | private IntIntSortDic CreateTestDictionary() 12 | { 13 | var dictionary = new IntIntSortDic(); 14 | for (var i = 0; i < 25; i++) 15 | { 16 | dictionary.Add(i, i + 26); 17 | } 18 | return dictionary; 19 | } 20 | 21 | [Test] 22 | public void Add() 23 | { 24 | var dictionary = new IntIntSortDic(); 25 | dictionary.Add(new System.Collections.Generic.KeyValuePair(1, 100)); 26 | dictionary.Add(2, 200); 27 | Assert.AreEqual(dictionary[1], 100); 28 | Assert.AreEqual(dictionary[2], 200); 29 | } 30 | 31 | [Test] 32 | public void Clear() 33 | { 34 | var dictionary = CreateTestDictionary(); 35 | dictionary.Clear(); 36 | Assert.Zero(dictionary.Count); 37 | } 38 | 39 | [Test] 40 | public void ContainsKey() 41 | { 42 | var dictionary = CreateTestDictionary(); 43 | Assert.IsTrue(dictionary.ContainsKey(1)); 44 | } 45 | 46 | [Test] 47 | public void ContainsValue() 48 | { 49 | var dictionary = CreateTestDictionary(); 50 | Assert.IsTrue(dictionary.ContainsValue(27)); 51 | } 52 | 53 | [Test] 54 | public void Count() 55 | { 56 | var dictionary = CreateTestDictionary(); 57 | Assert.AreEqual(dictionary.Count, 25); 58 | } 59 | 60 | [Test] 61 | public void Contains() 62 | { 63 | var dictionary = new IntIntSortDic(); 64 | System.Collections.Generic.KeyValuePair value = new System.Collections.Generic.KeyValuePair(1, 27); 65 | dictionary.Add(value); 66 | Assert.IsTrue(dictionary.Contains(value)); 67 | } 68 | 69 | [Test] 70 | public void Remove() 71 | { 72 | var dictionary = CreateTestDictionary(); 73 | dictionary.Remove(1); 74 | Assert.IsFalse(dictionary.ContainsKey(1)); 75 | } 76 | 77 | [Test] 78 | public void Enumeration_Works_Correctly() 79 | { 80 | var dictionary = CreateTestDictionary(); 81 | int count = 0; 82 | foreach (var kvp in dictionary) 83 | { 84 | count++; 85 | } 86 | Assert.True(count == 25); 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /Assets/Tests/SortedDictionaryTests.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e09278db9a80cd14db1204a7f07bb095 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Tests/SortedListTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using System; 3 | 4 | namespace SerializableCollections.Tests 5 | { 6 | public class SortedListTests 7 | { 8 | [Serializable] 9 | private class IntIntSortList : SortedList { } 10 | 11 | private IntIntSortList CreateTestList() 12 | { 13 | var list = new IntIntSortList(); 14 | for (var i = 0; i < 25; i++) 15 | { 16 | list.Add(i, i + 26); 17 | } 18 | return list; 19 | } 20 | 21 | [Test] 22 | public void Add() 23 | { 24 | var list = new IntIntSortList(); 25 | list.Add(new System.Collections.Generic.KeyValuePair(1, 100)); 26 | list.Add(2, 200); 27 | 28 | Assert.AreEqual(list[0], 100); 29 | Assert.AreEqual(list[1], 200); 30 | } 31 | 32 | [Test] 33 | public void Clear() 34 | { 35 | var list = CreateTestList(); 36 | list.Clear(); 37 | Assert.Zero(list.Count); 38 | } 39 | 40 | [Test] 41 | public void ContainsKey() 42 | { 43 | var list = CreateTestList(); 44 | Assert.IsTrue(list.ContainsKey(1)); 45 | } 46 | 47 | [Test] 48 | public void ContainsValue() 49 | { 50 | var list = CreateTestList(); 51 | Assert.IsTrue(list.ContainsValue(27)); 52 | } 53 | 54 | [Test] 55 | public void Count() 56 | { 57 | var list = CreateTestList(); 58 | Assert.AreEqual(list.Count, 25); 59 | } 60 | 61 | [Test] 62 | public void Contains() 63 | { 64 | var list = new IntIntSortList(); 65 | System.Collections.Generic.KeyValuePair value = new System.Collections.Generic.KeyValuePair(1, 27); 66 | list.Add(value); 67 | Assert.IsTrue(list.Contains(value)); 68 | } 69 | 70 | [Test] 71 | public void Remove() 72 | { 73 | var list = CreateTestList(); 74 | list.Remove(1); 75 | Assert.IsFalse(list.ContainsKey(1)); 76 | } 77 | 78 | [Test] 79 | public void Enumeration_Works_Correctly() 80 | { 81 | var list = CreateTestList(); 82 | int count = 0; 83 | foreach (var kvp in list) 84 | { 85 | count++; 86 | } 87 | Assert.True(count == 25); 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /Assets/Tests/SortedListTests.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 31ddda56de0067a4e81881fab997a86a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Tests/SortedSetTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using System; 3 | 4 | namespace SerializableCollections.Tests 5 | { 6 | public class SortedSetTests 7 | { 8 | [Serializable] 9 | private class StringSortedSet : SortedSet { } 10 | 11 | private StringSortedSet CreateTestSet() 12 | { 13 | var set = new StringSortedSet(); 14 | for (var i = 0; i < 25; i++) 15 | { 16 | set.Add(('a' + i).ToString()); 17 | } 18 | return set; 19 | } 20 | 21 | [Test] 22 | public void Add() 23 | { 24 | var set = new StringSortedSet(); 25 | set.Add("asdf"); 26 | Assert.Contains("asdf", set); 27 | } 28 | 29 | [Test] 30 | public void Clear() 31 | { 32 | var set = CreateTestSet(); 33 | set.Clear(); 34 | Assert.Zero(set.Count); 35 | } 36 | 37 | [Test] 38 | public void Contains() 39 | { 40 | var set = new StringSortedSet { "qwerty" }; 41 | Assert.IsTrue(set.Contains("qwerty")); 42 | } 43 | 44 | [Test] 45 | public void Count() 46 | { 47 | var set = new StringSortedSet { "a", "b", "c", "d", "e" }; 48 | Assert.AreEqual(set.Count, 5); 49 | } 50 | 51 | [Test] 52 | public void Remove() 53 | { 54 | var set = new StringSortedSet { "qwerty" }; 55 | set.Remove("qwerty"); 56 | Assert.IsFalse(set.Contains("qwerty")); 57 | } 58 | 59 | [Test] 60 | public void Enumeration_Works_Correctly() 61 | { 62 | var set = CreateTestSet(); 63 | int count = 0; 64 | foreach (var kvp in set) 65 | { 66 | count++; 67 | } 68 | Assert.True(count == 25); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Assets/Tests/SortedSetTests.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e6151bfd2620aae4f9c0c521cabc764c 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Tests/StackTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using System; 3 | 4 | namespace SerializableCollections.Tests 5 | { 6 | public class StackTests 7 | { 8 | [Serializable] 9 | public class StringStack : Stack { } 10 | 11 | private StringStack CreateTestStack() 12 | { 13 | var stack = new StringStack(); 14 | for (var i = 0; i < 25; i++) 15 | { 16 | stack.Push(new string((char)('a' + i), 1)); 17 | } 18 | 19 | return stack; 20 | } 21 | 22 | [Test] 23 | public void Add() 24 | { 25 | var stack = new StringStack(); 26 | stack.Push("a"); 27 | Assert.Contains("a", stack); 28 | } 29 | 30 | [Test] 31 | public void Clear() 32 | { 33 | var stack = new StringStack(); 34 | stack.Push("a"); 35 | stack.Clear(); 36 | Assert.Zero(stack.Count); 37 | } 38 | 39 | [Test] 40 | public void Contains() 41 | { 42 | var stack = CreateTestStack(); 43 | Assert.IsTrue(stack.Contains("a")); 44 | } 45 | 46 | [Test] 47 | public void Count() 48 | { 49 | var stack = new StringStack(); 50 | stack.Push("a"); 51 | stack.Push("b"); 52 | stack.Push("c"); 53 | stack.Push("d"); 54 | stack.Push("e"); 55 | Assert.AreEqual(stack.Count, 5); 56 | } 57 | 58 | [Test] 59 | public void IsLIFO() 60 | { 61 | var stack = new StringStack(); 62 | stack.Push("a"); 63 | stack.Push("b"); 64 | stack.Push("c"); 65 | string pop = stack.Pop(); 66 | Assert.AreEqual("c", pop); 67 | } 68 | 69 | [Test] 70 | public void Enumeration_Works_Correctly() 71 | { 72 | var stack = CreateTestStack(); 73 | int count = 0; 74 | foreach (var item in stack) 75 | count++; 76 | 77 | Assert.IsTrue(count == 25); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Assets/Tests/StackTests.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f42327f6ed4d3bb488c49fddd3f9f922 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Tests/Tests Assembly.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Tests", 3 | "references": [ 4 | "UnityEngine.TestRunner", 5 | "UnityEditor.TestRunner", 6 | "SerializableCollections" 7 | ], 8 | "includePlatforms": [], 9 | "excludePlatforms": [], 10 | "allowUnsafeCode": false, 11 | "overrideReferences": true, 12 | "precompiledReferences": [ 13 | "nunit.framework.dll" 14 | ], 15 | "autoReferenced": false, 16 | "defineConstraints": [ 17 | "UNITY_INCLUDE_TESTS" 18 | ], 19 | "versionDefines": [], 20 | "noEngineReferences": false 21 | } -------------------------------------------------------------------------------- /Assets/Tests/Tests Assembly.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c2745e4f0a96d5540a9553c3423caa83 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /LICENSE.MD: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Dameon Laird 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0652923fb75a97f4c8dcdabb526097d2 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/Dictionary.cs: -------------------------------------------------------------------------------- 1 | using SerializableCollections.GUI; 2 | using System; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | using UnityEngine; 6 | 7 | namespace SerializableCollections 8 | { 9 | #if UNITY_EDITOR 10 | [UsePropertyDrawer(typeof(DictionaryDrawer))] 11 | #endif 12 | public class Dictionary : SerializableCollection, ISerializationCallbackReceiver, ICollection>, IEnumerable>, IEnumerable, IDictionary, ICollection 13 | { 14 | [SerializeField] 15 | private System.Collections.Generic.List keys = new System.Collections.Generic.List(); 16 | [SerializeField] 17 | private System.Collections.Generic.List values = new System.Collections.Generic.List(); 18 | 19 | protected IDictionary Implementation { get; set; } 20 | 21 | // This key and value is used by the property drawer to add new keys/values to the dicitonary. 22 | [SerializeField] 23 | private KeyType key = default; 24 | protected KeyType Key { get { return key; } set { key = value; } } 25 | [SerializeField] 26 | private ValueType value = default; 27 | protected ValueType Value { get { return value; } set { this.value = value; } } 28 | #pragma warning disable 0414 29 | [SerializeField] 30 | private bool hasLostValue = false; 31 | #pragma warning restore 0414 32 | 33 | public ValueType this[KeyType key] 34 | { 35 | get { return Implementation[key]; } 36 | set { Implementation[key] = value; } 37 | } 38 | 39 | public Dictionary() : base() 40 | { 41 | Implementation = new System.Collections.Generic.Dictionary(); 42 | } 43 | 44 | public Dictionary(IDictionary implementation) 45 | { 46 | Implementation = implementation; 47 | } 48 | 49 | public Dictionary(IEqualityComparer comparer) 50 | { 51 | Implementation = new System.Collections.Generic.Dictionary(comparer); 52 | } 53 | 54 | public Dictionary(int capacity) 55 | { 56 | Implementation = new System.Collections.Generic.Dictionary(capacity); 57 | } 58 | 59 | public Dictionary(int capacity, IEqualityComparer comparer) 60 | { 61 | Implementation = new System.Collections.Generic.Dictionary(capacity, comparer); 62 | } 63 | 64 | private void AddTemp() 65 | { 66 | Add(key, value); 67 | ClearTemp(); 68 | } 69 | 70 | private void ClearTemp() 71 | { 72 | #if UNITY_EDITOR 73 | if (!typeof(KeyType).IsValueType && typeof(KeyType).GetConstructor(Type.EmptyTypes) != null) 74 | key = Activator.CreateInstance(); 75 | else 76 | key = default; 77 | 78 | if (!typeof(ValueType).IsValueType && typeof(ValueType).GetConstructor(Type.EmptyTypes) != null && !(typeof(ValueType).IsSubclassOf(typeof(UnityEngine.Object)))) 79 | value = Activator.CreateInstance(); 80 | else 81 | value = default; 82 | #else 83 | key = default; 84 | value = default; 85 | #endif 86 | } 87 | 88 | public void OnBeforeSerialize() 89 | { 90 | keys.Clear(); 91 | values.Clear(); 92 | 93 | foreach (var pair in Implementation) 94 | { 95 | keys.Add(pair.Key); 96 | values.Add(pair.Value); 97 | } 98 | } 99 | 100 | public void OnAfterDeserialize() 101 | { 102 | Implementation.Clear(); 103 | for (var i = 0; i < keys.Count && i < values.Count; i++) 104 | { 105 | if (!Implementation.ContainsKey(keys[i])) 106 | Implementation.Add(keys[i], values[i]); 107 | else 108 | { 109 | key = keys[i]; 110 | value = values[i]; 111 | hasLostValue = true; 112 | } 113 | } 114 | #if !UNITY_EDITOR 115 | keys.Clear(); 116 | values.Clear(); 117 | ClearTemp(); 118 | #endif 119 | } 120 | 121 | public ICollection Keys => Implementation.Keys; 122 | public ICollection Values => Implementation.Values; 123 | public int Count => Implementation.Count; 124 | public bool IsReadOnly => Implementation.IsReadOnly; 125 | 126 | public bool IsSynchronized => (Implementation is ICollection) ? ((ICollection)Implementation).IsSynchronized : throw new NotImplementedException(); 127 | 128 | public object SyncRoot => (Implementation is ICollection) ? ((ICollection)Implementation).SyncRoot : throw new NotImplementedException(); 129 | 130 | public virtual void Add(KeyType key, ValueType value) => Implementation.Add(key, value); 131 | public void Add(KeyValuePair item) => Add(item.Key, item.Value); 132 | public virtual void Clear() => Implementation.Clear(); 133 | public bool Contains(KeyValuePair item) => Implementation.Contains(item); 134 | public bool ContainsKey(KeyType key) => Implementation.ContainsKey(key); 135 | public bool ContainsValue(ValueType value) 136 | { 137 | foreach (var dictionaryValue in Implementation.Values) 138 | if (value.Equals(dictionaryValue)) 139 | return true; 140 | 141 | return false; 142 | } 143 | public void CopyTo(KeyValuePair[] array, int arrayIndex) => Implementation.CopyTo(array, arrayIndex); 144 | public IEnumerator> GetEnumerator() => Implementation.GetEnumerator(); 145 | IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); 146 | public virtual bool Remove(KeyType key) => Implementation.Remove(key); 147 | public virtual bool Remove(KeyValuePair item) => Remove(item.Key); 148 | bool IDictionary.Remove(KeyType key) => Remove(key); 149 | public bool TryGetValue(KeyType key, out ValueType value) => Implementation.TryGetValue(key, out value); 150 | 151 | public void CopyTo(Array array, int index) 152 | { 153 | if (Implementation is ICollection) 154 | ((ICollection)Implementation).CopyTo(array, index); 155 | else 156 | throw new NotImplementedException(); 157 | } 158 | } 159 | } -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/Dictionary.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 560ee3d460461b74887717ad9511ac98 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/GUI.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 604197ecbf9187b40809fb49e20049c5 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/GUI/CollectionDisplay.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEditor; 3 | using UnityEditorInternal; 4 | #endif 5 | using System; 6 | using UnityEngine; 7 | using System.Text; 8 | 9 | namespace SerializableCollections.GUI 10 | { 11 | public class CollectionDisplay 12 | { 13 | #if UNITY_EDITOR 14 | public static System.Collections.Generic.Dictionary DrawerStates { get; private set; } = new System.Collections.Generic.Dictionary(); 15 | 16 | private static PlayModeStateChange playModeState; 17 | private static GUIStyle centeredLabelStyle = new GUIStyle(EditorStyles.boldLabel); 18 | private static GUIStyle headerStyle = new GUIStyle(EditorStyles.miniBoldLabel); 19 | 20 | static CollectionDisplay() 21 | { 22 | Selection.selectionChanged += () => DrawerStates.Clear(); 23 | 24 | EditorApplication.hierarchyChanged += () => 25 | { 26 | DrawerStates.Clear(); 27 | }; 28 | 29 | centeredLabelStyle.alignment = TextAnchor.UpperCenter; 30 | headerStyle.fontSize = 12; 31 | EditorApplication.playModeStateChanged -= OnPlayStateChanged; 32 | EditorApplication.playModeStateChanged += OnPlayStateChanged; 33 | } 34 | 35 | public static string GetFullPath(SerializedProperty property) 36 | { 37 | return property.serializedObject.targetObject.GetInstanceID() + property.propertyPath; 38 | } 39 | 40 | public static DrawerState GetDrawerState(SerializedProperty property) 41 | { 42 | string propertyPath = GetFullPath(property); 43 | DrawerState state; 44 | if (!DrawerStates.ContainsKey(propertyPath)) 45 | { 46 | state = new DrawerState(property); 47 | DrawerStates.Add(GetFullPath(property), state); 48 | state.Property = property; 49 | state.Height = 0; 50 | } 51 | else 52 | state = DrawerStates[propertyPath]; 53 | 54 | return state; 55 | } 56 | 57 | public Rect Render(Rect position, SerializedProperty property, GUIContent label) 58 | { 59 | if (property.serializedObject.targetObject == null) 60 | return position; 61 | 62 | if (playModeState == PlayModeStateChange.ExitingEditMode || playModeState == PlayModeStateChange.ExitingPlayMode) 63 | return position; 64 | 65 | DrawerState state = GetDrawerState(property); 66 | 67 | SerializedProperty collection = property.FindPropertyRelative("values"); 68 | if (collection == null) 69 | Debug.Log(property.name); 70 | if (!ReorderableCollection.ListStates.ContainsKey(GetFullPath(collection))) 71 | { 72 | var newList = new ReorderableCollection(property, collection); 73 | newList.DrawHeaderAreaHandlers.Add(DrawTitle); 74 | 75 | newList.DrawElement += DrawElement; 76 | newList.DrawAddElement = DrawAddElement; 77 | newList.GetElementHeight = GetElementHeight; 78 | newList.Reorder += OnReorder; 79 | } 80 | 81 | state.Property = property; 82 | state.Height = 0; 83 | 84 | Rect startPosition = position; 85 | 86 | DisplayState listState = ReorderableCollection.ListStates[GetFullPath(collection)]; 87 | Color cachedColor = UnityEngine.GUI.color; 88 | var settings = PackageSettings.Settings.GetListSettings(collection); 89 | 90 | if (settings != null && settings.Color != Color.white) 91 | UnityEngine.GUI.color = settings.Color; 92 | 93 | if (collection != null) 94 | { 95 | position = DrawCollection(position, property, collection, label); 96 | } 97 | state.Height = position.y - startPosition.y; 98 | UnityEngine.GUI.color = cachedColor; 99 | 100 | return position; 101 | } 102 | 103 | protected virtual Rect DrawCollection(Rect position, SerializedProperty property, SerializedProperty collection, GUIContent label) 104 | { 105 | EditorGUI.BeginProperty(position, new GUIContent(collection.displayName), collection); 106 | { 107 | Rect foldoutPos = position; 108 | foldoutPos.height = EditorGUIUtility.singleLineHeight; 109 | collection.isExpanded = EditorGUI.Foldout(foldoutPos, collection.isExpanded, label, true); 110 | 111 | position.y += EditorGUIUtility.singleLineHeight; 112 | 113 | DisplayState listState = ReorderableCollection.ListStates[GetFullPath(collection)]; 114 | listState.Collection = collection; 115 | ReorderableList valuePairList = listState.List.List; 116 | valuePairList.serializedProperty = collection; 117 | if (collection.isExpanded && collection.isArray) 118 | { 119 | valuePairList.DoList(position); 120 | position.y += valuePairList.GetHeight(); 121 | } 122 | } 123 | EditorGUI.EndProperty(); 124 | return position; 125 | } 126 | 127 | private static void OnPlayStateChanged(PlayModeStateChange state) 128 | { 129 | playModeState = state; 130 | ReorderableCollection.ListStates.Clear(); 131 | } 132 | 133 | public virtual float GetPropertyHeight(SerializedProperty property, GUIContent label) 134 | { 135 | if (DrawerStates.ContainsKey(GetFullPath(property))) 136 | return DrawerStates[GetFullPath(property)].Height; 137 | 138 | return EditorGUI.GetPropertyHeight(property); 139 | } 140 | 141 | protected virtual float GetElementHeight(int index, SerializedProperty property, SerializedProperty collection) 142 | { 143 | if (collection != null) 144 | return EditorGUI.GetPropertyHeight(collection.GetArrayElementAtIndex(index)); 145 | 146 | return 0; 147 | } 148 | 149 | protected virtual void OnReorder(SerializedProperty property, SerializedProperty collection, int oldIndex, int newIndex) 150 | { 151 | } 152 | 153 | protected virtual float DrawTitle(Rect position, SerializedProperty property, SerializedProperty collection) 154 | { 155 | Rect startPosition = position; 156 | var fieldValue = SerializationReflection.GetPathReference(collection); 157 | Type[] generics = fieldValue.GetType().GenericTypeArguments; 158 | StringBuilder typeArguments = new StringBuilder(); 159 | for (var i = 0; i < generics.Length; i++) 160 | { 161 | typeArguments.Append(ObjectNames.NicifyVariableName(generics[i].Name)); 162 | if (i < generics.Length - 1) 163 | typeArguments.Append(", "); 164 | } 165 | 166 | string nicePropertyType = ObjectNames.NicifyVariableName(property.type); 167 | GUIContent label = new GUIContent($"{nicePropertyType} ({typeArguments.ToString()})"); 168 | position.height = EditorStyles.label.CalcHeight(label, position.width) + 5; 169 | 170 | EditorGUI.LabelField(position, label, headerStyle); 171 | 172 | position.y += position.height; 173 | 174 | return position.y - startPosition.y; 175 | } 176 | 177 | protected virtual void DrawElement(Rect position, int index, SerializedProperty property, SerializedProperty collection) 178 | { 179 | position.xMin += 10; 180 | position.yMax -= 5; 181 | SerializedProperty arrayElement = collection.GetArrayElementAtIndex(index); 182 | UnityEngine.GUI.SetNextControlName($"{GetFullPath(collection)}/{index}"); 183 | float fieldHeight = EditorStyles.textField.fixedHeight; 184 | EditorStyles.textField.fixedHeight = position.height + 2; 185 | if ((arrayElement.propertyType != SerializedPropertyType.ObjectReference) 186 | && (arrayElement.propertyType != SerializedPropertyType.String)) 187 | EditorGUI.PropertyField(position, arrayElement, true); 188 | else 189 | EditorGUI.PropertyField(position, arrayElement, GUIContent.none, true); 190 | 191 | EditorStyles.textField.fixedHeight = fieldHeight; 192 | } 193 | 194 | protected virtual float DrawAddElement(Rect position, SerializedProperty property, SerializedProperty collection) 195 | { 196 | SerializedProperty value = property.FindPropertyRelative("value"); 197 | if (value == null) 198 | return 0; 199 | 200 | position.height = EditorGUI.GetPropertyHeight(value); 201 | EditorGUI.PropertyField(position, value, true); 202 | return position.height; 203 | } 204 | 205 | #endif 206 | } 207 | } -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/GUI/CollectionDisplay.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 42418651f0f80f04a99d696c06d67088 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/GUI/CollectionDrawer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using UnityEngine; 4 | #if UNITY_EDITOR 5 | using UnityEditor; 6 | #endif 7 | 8 | namespace SerializableCollections.GUI 9 | { 10 | public class CollectionDrawer 11 | #if UNITY_EDITOR 12 | : PropertyDrawer 13 | #endif 14 | { 15 | #if UNITY_EDITOR 16 | private static System.Collections.Generic.Dictionary DisplayHandlers = new System.Collections.Generic.Dictionary(); 17 | 18 | public CollectionDrawer() 19 | { 20 | Type currentType = GetType(); 21 | while (currentType != null) 22 | { 23 | foreach (var attribute in GetType().GetCustomAttributes()) 24 | { 25 | if (attribute is DisplayType) 26 | { 27 | DisplayType cast = attribute as DisplayType; 28 | CollectionDisplay handler = (CollectionDisplay)Activator.CreateInstance(cast.Type); 29 | if (!DisplayHandlers.ContainsKey(GetType())) 30 | DisplayHandlers.Add(GetType(), handler); 31 | 32 | break; 33 | } 34 | } 35 | 36 | currentType = currentType.BaseType; 37 | } 38 | } 39 | 40 | public static void RegisterForDrawer(Type drawerType, Type drawerFor) 41 | { 42 | Type attributeUtility = Type.GetType("UnityEditor.ScriptAttributeUtility, UnityEditor"); 43 | Type drawerKeySetType = attributeUtility.GetNestedType("DrawerKeySet", BindingFlags.NonPublic); 44 | FieldInfo drawerKeySetDrawerType = drawerKeySetType.GetField("drawer"); 45 | FieldInfo drawerKeySetDrawerTarget = drawerKeySetType.GetField("type"); 46 | FieldInfo drawerTypeMapField = attributeUtility.GetField("s_DrawerTypeForType", BindingFlags.Static | BindingFlags.NonPublic); 47 | object drawerTypeMap = drawerTypeMapField.GetValue(null); 48 | if (drawerTypeMap == null) 49 | { 50 | MethodInfo buildMethod = attributeUtility.GetMethod("BuildDrawerTypeForTypeDictionary", BindingFlags.Static | BindingFlags.NonPublic); 51 | try 52 | { 53 | buildMethod.Invoke(null, null); 54 | } 55 | catch (TargetInvocationException) 56 | { 57 | // For some reason, this method generates a null argument down the line from a LINQ call. Doesn't seem to affect 58 | // functionality, so we're ignoring the exception. 59 | } 60 | drawerTypeMap = drawerTypeMapField.GetValue(attributeUtility); 61 | } 62 | MethodInfo drawerTypeMapAdd = drawerTypeMap.GetType().GetMethod("Add", new Type[] { typeof(Type), drawerKeySetType }); 63 | MethodInfo drawerTypeMapContainsKey = drawerTypeMap.GetType().GetMethod("ContainsKey", new Type[] { typeof(Type) }); 64 | bool containsKey = (bool)drawerTypeMapContainsKey.Invoke(drawerTypeMap, new object[] { drawerFor }); 65 | if (!containsKey) 66 | { 67 | object drawerKeySet = Activator.CreateInstance(drawerKeySetType); 68 | drawerKeySetDrawerType.SetValue(drawerKeySet, drawerType); 69 | drawerKeySetDrawerTarget.SetValue(drawerKeySet, drawerFor); 70 | drawerTypeMapAdd.Invoke(drawerTypeMap, new object[] { drawerFor, drawerKeySet }); 71 | } 72 | } 73 | 74 | public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 75 | { 76 | if (property != null && DisplayHandlers.ContainsKey(GetType())) 77 | DisplayHandlers[GetType()].Render(position, property, label); 78 | } 79 | 80 | public override float GetPropertyHeight(SerializedProperty property, GUIContent label) 81 | { 82 | if (DisplayHandlers.ContainsKey(GetType())) 83 | return DisplayHandlers[GetType()].GetPropertyHeight(property, label); 84 | 85 | return 0; 86 | } 87 | #endif 88 | } 89 | } -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/GUI/CollectionDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9c12bb54f7efc144385ce439eaa3193f 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/GUI/CustomCollectionAdd.cs: -------------------------------------------------------------------------------- 1 | namespace SerializableCollections.GUI 2 | { 3 | public interface CustomCollectionAdd 4 | { 5 | T Value { get; } 6 | void AddTemp(); 7 | void ClearTemp(); 8 | } 9 | } -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/GUI/CustomCollectionAdd.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 72dc82692e07a184dbb899ae1e1765bd 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/GUI/DictionaryDisplay.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using System; 3 | using UnityEditor; 4 | #endif 5 | using UnityEngine; 6 | 7 | namespace SerializableCollections.GUI 8 | { 9 | public class DictionaryDisplay : CollectionDisplay 10 | { 11 | #if UNITY_EDITOR 12 | private GUIStyle headerStyle = new GUIStyle(EditorStyles.miniBoldLabel); 13 | 14 | public DictionaryDisplay() : base() 15 | { 16 | headerStyle.alignment = TextAnchor.MiddleCenter; 17 | headerStyle.fontSize = 12; 18 | } 19 | 20 | protected override float GetElementHeight(int index, SerializedProperty property, SerializedProperty element) 21 | { 22 | if (property == null || property.serializedObject.targetObject == null) 23 | return 0; 24 | 25 | SerializedProperty keys = property.FindPropertyRelative("keys"); 26 | SerializedProperty values = property.FindPropertyRelative("values"); 27 | var key = keys?.GetArrayElementAtIndex(index); 28 | var value = values?.GetArrayElementAtIndex(index); 29 | float keyHeight = (key != null) ? EditorGUI.GetPropertyHeight(key) : 0; 30 | float valueHeight = (value != null) ? EditorGUI.GetPropertyHeight(value) : 0; 31 | keyHeight += 5; 32 | valueHeight += 5; 33 | float pairHeight = (keyHeight > valueHeight) ? keyHeight : valueHeight; 34 | return pairHeight; 35 | } 36 | 37 | protected override Rect DrawCollection(Rect position, SerializedProperty property, SerializedProperty collection, GUIContent label) 38 | { 39 | ReorderableCollection.ListStates[GetFullPath(collection)].List.DrawCustomAdd = true; 40 | return base.DrawCollection(position, property, collection, label); 41 | } 42 | 43 | protected override float DrawTitle(Rect position, SerializedProperty property, SerializedProperty collection) 44 | { 45 | float startY = position.y; 46 | position.y -= 2; 47 | 48 | Rect keyLabelPosition = position; 49 | keyLabelPosition.width *= .5f; 50 | keyLabelPosition.xMin += 10; 51 | keyLabelPosition.xMax -= 10; 52 | 53 | Rect valueLabelPosition = position; 54 | valueLabelPosition.width *= .5f; 55 | valueLabelPosition.x += valueLabelPosition.width; 56 | valueLabelPosition.width -= 11; 57 | 58 | var fieldValue = SerializationReflection.GetPathField(collection); 59 | Type[] generics = fieldValue.Value.DeclaringType.GenericTypeArguments; 60 | string keyType = ObjectNames.NicifyVariableName(generics[0].Name); 61 | string valueType = ObjectNames.NicifyVariableName(generics[1].Name); 62 | 63 | GUIContent keyLabel = new GUIContent("Key (" + keyType + ")"); 64 | GUIContent valueLabel = new GUIContent("Value (" + valueType + ")"); 65 | keyLabelPosition.height = headerStyle.CalcHeight(keyLabel, position.width) + 5; 66 | valueLabelPosition.height = keyLabelPosition.height; 67 | EditorGUI.LabelField(keyLabelPosition, keyLabel, headerStyle); 68 | EditorGUI.LabelField(valueLabelPosition, valueLabel, headerStyle); 69 | position.y += valueLabelPosition.height; 70 | return position.y - startY; 71 | } 72 | 73 | protected override void DrawElement(Rect position, int index, SerializedProperty property, SerializedProperty collection) 74 | { 75 | SerializedProperty keys = property.FindPropertyRelative("keys"); 76 | SerializedProperty values = property.FindPropertyRelative("values"); 77 | SerializedProperty key = keys.GetArrayElementAtIndex(index); 78 | SerializedProperty value = values.GetArrayElementAtIndex(index); 79 | 80 | position.xMin += 10f; 81 | 82 | Rect keyPosition = position; 83 | keyPosition.xMax -= position.width * .5f; 84 | keyPosition.xMax -= 10; 85 | keyPosition.height = EditorGUI.GetPropertyHeight(key) + 2; 86 | 87 | Rect valuePosition = position; 88 | valuePosition.xMin += position.width * .5f; 89 | valuePosition.xMin += 10; 90 | valuePosition.height = EditorGUI.GetPropertyHeight(value) + 2; 91 | 92 | float labelWidth = EditorGUIUtility.labelWidth; 93 | EditorGUIUtility.labelWidth = keyPosition.width * .4f; 94 | 95 | UnityEngine.GUI.SetNextControlName(GetFullPath(keys) + "/" + index); 96 | float textFieldHeight = EditorStyles.textField.fixedHeight; 97 | EditorStyles.textField.fixedHeight = keyPosition.height; 98 | if (key.hasChildren && (key.propertyType != SerializedPropertyType.ObjectReference) && (key.propertyType != SerializedPropertyType.String)) 99 | EditorGUI.PropertyField(keyPosition, key, new GUIContent("Key"), true); 100 | else 101 | EditorGUI.PropertyField(keyPosition, key, GUIContent.none, true); 102 | 103 | EditorStyles.textField.fixedHeight = valuePosition.height; 104 | UnityEngine.GUI.SetNextControlName(GetFullPath(values) + "/" + index); 105 | EditorGUIUtility.labelWidth = valuePosition.width * .4f; 106 | if (value.hasChildren && (value.propertyType != SerializedPropertyType.ObjectReference) && (value.propertyType != SerializedPropertyType.String)) 107 | EditorGUI.PropertyField(valuePosition, value, new GUIContent("Value"), true); 108 | else 109 | EditorGUI.PropertyField(valuePosition, value, GUIContent.none, true); 110 | 111 | EditorStyles.textField.fixedHeight = textFieldHeight; 112 | EditorGUIUtility.labelWidth = labelWidth; 113 | } 114 | 115 | protected override float DrawAddElement(Rect position, SerializedProperty property, SerializedProperty collection) 116 | { 117 | var tempKey = property.FindPropertyRelative("key"); 118 | var tempValue = property.FindPropertyRelative("value"); 119 | float labelWidth = EditorGUIUtility.labelWidth; 120 | Rect startPostion = position; 121 | 122 | Rect keyPosition = position; 123 | keyPosition.xMin += 15; 124 | keyPosition.xMax -= position.width * .5f + 10; 125 | keyPosition.height = EditorGUI.GetPropertyHeight(tempKey); 126 | 127 | float fieldHeight = EditorStyles.textField.fixedHeight; 128 | EditorStyles.textField.fixedHeight = keyPosition.height + 2; 129 | UnityEngine.GUI.SetNextControlName("New Key Add"); 130 | EditorGUIUtility.labelWidth = keyPosition.width * .4f; 131 | if (tempKey.hasChildren && (tempKey.propertyType != SerializedPropertyType.ObjectReference) && (tempKey.propertyType != SerializedPropertyType.String)) 132 | EditorGUI.PropertyField(keyPosition, tempKey, new GUIContent(tempKey.displayName), true); 133 | else 134 | EditorGUI.PropertyField(keyPosition, tempKey, GUIContent.none); 135 | 136 | Rect valuePosition = position; 137 | valuePosition.xMin += position.width * .5f + 10; 138 | valuePosition.xMax -= 15; 139 | valuePosition.height = EditorGUI.GetPropertyHeight(tempValue); 140 | 141 | EditorStyles.textField.fixedHeight = valuePosition.height + 2; 142 | EditorGUIUtility.labelWidth = valuePosition.width * .4f; 143 | if (tempValue.hasChildren && (tempValue.propertyType != SerializedPropertyType.ObjectReference) && (tempValue.propertyType != SerializedPropertyType.String)) 144 | EditorGUI.PropertyField(valuePosition, tempValue, new GUIContent(tempValue.displayName), true); 145 | else 146 | EditorGUI.PropertyField(valuePosition, tempValue, GUIContent.none); 147 | 148 | 149 | EditorStyles.textField.fixedHeight = fieldHeight; 150 | 151 | EditorGUIUtility.labelWidth = labelWidth; 152 | 153 | float propertyHeight = (keyPosition.height > valuePosition.height) ? keyPosition.height : valuePosition.height; 154 | position.y += propertyHeight + 5; 155 | return position.y - startPostion.y; 156 | } 157 | 158 | protected override void OnReorder(SerializedProperty property, SerializedProperty collection, int oldIndex, int newIndex) 159 | { 160 | SerializedProperty keys = property.FindPropertyRelative("keys"); 161 | keys.MoveArrayElement(oldIndex, newIndex); 162 | base.OnReorder(property, collection, oldIndex, newIndex); 163 | } 164 | #endif 165 | } 166 | } -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/GUI/DictionaryDisplay.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 15e80df3f7a0bb240a7400596f6a1ea3 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/GUI/DictionaryDrawer.cs: -------------------------------------------------------------------------------- 1 | namespace SerializableCollections.GUI 2 | { 3 | [DisplayType(typeof(DictionaryDisplay))] 4 | public class DictionaryDrawer : CollectionDrawer 5 | { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/GUI/DictionaryDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a0056ed6d9fd2e84eb7176a4e7dc22ec 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/GUI/DisplayState.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEditor; 3 | 4 | namespace SerializableCollections.GUI 5 | { 6 | public class DisplayState 7 | { 8 | public SerializedProperty Collection { get; set; } 9 | public ReorderableCollection List { get; set; } 10 | public bool ElementsDisabled { get; set; } 11 | private bool addingElement; 12 | public bool AddingElement { get { return addingElement; } set { addingElement = value; List.List.draggable = !value; } } 13 | public float LastAddingHeight { get; set; } 14 | public float LastHeaderHeight { get; set; } 15 | public float LastFooterHeight { get; set; } 16 | public bool EditingSettings { get; set; } 17 | public int CurrentPage { get; set; } 18 | public int CurrentPageSet { get; set; } 19 | public int PageSetSize { get; set; } 20 | } 21 | } 22 | #endif 23 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/GUI/DisplayState.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5af88ce31a9e6b841a457d3ed99626ae 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/GUI/DisplayType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SerializableCollections.GUI 4 | { 5 | [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] 6 | public class DisplayType : Attribute 7 | { 8 | public Type Type; 9 | 10 | public DisplayType(Type displayClass) 11 | { 12 | Type = displayClass; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/GUI/DisplayType.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 55a424de4f9cf29449c7926c7a1c4abf 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/GUI/DrawerState.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEditor; 3 | 4 | namespace SerializableCollections.GUI 5 | { 6 | public sealed class DrawerState 7 | { 8 | public SerializedProperty Property { get; set; } 9 | public float Height { get; set; } 10 | 11 | public DrawerState(SerializedProperty property) 12 | { 13 | Property = property; 14 | } 15 | } 16 | } 17 | #endif 18 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/GUI/DrawerState.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7c1e87b12bce36e4583d137a3a623d35 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/GUI/HashSetDrawer.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEditor; 3 | using UnityEngine; 4 | 5 | namespace SerializableCollections.GUI 6 | { 7 | [DisplayType(typeof(HashSetDisplay))] 8 | public class HashSetDrawer : CollectionDrawer 9 | { 10 | } 11 | 12 | public class HashSetDisplay : CollectionDisplay 13 | { 14 | protected override Rect DrawCollection(Rect position, SerializedProperty property, SerializedProperty collection, GUIContent label) 15 | { 16 | ReorderableCollection.ListStates[GetFullPath(collection)].List.DrawCustomAdd = true; 17 | return base.DrawCollection(position, property, collection, label); 18 | } 19 | } 20 | } 21 | #endif -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/GUI/HashSetDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a443c15d69a4e024bb48371e2c4a49b6 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/GUI/LinkedListDrawer.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEditor; 3 | using UnityEngine; 4 | 5 | namespace SerializableCollections.GUI 6 | { 7 | [DisplayType(typeof(LinkedListDisplay))] 8 | public class LinkedListDrawer : CollectionDrawer 9 | { 10 | } 11 | 12 | public class LinkedListDisplay : CollectionDisplay 13 | { 14 | protected override Rect DrawCollection(Rect position, SerializedProperty property, SerializedProperty collection, GUIContent label) 15 | { 16 | ReorderableCollection.ListStates[GetFullPath(collection)].List.DrawCustomAdd = true; 17 | return base.DrawCollection(position, property, collection, label); 18 | } 19 | } 20 | } 21 | #endif -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/GUI/LinkedListDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 149a3eec5254b3a43bc8ed2122b3ae64 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/GUI/ListDrawer.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | 3 | namespace SerializableCollections.GUI 4 | { 5 | [DisplayType(typeof(CollectionDisplay))] 6 | public class ListDrawer : CollectionDrawer 7 | { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/GUI/ListDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c6fdb05e4e9b457479402ed300d031fe 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/GUI/ReorderableCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | #if UNITY_EDITOR 5 | using UnityEditor; 6 | using UnityEditorInternal; 7 | #endif 8 | 9 | namespace SerializableCollections.GUI 10 | { 11 | public class ReorderableCollection 12 | { 13 | #if UNITY_EDITOR 14 | public delegate float DrawAreaHandler(Rect position, SerializedProperty property, SerializedProperty collection); 15 | public delegate void DrawElementHandler(Rect position, int index, SerializedProperty property, SerializedProperty collection); 16 | public delegate float ElementHeightHandler(int index, SerializedProperty property, SerializedProperty collection); 17 | public delegate void ReorderHandler(SerializedProperty property, SerializedProperty collection, int oldIndex, int newIndex); 18 | 19 | public static Dictionary ListStates { get; private set; } = new Dictionary(); 20 | public static readonly Texture2D alternatingBGColor = new Texture2D(1, 1); 21 | public static readonly Texture2D selectedColor = new Texture2D(1, 1); 22 | private static readonly GUIStyle linkStyle = new GUIStyle(EditorStyles.label); 23 | private static readonly GUIStyle headerBackgroundStyle = new GUIStyle("RL Header"); 24 | private static readonly GUIStyle footerBackgroundStyle = new GUIStyle("RL Footer"); 25 | private static readonly GUIStyle centeredLabelStyle = new GUIStyle(EditorStyles.boldLabel); 26 | private static readonly GUIStyle addRemButtonStyle = new GUIStyle("Button"); 27 | private static readonly GUIStyle activeSettingsBackground = new GUIStyle(); 28 | private static readonly GUIStyle boxBackground = "RL Background"; 29 | private static readonly Texture2D dividerTexture = new Texture2D(1, 1); 30 | 31 | static ReorderableCollection() 32 | { 33 | Selection.selectionChanged += () => 34 | { 35 | ListStates.Clear(); 36 | }; 37 | 38 | EditorApplication.hierarchyChanged += () => 39 | { 40 | ListStates.Clear(); 41 | }; 42 | 43 | centeredLabelStyle.alignment = TextAnchor.UpperCenter; 44 | dividerTexture.SetPixel(0, 0, (EditorGUIUtility.isProSkin) ? Color.white : Color.black); 45 | activeSettingsBackground.normal.background = dividerTexture; 46 | alternatingBGColor.SetPixel(0, 0, (EditorGUIUtility.isProSkin) ? new Color(.25f, .25f, .25f) : new Color(.75f, .75f, .75f)); 47 | selectedColor.SetPixel(0, 0, UnityEngine.GUI.skin.settings.selectionColor); 48 | linkStyle.normal.textColor = Color.blue; 49 | linkStyle.hover.textColor = Color.cyan; 50 | addRemButtonStyle.alignment = TextAnchor.MiddleCenter; 51 | addRemButtonStyle.fontSize = 14; 52 | addRemButtonStyle.fontStyle = FontStyle.Bold; 53 | } 54 | 55 | public static int GetItemsPerPage(SerializedProperty collection) 56 | { 57 | PackageSettings.ViewSettings settings = PackageSettings.Settings.GetListSettings(collection); 58 | PackageSettings.ViewSettings defaultSettings = PackageSettings.Settings.DefaultListSettings; 59 | int pageSize; 60 | if (settings == null) 61 | pageSize = (defaultSettings.UsePages) ? defaultSettings.ItemsPerPage : collection.arraySize; 62 | else 63 | pageSize = (settings.UsePages) ? settings.ItemsPerPage : collection.arraySize; 64 | 65 | return pageSize; 66 | } 67 | 68 | public static Vector2Int GetPageDisplayRange(SerializedProperty collection) 69 | { 70 | DisplayState state = ListStates[CollectionDisplay.GetFullPath(collection)]; 71 | int pageSize = GetItemsPerPage(state.Collection); 72 | int pageStartIndex = (state.CurrentPageSet * state.PageSetSize) + (state.CurrentPage * pageSize); 73 | int pageEndIndex = pageStartIndex + pageSize; 74 | return new Vector2Int(pageStartIndex, pageEndIndex); 75 | } 76 | 77 | private float DrawSettingsButton(Rect position, SerializedProperty property, SerializedProperty collection) 78 | { 79 | var state = ListStates[CollectionDisplay.GetFullPath(collection)]; 80 | Rect settingsPosition = position; 81 | settingsPosition.xMin = (settingsPosition.xMax - 20) + 7; 82 | settingsPosition.xMax += 7; 83 | settingsPosition.y += 4; 84 | settingsPosition.height = 20; 85 | 86 | GUIContent iconContent = EditorGUIUtility.IconContent("_Popup"); 87 | GUIStyle buttonStyle = centeredLabelStyle; 88 | Color guiColor = UnityEngine.GUI.color; 89 | if (state.EditingSettings) 90 | { 91 | UnityEngine.GUI.color = Color.Lerp(guiColor, Color.yellow, .3f); 92 | buttonStyle = activeSettingsBackground; 93 | buttonStyle.fixedHeight = settingsPosition.height - 4; 94 | buttonStyle.fixedWidth = settingsPosition.width - 4; 95 | } 96 | 97 | if (UnityEngine.GUI.Button(settingsPosition, iconContent.image, buttonStyle)) 98 | { 99 | state.EditingSettings = !state.EditingSettings; 100 | } 101 | 102 | UnityEngine.GUI.color = guiColor; 103 | return 0; 104 | } 105 | 106 | private static float DrawSettings(Rect position, SerializedProperty property, SerializedProperty collection) 107 | { 108 | var listState = ListStates[CollectionDisplay.GetFullPath(collection)]; 109 | 110 | if (!listState.EditingSettings) 111 | { 112 | return 0; 113 | } 114 | 115 | Rect startPosition = position; 116 | 117 | position.xMin -= 6; 118 | position.xMax += 6; 119 | 120 | PackageSettings.ViewSettings settings = PackageSettings.Settings.GetListSettings(collection); 121 | PackageSettings.ViewSettings defaultSettings = PackageSettings.Settings.DefaultListSettings; 122 | int pageSize = (settings == null) ? defaultSettings.ItemsPerPage : settings.ItemsPerPage; 123 | position.xMin += 7; 124 | position.xMax -= 7; 125 | position.y += 4; 126 | 127 | position.height = EditorStyles.boldLabel.CalcHeight(new GUIContent("List Settings"), position.width); 128 | UnityEngine.GUI.Label(position, new GUIContent("List Settings"), EditorStyles.boldLabel); 129 | position.y += position.height; 130 | 131 | bool usePages = (settings == null) ? defaultSettings.UsePages : settings.UsePages; 132 | bool newUsePages = EditorGUI.Toggle(position, "Use Page System", usePages); 133 | position.y += position.height; 134 | if (usePages != newUsePages) 135 | { 136 | if (settings == null) 137 | settings = PackageSettings.Settings.AddNewSettings(collection); 138 | 139 | settings.UsePages = newUsePages; 140 | listState.CurrentPage = 0; 141 | EditorUtility.SetDirty(PackageSettings.Settings); 142 | } 143 | 144 | float fieldHeight = EditorStyles.textField.fixedHeight; 145 | position.height = EditorGUIUtility.singleLineHeight; 146 | EditorStyles.textField.fixedHeight = position.height; 147 | if (newUsePages) 148 | { 149 | int newPageSize = EditorGUI.DelayedIntField(position, "Items Per Page", pageSize); 150 | if (newPageSize < 1) 151 | newPageSize = Mathf.Clamp(newPageSize, 1, 100); 152 | 153 | if (newPageSize != pageSize) 154 | { 155 | if (settings == null) 156 | settings = PackageSettings.Settings.AddNewSettings(collection); 157 | 158 | settings.ItemsPerPage = newPageSize; 159 | listState.CurrentPage = 0; 160 | EditorUtility.SetDirty(PackageSettings.Settings); 161 | } 162 | position.y += position.height + 4; 163 | } 164 | 165 | Color settingsColor = (settings == null) ? defaultSettings.Color : settings.Color; 166 | Color newColor = EditorGUI.ColorField(position, "List Color", settingsColor); 167 | if (newColor != settingsColor) 168 | { 169 | if (settings == null) 170 | settings = PackageSettings.Settings.AddNewSettings(collection); 171 | 172 | settings.Color = newColor; 173 | EditorUtility.SetDirty(PackageSettings.Settings); 174 | } 175 | position.y += position.height + 4; 176 | 177 | EditorStyles.textField.fixedHeight = fieldHeight; 178 | position.height = 2; 179 | UnityEngine.GUI.DrawTexture(position, dividerTexture); 180 | position.y += position.height + 2; 181 | return position.y - startPosition.y; 182 | } 183 | 184 | private static float DrawPageSelection(Rect position, SerializedProperty property, SerializedProperty collection) 185 | { 186 | Rect startPosition = position; 187 | var state = ListStates[CollectionDisplay.GetFullPath(collection)]; 188 | int currentPage = state.CurrentPage; 189 | int pageSize = GetItemsPerPage(collection); 190 | int pages = Mathf.CeilToInt(collection.arraySize / (float)pageSize); 191 | 192 | Rect pagePosition = position; 193 | pagePosition.height = EditorGUIUtility.singleLineHeight + 5; 194 | pagePosition.xMax = pagePosition.xMin + 20; 195 | float availableWidth = position.width - 100; 196 | int maxPossiblePageButtons = Mathf.RoundToInt(Mathf.Abs(Mathf.Ceil(availableWidth / pagePosition.width))) - 2; 197 | int pageSets = Mathf.CeilToInt(pages / (float)maxPossiblePageButtons); 198 | int startPage = state.CurrentPage; 199 | int startPageSet = state.CurrentPageSet; 200 | 201 | if ((state.CurrentPageSet * maxPossiblePageButtons) >= pages) 202 | state.CurrentPageSet = 0; 203 | 204 | int pageMin = (state.CurrentPageSet * maxPossiblePageButtons); 205 | int pageMax = pageMin + maxPossiblePageButtons; 206 | if (pageMax >= pages) 207 | pageMax = pages; 208 | 209 | if (Event.current.type == EventType.Repaint) 210 | { 211 | state.PageSetSize = maxPossiblePageButtons; 212 | 213 | if (state.CurrentPage >= (pageMax - pageMin)) 214 | state.CurrentPage = 0; 215 | if (state.CurrentPage < 0) 216 | state.CurrentPage = (pageMax - pageMin) - 1; 217 | } 218 | 219 | if (pages > 1) 220 | { 221 | if (state.CurrentPageSet > 0) 222 | { 223 | EditorGUIUtility.AddCursorRect(pagePosition, MouseCursor.Link); 224 | if (UnityEngine.GUI.Button(pagePosition, EditorGUIUtility.TrIconContent("Animation.FirstKey"), linkStyle)) 225 | { 226 | EditorGUIUtility.AddCursorRect(pagePosition, MouseCursor.Link); 227 | state.CurrentPageSet--; 228 | } 229 | } 230 | 231 | pagePosition.x += pagePosition.width; 232 | 233 | if (currentPage + state.CurrentPageSet > 0) 234 | { 235 | EditorGUIUtility.AddCursorRect(pagePosition, MouseCursor.Link); 236 | if (UnityEngine.GUI.Button(pagePosition, EditorGUIUtility.TrIconContent("Animation.PrevKey", "Previous page"), linkStyle)) 237 | { 238 | EditorGUIUtility.AddCursorRect(pagePosition, MouseCursor.Link); 239 | state.CurrentPage--; 240 | 241 | if (state.CurrentPage < 0) 242 | { 243 | state.CurrentPageSet--; 244 | state.CurrentPage = maxPossiblePageButtons - 1; 245 | } 246 | } 247 | } 248 | 249 | pagePosition.x += pagePosition.width; 250 | 251 | for (var i = pageMin; i < pageMax; i++) 252 | { 253 | GUIContent label = new GUIContent((i + 1).ToString()); 254 | if (i != state.CurrentPage + pageMin) 255 | { 256 | EditorGUIUtility.AddCursorRect(pagePosition, MouseCursor.Link); 257 | if (UnityEngine.GUI.Button(pagePosition, label, linkStyle)) 258 | { 259 | state.CurrentPage = i - pageMin; 260 | } 261 | } 262 | else 263 | { 264 | UnityEngine.GUI.Label(pagePosition, label, EditorStyles.boldLabel); 265 | Rect underlinePos = pagePosition; 266 | EditorStyles.boldLabel.CalcMinMaxWidth(label, out _, out float maxWidth); 267 | underlinePos.width = maxWidth; 268 | underlinePos.yMax -= 3; 269 | underlinePos.yMin = underlinePos.yMax - 2; 270 | EditorGUI.DrawRect(underlinePos, EditorStyles.boldLabel.normal.textColor); 271 | } 272 | 273 | pagePosition.x += pagePosition.width; 274 | } 275 | 276 | if (currentPage + pageMin < (pages - 1)) 277 | { 278 | EditorGUIUtility.AddCursorRect(pagePosition, MouseCursor.Link); 279 | if (UnityEngine.GUI.Button(pagePosition, EditorGUIUtility.TrIconContent("Animation.NextKey", "Next Page."), linkStyle)) 280 | { 281 | state.CurrentPage++; 282 | if (state.CurrentPage + (state.CurrentPageSet * maxPossiblePageButtons) >= pageMax) 283 | { 284 | state.CurrentPageSet++; 285 | state.CurrentPage = 0; 286 | } 287 | } 288 | 289 | pagePosition.x += pagePosition.width; 290 | } 291 | 292 | if (state.CurrentPageSet < pageSets - 1) 293 | { 294 | EditorGUIUtility.AddCursorRect(pagePosition, MouseCursor.Link); 295 | if (UnityEngine.GUI.Button(pagePosition, EditorGUIUtility.TrIconContent("Animation.LastKey"), linkStyle)) 296 | { 297 | EditorGUIUtility.AddCursorRect(pagePosition, MouseCursor.Link); 298 | state.CurrentPageSet++; 299 | } 300 | } 301 | } 302 | 303 | if (state.CurrentPage != startPage || state.CurrentPageSet != startPageSet) 304 | { 305 | EditorGUIUtility.editingTextField = false; 306 | state.List.List.index = -1; 307 | } 308 | 309 | position.y += pagePosition.height; 310 | return position.y - startPosition.y; 311 | } 312 | 313 | private static float DrawHeaderBackground(Rect position, SerializedProperty property, SerializedProperty collection) 314 | { 315 | var listState = ListStates[CollectionDisplay.GetFullPath(collection)]; 316 | Rect bgPosition = position; 317 | bgPosition.xMin -= 6; 318 | bgPosition.xMax += 6; 319 | DrawAreaBackground(bgPosition, headerBackgroundStyle, listState.LastHeaderHeight + 2); 320 | return 0; 321 | } 322 | 323 | private static float DrawFooterBackground(Rect position, SerializedProperty property, SerializedProperty collection) 324 | { 325 | var listState = ListStates[CollectionDisplay.GetFullPath(collection)]; 326 | position.yMin -= 2; 327 | DrawAreaBackground(position, footerBackgroundStyle, listState.LastFooterHeight); 328 | return 0; 329 | } 330 | 331 | private static void DrawAreaBackground(Rect position, GUIStyle style, float height) 332 | { 333 | if (Event.current.type == EventType.Repaint) 334 | { 335 | Rect backgroundPos = position; 336 | backgroundPos.height = height; 337 | backgroundPos.yMax = backgroundPos.yMin + height; 338 | style.fixedHeight = backgroundPos.height; 339 | style.fixedWidth = backgroundPos.width; 340 | style.Draw(backgroundPos, GUIContent.none, 2); 341 | } 342 | } 343 | 344 | private static float DrawAddRemoveButtons(Rect position, SerializedProperty property, SerializedProperty collection) 345 | { 346 | var state = ListStates[CollectionDisplay.GetFullPath(collection)]; 347 | 348 | Rect addButtonPosition = position; 349 | addButtonPosition.height = 20; 350 | addButtonPosition.xMax -= 3; 351 | addButtonPosition.xMin = addButtonPosition.xMax - 20; 352 | 353 | if (UnityEngine.GUI.Button(addButtonPosition, "+", addRemButtonStyle)) 354 | { 355 | state.List.List.onAddCallback.Invoke(state.List.List); 356 | state.ElementsDisabled = false; 357 | } 358 | 359 | Rect remButtonPosition = addButtonPosition; 360 | remButtonPosition.x -= 20; 361 | if (collection.arraySize > 0 && state.List.List.index > -1) 362 | if (UnityEngine.GUI.Button(remButtonPosition, "-", addRemButtonStyle)) 363 | state.List.List.onRemoveCallback.Invoke(state.List.List); 364 | 365 | return 0; 366 | } 367 | 368 | public event ReorderHandler Reorder; 369 | public event DrawElementHandler DrawElement; 370 | public DrawAreaHandler DrawAddElement { get; set; } 371 | public ElementHeightHandler GetElementHeight; 372 | public ReorderableList List; 373 | public bool DrawCustomAdd { get; set; } 374 | 375 | public List DrawHeaderAreaHandlers = new List(); 376 | public List DrawFooterAreaHandlers = new List(); 377 | 378 | public ReorderableCollection(SerializedProperty property, SerializedProperty collection) 379 | { 380 | bool allowDrag = true; 381 | object pathReference = SerializationReflection.GetPathReference(property); 382 | if (pathReference != null) 383 | { 384 | Type sortedType = SerializationReflection.GetPathReference(property).GetType(); 385 | 386 | while (sortedType != null) 387 | { 388 | if (sortedType.GetInterface("SortedCollection`1") != null) 389 | { 390 | allowDrag = false; 391 | break; 392 | } 393 | sortedType = sortedType.BaseType; 394 | } 395 | } 396 | 397 | string collectionPath = CollectionDisplay.GetFullPath(collection); 398 | 399 | DisplayState listState; 400 | if (ListStates.ContainsKey(collectionPath)) 401 | ListStates.Remove(collectionPath); 402 | 403 | listState = new DisplayState(); 404 | ListStates.Add(collectionPath, listState); 405 | listState.Collection = collection; 406 | listState.List = this; 407 | 408 | DrawerState drawerState = CollectionDisplay.GetDrawerState(property); 409 | var newList = new ReorderableList(collection.serializedObject, collection) 410 | { 411 | draggable = allowDrag, 412 | }; 413 | newList.showDefaultBackground = false; 414 | 415 | newList.onReorderCallbackWithDetails = (ReorderableList list, int oldIndex, int newIndex) => 416 | { 417 | Reorder?.Invoke(drawerState.Property, listState.Collection, oldIndex, newIndex); 418 | }; 419 | 420 | newList.drawHeaderCallback = (Rect position) => 421 | { 422 | SerializedProperty hasLostValue = drawerState.Property.FindPropertyRelative("hasLostValue"); 423 | if (hasLostValue != null && hasLostValue.boolValue == true) 424 | { 425 | EditorUtility.DisplayDialog("Collection Error", "You've attempted to change an element in a way that prevents it from being added to the collection. The element will be moved to the Add Element area of the list so you can change the element and add it back in.", "Okay"); 426 | ListStates[CollectionDisplay.GetFullPath(listState.Collection)].AddingElement = true; 427 | hasLostValue.boolValue = false; 428 | } 429 | 430 | Rect startPosition = position; 431 | 432 | DrawHeaderBackground(position, drawerState.Property, listState.Collection); 433 | DrawSettingsButton(position, drawerState.Property, listState.Collection); 434 | position.y += DrawSettings(position, drawerState.Property, listState.Collection); 435 | 436 | for (var i = 0; i < DrawHeaderAreaHandlers.Count; i++) 437 | { 438 | position.y += DrawHeaderAreaHandlers[i].Invoke(position, drawerState.Property, listState.Collection); 439 | } 440 | 441 | listState.LastHeaderHeight = position.y - startPosition.y; 442 | newList.headerHeight = listState.LastHeaderHeight; 443 | }; 444 | 445 | newList.drawElementCallback += (Rect position, int index, bool isActive, bool isFocused) => 446 | { 447 | position.y += 2; 448 | 449 | var pageRange = GetPageDisplayRange(listState.Collection); 450 | if (index >= pageRange.x && index < pageRange.y) 451 | { 452 | EditorGUI.BeginDisabledGroup(listState.AddingElement); 453 | DrawElement?.Invoke(position, index, drawerState.Property, listState.Collection); 454 | EditorGUI.EndDisabledGroup(); 455 | } 456 | }; 457 | 458 | newList.drawElementBackgroundCallback = (Rect position, int index, bool isActive, bool isFocused) => 459 | { 460 | if (Mathf.Approximately(position.height, 0)) 461 | return; 462 | 463 | Rect backgroundPos = position; 464 | backgroundPos.yMin -= 2; 465 | backgroundPos.yMax += 2; 466 | boxBackground.fixedHeight = backgroundPos.height; 467 | boxBackground.fixedWidth = backgroundPos.width; 468 | Color guiColor = UnityEngine.GUI.color; 469 | 470 | if (isActive) 471 | UnityEngine.GUI.color = UnityEngine.GUI.skin.settings.selectionColor; 472 | 473 | if (index % 2 == 0) 474 | { 475 | UnityEngine.GUI.color = Color.Lerp(UnityEngine.GUI.color, Color.black, .1f); 476 | } 477 | 478 | if (Event.current.type == EventType.Repaint) 479 | boxBackground.Draw(position, false, isActive, true, false); 480 | 481 | UnityEngine.GUI.color = guiColor; 482 | 483 | position.xMin += 2; 484 | position.xMax -= 3; 485 | }; 486 | 487 | newList.elementHeightCallback += (int index) => 488 | { 489 | int pageSize = GetItemsPerPage(listState.Collection); 490 | int pageStartIndex = (listState.CurrentPageSet * listState.PageSetSize * pageSize) + (listState.CurrentPage * pageSize); 491 | int pageEndIndex = pageStartIndex + pageSize; 492 | 493 | if (index >= pageStartIndex && index < pageEndIndex && (GetElementHeight != null)) 494 | { 495 | return GetElementHeight(index, drawerState.Property, listState.Collection) + 2; 496 | } 497 | 498 | return 0; 499 | }; 500 | 501 | newList.drawFooterCallback = (Rect position) => 502 | { 503 | DrawFooterBackground(position, drawerState.Property, listState.Collection); 504 | DrawAddRemoveButtons(position, drawerState.Property, listState.Collection); 505 | 506 | Rect startPosition = position; 507 | for (var i = 0; i < DrawFooterAreaHandlers.Count; i++) 508 | { 509 | position.y += DrawFooterAreaHandlers[i].Invoke(position, drawerState.Property, listState.Collection); 510 | } 511 | 512 | position.y += DrawPageSelection(position, drawerState.Property, listState.Collection); 513 | if (listState.List.DrawCustomAdd) 514 | position.y += DrawAddArea(position, property, collection); 515 | 516 | listState.LastFooterHeight = position.y - startPosition.y; 517 | listState.LastFooterHeight += 4; 518 | List.footerHeight = listState.LastFooterHeight; 519 | }; 520 | 521 | newList.onRemoveCallback += (ReorderableList targetList) => 522 | { 523 | if (targetList.index > -1) 524 | { 525 | int pageSize = GetItemsPerPage(listState.Collection); 526 | int pageStartIndex = GetPageDisplayRange(listState.Collection).x; 527 | listState.Collection.DeleteArrayElementAtIndex(pageStartIndex + targetList.index); 528 | } 529 | }; 530 | 531 | newList.onAddCallback += (ReorderableList targetList) => 532 | { 533 | if (DrawCustomAdd) 534 | { 535 | ListStates[collectionPath].AddingElement = !ListStates[collectionPath].AddingElement; 536 | if (ListStates[collectionPath].AddingElement) 537 | SerializationReflection.CallPrivateMethod(property, "ClearTemp"); 538 | 539 | } 540 | else 541 | listState.Collection.InsertArrayElementAtIndex(listState.Collection.arraySize); 542 | }; 543 | 544 | List = newList; 545 | } 546 | 547 | private float DrawAddArea(Rect position, SerializedProperty property, SerializedProperty collection) 548 | { 549 | DisplayState state = ListStates[CollectionDisplay.GetFullPath(collection)]; 550 | if (!state.AddingElement || !collection.isExpanded) 551 | return 0; 552 | 553 | ReorderableList list = state.List.List; 554 | Rect startPosition = position; 555 | 556 | Rect labelPosition = position; 557 | 558 | labelPosition.height = EditorGUIUtility.singleLineHeight; 559 | UnityEngine.GUI.Label(labelPosition, new GUIContent("Add Element"), centeredLabelStyle); 560 | position.y += labelPosition.height; 561 | position.xMin += 20; 562 | position.xMax -= 20; 563 | 564 | if (DrawAddElement != null) 565 | position.y += DrawAddElement(position, property, collection); 566 | 567 | Rect addButtonPosition = position; 568 | addButtonPosition.xMax -= position.width * .55f; 569 | addButtonPosition.height = EditorGUIUtility.singleLineHeight; 570 | if (UnityEngine.GUI.Button(addButtonPosition, "Add")) 571 | { 572 | bool successful = true; 573 | try 574 | { 575 | SerializationReflection.CallPrivateMethod(property, "AddTemp"); 576 | } 577 | catch (Exception e) 578 | { 579 | successful = false; 580 | EditorUtility.DisplayDialog("Cannot Add to Collection", e.InnerException.Message, "Okay"); 581 | } 582 | 583 | if (successful) 584 | EndAddMode(state); 585 | } 586 | 587 | Rect cancelButtonPosition = position; 588 | cancelButtonPosition.xMin += position.width * .55f; 589 | cancelButtonPosition.height = EditorGUIUtility.singleLineHeight; 590 | if (UnityEngine.GUI.Button(cancelButtonPosition, "Cancel")) 591 | { 592 | SerializationReflection.CallPrivateMethod(property, "ClearTemp"); 593 | EndAddMode(state); 594 | state.LastAddingHeight = 0; 595 | return 0; 596 | } 597 | 598 | position.y += addButtonPosition.height; 599 | position.y += 5; 600 | 601 | state.LastAddingHeight = position.y - startPosition.y; 602 | return state.LastAddingHeight; 603 | } 604 | 605 | private void EndAddMode(DisplayState listState) 606 | { 607 | listState.AddingElement = !listState.AddingElement; 608 | UnityEngine.GUI.FocusControl(null); 609 | } 610 | #endif 611 | } 612 | } 613 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/GUI/ReorderableCollection.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: abd9aa793a78f9842a120c5577ebc5bc 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/GUI/SerializationReflection.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Reflection; 5 | using UnityEditor; 6 | 7 | namespace SerializableCollections.GUI 8 | { 9 | public static class SerializationReflection 10 | { 11 | public static void CallPrivateMethod(SerializedProperty property, string methodName) 12 | { 13 | MethodInfo method = null; 14 | BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public; 15 | object pathReference = GetPathReference(property); 16 | 17 | Type currentType = pathReference.GetType(); 18 | while (currentType != null) 19 | { 20 | method = currentType.GetMethod(methodName, flags); 21 | if (method != null) 22 | break; 23 | 24 | currentType = currentType.BaseType; 25 | } 26 | 27 | method.Invoke(pathReference, null); 28 | } 29 | 30 | public static object GetPathReference(SerializedProperty property) 31 | { 32 | BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public; 33 | PathEntry[] path = SplitPath(property.propertyPath); 34 | object currentObject = property.serializedObject.targetObject; 35 | FieldInfo currentField = null; 36 | bool isInArray = false; 37 | for (var i = 0; i < path.Length; i++) 38 | { 39 | if (path[i].FieldName == "Array") 40 | { 41 | isInArray = true; 42 | continue; 43 | } 44 | 45 | Type objectType = currentObject.GetType(); 46 | PropertyInfo indexerProperty = null; 47 | while (objectType != null) 48 | { 49 | if (path[i].FieldName == "data" && isInArray) 50 | indexerProperty = objectType.GetProperty("Item"); 51 | 52 | currentField = objectType.GetField(path[i].FieldName, flags); 53 | if (currentField != null || indexerProperty != null) 54 | break; 55 | 56 | objectType = objectType.BaseType; 57 | } 58 | 59 | if (currentField == null && indexerProperty == null) 60 | UnityEngine.Debug.Log(property.propertyPath + " - " + path[i].FieldName); 61 | 62 | if (indexerProperty != null) 63 | currentObject = indexerProperty.GetValue(currentObject, new object[] { path[i].ArrayIndex }); 64 | else 65 | currentObject = currentField.GetValue(currentObject); 66 | 67 | isInArray = false; 68 | } 69 | 70 | return currentObject; 71 | } 72 | 73 | public static KeyValuePair GetPathField(SerializedProperty property) 74 | { 75 | BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public; 76 | PathEntry[] path = SplitPath(property.propertyPath); 77 | object currentObject = property.serializedObject.targetObject; 78 | object lastObject = null; 79 | FieldInfo currentField = null; 80 | bool isInArray = false; 81 | for (var i = 0; i < path.Length; i++) 82 | { 83 | if (path[i].FieldName == "Array") 84 | { 85 | isInArray = true; 86 | continue; 87 | } 88 | 89 | if (currentObject == null) 90 | UnityEngine.Debug.Log(i); 91 | Type objectType = currentObject.GetType(); 92 | int maxDepth = 10; 93 | PropertyInfo indexerProperty = null; 94 | while (objectType != null) 95 | { 96 | if (path[i].FieldName == "data" && isInArray) 97 | indexerProperty = objectType.GetProperty("Item"); 98 | 99 | currentField = objectType.GetField(path[i].FieldName, flags); 100 | if (currentField != null || indexerProperty != null) 101 | break; 102 | 103 | objectType = objectType.BaseType; 104 | maxDepth--; 105 | if (maxDepth < 0) 106 | break; 107 | } 108 | 109 | lastObject = currentObject; 110 | if (indexerProperty != null) 111 | currentObject = indexerProperty.GetValue(currentObject, new object[] { path[i].ArrayIndex }); 112 | else 113 | currentObject = currentField.GetValue(currentObject); 114 | 115 | isInArray = false; 116 | } 117 | 118 | return new KeyValuePair(lastObject, currentField); 119 | } 120 | 121 | public static PathEntry[] SplitPath(string propertyPath) 122 | { 123 | string[] splitInput = propertyPath.Split('.'); 124 | System.Collections.Generic.List entries = new System.Collections.Generic.List(); 125 | for (var inputIndex = 0; inputIndex < splitInput.Length; inputIndex++) 126 | { 127 | int index = -1; 128 | if (splitInput[inputIndex].EndsWith("]")) 129 | { 130 | string indexString = ""; 131 | // Starting at index 5, which is the "Data[" part of the string 132 | for (var charIndex = 5; charIndex < splitInput[inputIndex].Length - 1; charIndex++) 133 | { 134 | indexString += splitInput[inputIndex][charIndex]; 135 | } 136 | int.TryParse(indexString, out index); 137 | 138 | splitInput[inputIndex] = splitInput[inputIndex].Remove(4, splitInput[inputIndex].Length - 4); 139 | } 140 | entries.Add(new PathEntry(splitInput[inputIndex], index)); 141 | } 142 | return entries.ToArray(); 143 | } 144 | 145 | public struct PathEntry 146 | { 147 | public string FieldName; 148 | public int ArrayIndex; 149 | 150 | public PathEntry(string fieldName, int arrayIndex) 151 | { 152 | FieldName = fieldName; 153 | ArrayIndex = arrayIndex; 154 | } 155 | } 156 | } 157 | } 158 | #endif -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/GUI/SerializationReflection.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ad9b9b95f01d7e24c941d90f5e9638e9 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/GUI/UsePropertyDrawer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SerializableCollections.GUI 4 | { 5 | public class UsePropertyDrawer : Attribute 6 | { 7 | public Type PropertyDrawerType; 8 | 9 | public UsePropertyDrawer(Type propertyDrawerType) 10 | { 11 | PropertyDrawerType = propertyDrawerType; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/GUI/UsePropertyDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9d1c6e3fc7338484891f095c9eb686b2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/HashSet.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | 6 | namespace SerializableCollections 7 | { 8 | #if UNITY_EDITOR 9 | [GUI.UsePropertyDrawer(typeof(GUI.HashSetDrawer))] 10 | #endif 11 | public class HashSet : SerializableCollection, ISet, ISerializationCallbackReceiver, ICollection, ICollection, IEnumerable, IEnumerable, IReadOnlyCollection 12 | { 13 | protected ISet Implementation { get; set; } 14 | [SerializeField] 15 | private System.Collections.Generic.List values = new System.Collections.Generic.List(); 16 | [SerializeField] 17 | private T value = default; 18 | #pragma warning disable 0414 19 | [SerializeField] 20 | private bool hasLostValue = false; 21 | #pragma warning restore 0414 22 | 23 | public HashSet() 24 | { 25 | Implementation = new System.Collections.Generic.HashSet(); 26 | } 27 | 28 | public HashSet(ISet implementation) 29 | { 30 | Implementation = implementation; 31 | } 32 | 33 | public HashSet(IEqualityComparer comparer) 34 | { 35 | Implementation = new System.Collections.Generic.HashSet(comparer); 36 | } 37 | 38 | public HashSet(IEnumerable collection) 39 | { 40 | ClearTemp(); 41 | } 42 | 43 | private void AddTemp() 44 | { 45 | Add(value); 46 | ClearTemp(); 47 | } 48 | 49 | private void ClearTemp() 50 | { 51 | if (!typeof(T).IsValueType && typeof(T).GetConstructor(Type.EmptyTypes) != null) 52 | value = Activator.CreateInstance(); 53 | else 54 | value = default; 55 | } 56 | 57 | public void OnBeforeSerialize() 58 | { 59 | values.Clear(); 60 | 61 | foreach (var item in Implementation) 62 | { 63 | values.Add(item); 64 | } 65 | } 66 | 67 | public void OnAfterDeserialize() 68 | { 69 | Implementation.Clear(); 70 | for (var i = 0; i < values.Count && i < values.Count; i++) 71 | { 72 | if (!Implementation.Contains(values[i])) 73 | Implementation.Add(values[i]); 74 | else 75 | { 76 | value = values[i]; 77 | hasLostValue = true; 78 | } 79 | } 80 | #if !UNITY_EDITOR 81 | values.Clear(); 82 | ClearTemp(); 83 | #endif 84 | } 85 | 86 | public int Count => Implementation.Count; 87 | public bool IsReadOnly => Implementation.IsReadOnly; 88 | 89 | public bool IsSynchronized => ((ICollection)values).IsSynchronized; 90 | 91 | public object SyncRoot => ((ICollection)values).SyncRoot; 92 | 93 | void ICollection.Add(T item) => Add(item); 94 | public virtual bool Add(T item) => Implementation.Add(item); 95 | public virtual void Clear() => Implementation.Clear(); 96 | public bool Contains(T item) => Implementation.Contains(item); 97 | public void CopyTo(T[] array, int arrayIndex) => Implementation.CopyTo(array, arrayIndex); 98 | public void ExceptWith(IEnumerable other) => Implementation.ExceptWith(other); 99 | public IEnumerator GetEnumerator() => Implementation.GetEnumerator(); 100 | IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); 101 | public void IntersectWith(IEnumerable other) => Implementation.IntersectWith(other); 102 | public bool IsProperSubsetOf(IEnumerable other) => Implementation.IsProperSubsetOf(other); 103 | public bool IsProperSupersetOf(IEnumerable other) => Implementation.IsProperSupersetOf(other); 104 | public bool IsSubsetOf(IEnumerable other) => Implementation.IsSubsetOf(other); 105 | public bool IsSupersetOf(IEnumerable other) => Implementation.IsSupersetOf(other); 106 | public bool Overlaps(IEnumerable other) => Implementation.Overlaps(other); 107 | public virtual bool Remove(T item) => Implementation.Remove(item); 108 | public virtual int RemoveWhere(Predicate match) 109 | { 110 | System.Collections.Generic.HashSet removals = new System.Collections.Generic.HashSet(); 111 | foreach (var item in Implementation) 112 | if (match.Invoke(item)) 113 | removals.Add(item); 114 | 115 | int removeCount = removals.Count; 116 | foreach (var item in removals) 117 | Implementation.Remove(item); 118 | 119 | return removeCount; 120 | } 121 | public bool SetEquals(IEnumerable other) => Implementation.SetEquals(other); 122 | public void SymmetricExceptWith(IEnumerable other) => Implementation.SymmetricExceptWith(other); 123 | public void UnionWith(IEnumerable other) => Implementation.UnionWith(other); 124 | 125 | public void CopyTo(Array array, int index) 126 | { 127 | ((ICollection)values).CopyTo(array, index); 128 | } 129 | } 130 | } -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/HashSet.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b1f61ab1764e2604cbf89a198598ccc1 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/LinkedList.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | 6 | namespace SerializableCollections 7 | { 8 | #if UNITY_EDITOR 9 | [GUI.UsePropertyDrawer(typeof(GUI.LinkedListDrawer))] 10 | #endif 11 | public class LinkedList : SerializableCollection, ISerializationCallbackReceiver, ICollection, IEnumerable, IEnumerable, IReadOnlyCollection, ICollection 12 | { 13 | private System.Collections.Generic.LinkedList linkedList = new System.Collections.Generic.LinkedList(); 14 | [SerializeField] 15 | private System.Collections.Generic.List values = new System.Collections.Generic.List(); 16 | 17 | [SerializeField] 18 | private T value; 19 | 20 | public LinkedList() 21 | { 22 | linkedList = new System.Collections.Generic.LinkedList(); 23 | } 24 | 25 | public LinkedList(IEnumerable collection) 26 | { 27 | linkedList = new System.Collections.Generic.LinkedList(collection); 28 | } 29 | 30 | private void AddTemp() 31 | { 32 | linkedList.AddLast(value); 33 | ClearTemp(); 34 | } 35 | 36 | private void ClearTemp() 37 | { 38 | value = default; 39 | } 40 | 41 | public void OnBeforeSerialize() 42 | { 43 | values.Clear(); 44 | 45 | foreach (var value in linkedList) 46 | { 47 | values.Add(value); 48 | } 49 | } 50 | 51 | public void OnAfterDeserialize() 52 | { 53 | linkedList.Clear(); 54 | for (var i = 0; i < values.Count && i < values.Count; i++) 55 | { 56 | if (!linkedList.Contains(values[i])) 57 | linkedList.AddLast(values[i]); 58 | } 59 | 60 | } 61 | 62 | public int Count => linkedList.Count; 63 | public bool IsReadOnly => ((ICollection)linkedList).IsReadOnly; 64 | public bool IsSynchronized => ((ICollection)linkedList).IsSynchronized; 65 | public object SyncRoot => ((ICollection)linkedList).SyncRoot; 66 | 67 | public void Add(T value) => linkedList.AddLast(value); 68 | public LinkedListNode AddAfter(LinkedListNode node, T value) => linkedList.AddAfter(node, value); 69 | public LinkedListNode AddBefore(LinkedListNode node, T value) => linkedList.AddBefore(node, value); 70 | public LinkedListNode AddFirst(T value) => linkedList.AddFirst(value); 71 | public LinkedListNode AddLast(T value) => linkedList.AddLast(value); 72 | public void Clear() => linkedList.Clear(); 73 | public bool Contains(T value) => linkedList.Contains(value); 74 | public void CopyTo(T[] array, int arrayIndex) => linkedList.CopyTo(array, arrayIndex); 75 | public void CopyTo(Array array, int index) => ((ICollection)linkedList).CopyTo(array, index); 76 | public LinkedListNode Find(T value) => linkedList.Find(value); 77 | public LinkedListNode FindLast(T value) => linkedList.FindLast(value); 78 | public IEnumerator GetEnumerator() => linkedList.GetEnumerator(); 79 | IEnumerator IEnumerable.GetEnumerator() => linkedList.GetEnumerator(); 80 | public bool Remove(T value) => linkedList.Remove(value); 81 | public void Remove(LinkedListNode node) => linkedList.Remove(node); 82 | public void RemoveFirst() => linkedList.RemoveFirst(); 83 | public void RemoveLast() => linkedList.RemoveLast(); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/LinkedList.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c1ef31e08d0f44a4cb3e52b110774078 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/List.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | 6 | namespace SerializableCollections 7 | { 8 | #if UNITY_EDITOR 9 | [GUI.UsePropertyDrawer(typeof(GUI.ListDrawer))] 10 | #endif 11 | public class List : SerializableCollection, ICollection, IEnumerable, IEnumerable, IList, IReadOnlyCollection, IReadOnlyList, ICollection 12 | { 13 | [SerializeField] 14 | private System.Collections.Generic.List values; 15 | 16 | public T this[int index] { get => (values)[index]; set => (values)[index] = value; } 17 | public int Capacity => values.Capacity; 18 | public int Count => values.Count; 19 | public bool IsReadOnly => ((IList)values).IsReadOnly; 20 | 21 | public bool IsSynchronized => ((ICollection)values).IsSynchronized; 22 | public object SyncRoot => ((ICollection)values).SyncRoot; 23 | 24 | public List() 25 | { 26 | if (values == null) 27 | values = new System.Collections.Generic.List(); 28 | } 29 | 30 | public List(IEnumerable collection) => values = new System.Collections.Generic.List(collection); 31 | public List(int capacity) => values = new System.Collections.Generic.List(capacity); 32 | 33 | public void Add(T item) => values.Add(item); 34 | public void AddRange(IEnumerable collection) => values.AddRange(collection); 35 | public int BinarySearch(T item) => values.BinarySearch(item); 36 | public int BinarySearch(T item, IComparer comparer) => values.BinarySearch(item, comparer); 37 | public int BinarySearch(int index, int count, T item, IComparer comparer) => values.BinarySearch(index, count, item, comparer); 38 | public void Clear() => values.Clear(); 39 | public bool Contains(T item) => values.Contains(item); 40 | public List ConvertAll(Converter converter) => new List(values.ConvertAll(converter)); 41 | public void CopyTo(T[] array) => values.CopyTo(array); 42 | public void CopyTo(T[] array, int arrayIndex) => values.CopyTo(array, arrayIndex); 43 | public void CopyTo(Array array, int index) => ((ICollection)values).CopyTo(array, index); 44 | public void CopyTo(int index, T[] array, int arrayIndex, int count) => values.CopyTo(index, array, arrayIndex, count); 45 | public bool Exists(Predicate match) => values.Exists(match); 46 | public T Find(Predicate match) => values.Find(match); 47 | public List FindAll(Predicate match) => new List(values.FindAll(match)); 48 | public int FindIndex(int startIndex, int count, Predicate match) => values.FindIndex(startIndex, count, match); 49 | public int FindIndex(int startIndex, Predicate match) => values.FindIndex(startIndex, match); 50 | public int FindIndex(Predicate match) => values.FindIndex(match); 51 | public T FindLast(Predicate match) => values.FindLast(match); 52 | public int FindLastIndex(int startIndex, int count, Predicate match) => values.FindLastIndex(startIndex, count, match); 53 | public int FindLastIndex(int startIndex, Predicate match) => values.FindLastIndex(startIndex, match); 54 | public int FindLastIndex(Predicate match) => values.FindLastIndex(match); 55 | public void ForEach(Action action) => values.ForEach(action); 56 | public IEnumerator GetEnumerator() => values.GetEnumerator(); 57 | IEnumerator IEnumerable.GetEnumerator() => values.GetEnumerator(); 58 | public List GetRange(int index, int count) => new List(values.GetRange(index, count)); 59 | public int IndexOf(T item, int index, int count) => values.IndexOf(item, index, count); 60 | public int IndexOf(T item, int index) => values.IndexOf(item, index); 61 | public int IndexOf(T item) => values.IndexOf(item); 62 | public void Insert(int index, T item) => values.Insert(index, item); 63 | public void InsertRange(int index, IEnumerable collection) => values.InsertRange(index, collection); 64 | public int LastIndexOf(T item) => values.LastIndexOf(item); 65 | public int LastIndexOf(T item, int index) => values.LastIndexOf(item, index); 66 | public int LastIndexOf(T item, int index, int count) => values.LastIndexOf(item, index, count); 67 | public bool Remove(T item) => values.Remove(item); 68 | public int RemoveAll(Predicate match) => values.RemoveAll(match); 69 | public void RemoveAt(int index) => values.RemoveAt(index); 70 | public void RemoveRange(int index, int count) => values.RemoveRange(index, count); 71 | public void Reverse(int index, int count) => values.Reverse(index, count); 72 | public void Reverse() => values.Reverse(); 73 | public void Sort(Comparison comparison) => values.Sort(comparison); 74 | public void Sort(int index, int count, IComparer comparer) => values.Sort(index, count, comparer); 75 | public void Sort() => values.Sort(); 76 | public void Sort(IComparer comparer) => values.Sort(comparer); 77 | public T[] ToArray() => values.ToArray(); 78 | public void TrimExcess() => values.TrimExcess(); 79 | public bool TrueForAll(Predicate match) => values.TrueForAll(match); 80 | } 81 | } -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/List.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7e7f02e29ebaaca4eb129e37774448fb 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/PackageSettings.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using UnityEditor; 4 | using System; 5 | 6 | namespace SerializableCollections 7 | { 8 | [ExecuteInEditMode] 9 | [CreateAssetMenu(menuName = "SerializableCollections Settings")] 10 | public sealed class PackageSettings : ScriptableObject 11 | { 12 | private static PackageSettings settings; 13 | public static PackageSettings Settings 14 | { 15 | get 16 | { 17 | if (settings == null) 18 | { 19 | var allSettings = AssetDatabase.FindAssets("t: PackageSettings"); 20 | if (allSettings.Length > 0) 21 | { 22 | settings = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(allSettings[0])); 23 | } 24 | else 25 | { 26 | var newSettings = CreateInstance(); 27 | AssetDatabase.CreateAsset(newSettings, "Assets/Serializable Collections Settings.asset"); 28 | settings = newSettings; 29 | } 30 | } 31 | 32 | return settings; 33 | } 34 | } 35 | 36 | [SerializeField] 37 | private ViewSettings defaultListSettings = new ViewSettings(); 38 | public ViewSettings DefaultListSettings { get { return defaultListSettings; } } 39 | 40 | [SerializeField] 41 | private ListLookup listViewSettings = new ListLookup(); 42 | public ListLookup ListViewSettings { get { return listViewSettings; } } 43 | 44 | public ViewSettings GetListSettings(SerializedProperty collection) 45 | { 46 | string collectionPath = GetCollectionPath(collection); 47 | if (collectionPath == null || !listViewSettings.ContainsKey(collectionPath)) 48 | return null; 49 | 50 | return listViewSettings[collectionPath]; 51 | } 52 | 53 | public ViewSettings AddNewSettings(SerializedProperty collection) 54 | { 55 | ViewSettings settings = new ViewSettings(DefaultListSettings); 56 | string path = GetCollectionPath(collection); 57 | if (path != null) 58 | listViewSettings.Add(GetCollectionPath(collection), settings); 59 | else 60 | return null; 61 | 62 | return settings; 63 | } 64 | 65 | private string GetCollectionPath(SerializedProperty collection) 66 | { 67 | try 68 | { 69 | return collection.serializedObject.targetObject.GetType() + "." + collection.propertyPath; 70 | } 71 | catch (Exception) 72 | { 73 | return null; 74 | } 75 | } 76 | 77 | [Serializable] 78 | public class ListLookup : Dictionary { } 79 | 80 | [Serializable] 81 | public class ViewSettings 82 | { 83 | [SerializeField] 84 | private Color color = Color.white; 85 | public Color Color { get { return color; } set { color = value; } } 86 | 87 | [SerializeField] 88 | private bool usePages = true; 89 | public bool UsePages { get { return usePages; } set { usePages = value; } } 90 | 91 | [SerializeField] 92 | private int itemsPerPage = 10; 93 | public int ItemsPerPage { get { return itemsPerPage; } set { itemsPerPage = value; } } 94 | 95 | [SerializeField] 96 | private string keyLabel = default; 97 | public string KeyLabel { get { return keyLabel; } set { keyLabel = value; } } 98 | 99 | [SerializeField] 100 | private string valueLabel = default; 101 | public string ValueLabel { get { return valueLabel; } set { valueLabel = value; } } 102 | 103 | public ViewSettings() { } 104 | public ViewSettings(ViewSettings source) 105 | { 106 | color = source.color; 107 | usePages = source.usePages; 108 | itemsPerPage = source.itemsPerPage; 109 | } 110 | } 111 | } 112 | } 113 | #endif 114 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/PackageSettings.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a46a3d68b2b260b45b177b010eba5aa9 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/Queue.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | 6 | namespace SerializableCollections 7 | { 8 | #if UNITY_EDITOR 9 | [GUI.UsePropertyDrawer(typeof(GUI.LinkedListDrawer))] 10 | #endif 11 | public class Queue : SerializableCollection, ISerializationCallbackReceiver, IEnumerable, IEnumerable, IReadOnlyCollection, ICollection 12 | { 13 | private System.Collections.Generic.Queue queue; 14 | [SerializeField] 15 | private System.Collections.Generic.List values = new System.Collections.Generic.List(); 16 | [SerializeField] 17 | private T value; 18 | 19 | private void AddTemp() 20 | { 21 | Enqueue(value); 22 | ClearTemp(); 23 | } 24 | 25 | private void ClearTemp() 26 | { 27 | value = default; 28 | } 29 | 30 | public void OnBeforeSerialize() 31 | { 32 | values.Clear(); 33 | 34 | foreach (var item in queue) 35 | { 36 | values.Add(item); 37 | } 38 | } 39 | 40 | public void OnAfterDeserialize() 41 | { 42 | queue.Clear(); 43 | 44 | for (var i = 0; i < values.Count && i < values.Count; i++) 45 | { 46 | if (!queue.Contains(values[i])) 47 | queue.Enqueue(values[i]); 48 | } 49 | } 50 | 51 | public Queue() => queue = new System.Collections.Generic.Queue(); 52 | public Queue(IEnumerable collection) => queue = new System.Collections.Generic.Queue(collection); 53 | public Queue(int capacity) => queue = new System.Collections.Generic.Queue(capacity); 54 | 55 | public void Clear() => queue.Clear(); 56 | public bool Contains(T item) => queue.Contains(item); 57 | public void CopyTo(T[] array, int arrayIndex) => queue.CopyTo(array, arrayIndex); 58 | public void CopyTo(Array array, int index) => ((ICollection)queue).CopyTo(array, index); 59 | public int Count => queue.Count; 60 | public T Dequeue() => queue.Dequeue(); 61 | public void Enqueue(T item) => queue.Enqueue(item); 62 | public IEnumerator GetEnumerator() => queue.GetEnumerator(); 63 | IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); 64 | public bool IsSynchronized => ((ICollection)queue).IsSynchronized; 65 | public T Peek() => queue.Peek(); 66 | public object SyncRoot => ((ICollection)queue).SyncRoot; 67 | public T[] ToArray => queue.ToArray(); 68 | public void TrimExcess() => queue.TrimExcess(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/Queue.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 65ab24f72ab8eaa46a5635e6d4b73715 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/SerializableCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SerializableCollections 4 | { 5 | public abstract class SerializableCollection 6 | { 7 | #if UNITY_EDITOR 8 | public SerializableCollection() 9 | { 10 | RegisterForDrawer(); 11 | } 12 | 13 | protected virtual void RegisterForDrawer() 14 | { 15 | Type currentType = GetType(); 16 | while (currentType != null) 17 | { 18 | foreach (var attribute in currentType.CustomAttributes) 19 | { 20 | if (attribute.AttributeType == typeof(GUI.UsePropertyDrawer)) 21 | { 22 | Type drawerType = attribute.ConstructorArguments[0].Value as Type; 23 | GUI.CollectionDrawer.RegisterForDrawer(drawerType, GetType()); 24 | } 25 | } 26 | 27 | currentType = currentType.BaseType; 28 | } 29 | } 30 | #endif 31 | } 32 | } -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/SerializableCollection.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4f07bb64bda130e46b0e9c00b183b914 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/SortedCollection.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SerializableCollections 4 | { 5 | public interface SortedCollection 6 | { 7 | IComparer Comparer { get; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/SortedCollection.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5d62edeca1e1b684891de20d25a93503 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/SortedDictionary.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SerializableCollections 4 | { 5 | public class SortedDictionary : Dictionary, IReadOnlyCollection>, IReadOnlyDictionary, SortedCollection 6 | { 7 | private System.Collections.Generic.SortedDictionary sortedDictionary; 8 | 9 | public SortedDictionary() 10 | { 11 | sortedDictionary = new System.Collections.Generic.SortedDictionary(); 12 | Implementation = sortedDictionary; 13 | } 14 | 15 | public SortedDictionary(IComparer comparer) 16 | { 17 | sortedDictionary = new System.Collections.Generic.SortedDictionary(comparer); 18 | Implementation = sortedDictionary; 19 | } 20 | 21 | public SortedDictionary(IDictionary dictionary) 22 | { 23 | sortedDictionary = new System.Collections.Generic.SortedDictionary(dictionary); 24 | Implementation = sortedDictionary; 25 | } 26 | 27 | public SortedDictionary(IDictionary dictionary, IComparer comparer) 28 | { 29 | sortedDictionary = new System.Collections.Generic.SortedDictionary(dictionary, comparer); 30 | Implementation = sortedDictionary; 31 | } 32 | 33 | public IComparer Comparer => sortedDictionary.Comparer; 34 | IEnumerable IReadOnlyDictionary.Keys => ((IReadOnlyDictionary)sortedDictionary).Keys; 35 | IEnumerable IReadOnlyDictionary.Values => ((IReadOnlyDictionary)sortedDictionary).Values; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/SortedDictionary.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e06f189f01e56b145bd0037083a53b50 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/SortedList.cs: -------------------------------------------------------------------------------- 1 | using SerializableCollections.GUI; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | 6 | namespace SerializableCollections 7 | { 8 | public class SortedList : Dictionary, SortedCollection 9 | { 10 | private System.Collections.Generic.SortedList sortedList; 11 | 12 | public SortedList() 13 | { 14 | sortedList = new System.Collections.Generic.SortedList(); 15 | Implementation = sortedList; 16 | } 17 | 18 | public SortedList(int capacity) 19 | { 20 | sortedList = new System.Collections.Generic.SortedList(capacity); 21 | Implementation = sortedList; 22 | } 23 | 24 | public SortedList(IDictionary dictionary) 25 | { 26 | sortedList = new System.Collections.Generic.SortedList(dictionary); 27 | Implementation = sortedList; 28 | } 29 | 30 | public SortedList(int capacity, IComparer comparer) 31 | { 32 | sortedList = new System.Collections.Generic.SortedList(capacity, comparer); 33 | Implementation = sortedList; 34 | } 35 | 36 | public SortedList(IDictionary dictionary, IComparer comparer) 37 | { 38 | sortedList = new System.Collections.Generic.SortedList(dictionary, comparer); 39 | Implementation = sortedList; 40 | } 41 | 42 | public int Capacity => sortedList.Capacity; 43 | public IComparer Comparer => sortedList.Comparer; 44 | 45 | public ValueType this[int key] => sortedList.Values[key]; 46 | public int IndexOfValue(ValueType value) => sortedList.IndexOfValue(value); 47 | public int IndexofKey(KeyType key) => sortedList.IndexOfKey(key); 48 | public void TrimExcess() => sortedList.TrimExcess(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/SortedList.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4d4928a5c330cfd4488d56b0bcee8c05 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/SortedSet.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace SerializableCollections 5 | { 6 | public class SortedSet : HashSet, SortedCollection 7 | { 8 | private System.Collections.Generic.SortedSet sortedSet; 9 | 10 | public SortedSet() { } 11 | public SortedSet(IComparer comparer) 12 | { 13 | sortedSet = new System.Collections.Generic.SortedSet(comparer); 14 | Implementation = sortedSet; 15 | } 16 | 17 | public SortedSet(IEnumerable collection) 18 | { 19 | sortedSet = new System.Collections.Generic.SortedSet(collection); 20 | Implementation = sortedSet; 21 | } 22 | 23 | public SortedSet(IEnumerable collection, IComparer comparer) 24 | { 25 | sortedSet = new System.Collections.Generic.SortedSet(collection, comparer); 26 | Implementation = sortedSet; 27 | } 28 | 29 | public SortedSet GetViewBetween(T lowerValue, T upperValue) 30 | { 31 | return new SortedSet(sortedSet.GetViewBetween(lowerValue, upperValue)); 32 | } 33 | 34 | public IComparer Comparer => sortedSet.Comparer; 35 | public T Min => sortedSet.Min; 36 | public T Max => sortedSet.Max; 37 | 38 | public void CopyTo(T[] array, int index, int count) => sortedSet.CopyTo(array, index, count); 39 | public void CopyTo(T[] array) => sortedSet.CopyTo(array); 40 | public IEnumerable Reverse() => sortedSet.Reverse(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/SortedSet.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 598183244dbb5d44c8e574c6f8a992b6 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/Stack.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | 6 | namespace SerializableCollections 7 | { 8 | #if UNITY_EDITOR 9 | [GUI.UsePropertyDrawer(typeof(GUI.LinkedListDrawer))] 10 | #endif 11 | public class Stack : SerializableCollection, ISerializationCallbackReceiver, IEnumerable, IEnumerable, IReadOnlyCollection, ICollection 12 | { 13 | private System.Collections.Generic.Stack stack = new System.Collections.Generic.Stack(); 14 | [SerializeField] 15 | private System.Collections.Generic.List values = new System.Collections.Generic.List(); 16 | [SerializeField] 17 | private T value; 18 | 19 | public bool IsSynchronized => ((ICollection)stack).IsSynchronized; 20 | public object SyncRoot => ((ICollection)stack).SyncRoot; 21 | public int Count => stack.Count; 22 | 23 | private void AddTemp() 24 | { 25 | stack.Push(value); 26 | ClearTemp(); 27 | } 28 | 29 | private void ClearTemp() 30 | { 31 | value = default; 32 | } 33 | 34 | public void OnBeforeSerialize() 35 | { 36 | values.Clear(); 37 | foreach (var item in stack) 38 | { 39 | values.Add(item); 40 | } 41 | } 42 | 43 | public void OnAfterDeserialize() 44 | { 45 | stack.Clear(); 46 | for (var i = values.Count - 1; i > -1; i--) 47 | { 48 | if (!stack.Contains(values[i])) 49 | stack.Push(values[i]); 50 | } 51 | } 52 | 53 | public virtual void Clear() => stack.Clear(); 54 | public bool Contains(T item) => stack.Contains(item); 55 | public void CopyTo(T[] array, int arrayIndex) => stack.CopyTo(array, arrayIndex); 56 | public void CopyTo(Array array, int index) => ((ICollection)stack).CopyTo(array, index); 57 | public IEnumerator GetEnumerator() => stack.GetEnumerator(); 58 | IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); 59 | public T Peek() => stack.Peek(); 60 | public virtual T Pop() => stack.Pop(); 61 | public virtual void Push(T item) => stack.Push(item); 62 | public T[] ToArray => stack.ToArray(); 63 | public void TrimExcess() => stack.TrimExcess(); 64 | } 65 | } -------------------------------------------------------------------------------- /Packages/SerializableCollections/Scripts/Stack.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bc1ff5ef7cc620f4098b7cc49973d6f2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/Serializable Collections Assembly.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SerializableCollections", 3 | "references": [], 4 | "includePlatforms": [], 5 | "excludePlatforms": [], 6 | "allowUnsafeCode": false, 7 | "overrideReferences": false, 8 | "precompiledReferences": [], 9 | "autoReferenced": true, 10 | "defineConstraints": [], 11 | "versionDefines": [], 12 | "noEngineReferences": false 13 | } -------------------------------------------------------------------------------- /Packages/SerializableCollections/Serializable Collections Assembly.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b5f3d83bdf777dc4981d914ccfe931a9 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Packages/SerializableCollections/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.daemonlair.serializablecollections", 3 | "version": "0.0.1", 4 | "displayName": "Serializable Collections", 5 | "description": "Equivalents of the data structures found in System.Collections.Generic that can be viewed in the editor and serialized by Unity.", 6 | "unity": "2017.1", 7 | "unityRelease": "5f1", 8 | "keywords": [ 9 | "collections", 10 | "dictionary", 11 | "serializable" 12 | ], 13 | "author": { 14 | "name": "Dameon Laird", 15 | "email": "dameonlair@gmail.com" 16 | }, 17 | "type": "library" 18 | } -------------------------------------------------------------------------------- /Packages/SerializableCollections/package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4e14ba1e74913734a83a38ab847115c6 3 | PackageManifestImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Packages/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "com.unity.2d.sprite": "1.0.0", 4 | "com.unity.test-framework": "1.1.3", 5 | "com.unity.ugui": "1.0.0", 6 | "com.unity.modules.ai": "1.0.0", 7 | "com.unity.modules.animation": "1.0.0", 8 | "com.unity.modules.imgui": "1.0.0", 9 | "com.unity.modules.jsonserialize": "1.0.0", 10 | "com.unity.modules.physics": "1.0.0", 11 | "com.unity.modules.physics2d": "1.0.0", 12 | "com.unity.modules.ui": "1.0.0", 13 | "com.unity.modules.uielements": "1.0.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!11 &1 4 | AudioManager: 5 | m_ObjectHideFlags: 0 6 | m_Volume: 1 7 | Rolloff Scale: 1 8 | Doppler Factor: 1 9 | Default Speaker Mode: 2 10 | m_SampleRate: 0 11 | m_DSPBufferSize: 1024 12 | m_VirtualVoiceCount: 512 13 | m_RealVoiceCount: 32 14 | m_SpatializerPlugin: 15 | m_AmbisonicDecoderPlugin: 16 | m_DisableAudio: 0 17 | m_VirtualizeEffects: 1 18 | -------------------------------------------------------------------------------- /ProjectSettings/ClusterInputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!236 &1 4 | ClusterInputManager: 5 | m_ObjectHideFlags: 0 6 | m_Inputs: [] 7 | -------------------------------------------------------------------------------- /ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!55 &1 4 | PhysicsManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 7 7 | m_Gravity: {x: 0, y: -9.81, z: 0} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_BounceThreshold: 2 10 | m_SleepThreshold: 0.005 11 | m_DefaultContactOffset: 0.01 12 | m_DefaultSolverIterations: 6 13 | m_DefaultSolverVelocityIterations: 1 14 | m_QueriesHitBackfaces: 0 15 | m_QueriesHitTriggers: 1 16 | m_EnableAdaptiveForce: 0 17 | m_ClothInterCollisionDistance: 0 18 | m_ClothInterCollisionStiffness: 0 19 | m_ContactsGeneration: 1 20 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 21 | m_AutoSimulation: 1 22 | m_AutoSyncTransforms: 0 23 | m_ReuseCollisionCallbacks: 1 24 | m_ClothInterCollisionSettingsToggle: 0 25 | m_ContactPairsMode: 0 26 | m_BroadphaseType: 0 27 | m_WorldBounds: 28 | m_Center: {x: 0, y: 0, z: 0} 29 | m_Extent: {x: 250, y: 250, z: 250} 30 | m_WorldSubdivisions: 8 31 | -------------------------------------------------------------------------------- /ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1045 &1 4 | EditorBuildSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Scenes: 8 | - enabled: 1 9 | path: Assets/Examples/ExampleScene.unity 10 | guid: 2cda990e2423bbf4892e6590ba056729 11 | m_configObjects: {} 12 | -------------------------------------------------------------------------------- /ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!159 &1 4 | EditorSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 7 7 | m_ExternalVersionControlSupport: Visible Meta Files 8 | m_SerializationMode: 2 9 | m_LineEndingsForNewScripts: 0 10 | m_DefaultBehaviorMode: 1 11 | m_SpritePackerMode: 4 12 | m_SpritePackerPaddingPower: 1 13 | m_EtcTextureCompressorBehavior: 1 14 | m_EtcTextureFastCompressor: 1 15 | m_EtcTextureNormalCompressor: 2 16 | m_EtcTextureBestCompressor: 4 17 | m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd 18 | m_ProjectGenerationRootNamespace: 19 | m_UserGeneratedProjectSuffix: 20 | m_CollabEditorSettings: 21 | inProgressEnabled: 1 22 | -------------------------------------------------------------------------------- /ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!30 &1 4 | GraphicsSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 13 7 | m_Deferred: 8 | m_Mode: 1 9 | m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} 10 | m_DeferredReflections: 11 | m_Mode: 1 12 | m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0} 13 | m_ScreenSpaceShadows: 14 | m_Mode: 1 15 | m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} 16 | m_LegacyDeferred: 17 | m_Mode: 1 18 | m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} 19 | m_DepthNormals: 20 | m_Mode: 1 21 | m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} 22 | m_MotionVectors: 23 | m_Mode: 1 24 | m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0} 25 | m_LightHalo: 26 | m_Mode: 1 27 | m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0} 28 | m_LensFlare: 29 | m_Mode: 1 30 | m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0} 31 | m_VideoShadersIncludeMode: 2 32 | m_AlwaysIncludedShaders: 33 | - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} 34 | - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0} 35 | - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0} 36 | - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0} 37 | - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} 38 | - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} 39 | - {fileID: 10783, guid: 0000000000000000f000000000000000, type: 0} 40 | m_PreloadedShaders: [] 41 | m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, 42 | type: 0} 43 | m_CustomRenderPipeline: {fileID: 0} 44 | m_TransparencySortMode: 0 45 | m_TransparencySortAxis: {x: 0, y: 0, z: 1} 46 | m_DefaultRenderingPath: 1 47 | m_DefaultMobileRenderingPath: 1 48 | m_TierSettings: [] 49 | m_LightmapStripping: 0 50 | m_FogStripping: 0 51 | m_InstancingStripping: 0 52 | m_LightmapKeepPlain: 1 53 | m_LightmapKeepDirCombined: 1 54 | m_LightmapKeepDynamicPlain: 1 55 | m_LightmapKeepDynamicDirCombined: 1 56 | m_LightmapKeepShadowMask: 1 57 | m_LightmapKeepSubtractive: 1 58 | m_FogKeepLinear: 1 59 | m_FogKeepExp: 1 60 | m_FogKeepExp2: 1 61 | m_AlbedoSwatchInfos: [] 62 | m_LightsUseLinearIntensity: 0 63 | m_LightsUseColorTemperature: 0 64 | m_LogWhenShaderIsCompiled: 0 65 | m_AllowEnlightenSupportForUpgradedProject: 1 66 | -------------------------------------------------------------------------------- /ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!13 &1 4 | InputManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Axes: 8 | - serializedVersion: 3 9 | m_Name: Horizontal 10 | descriptiveName: 11 | descriptiveNegativeName: 12 | negativeButton: left 13 | positiveButton: right 14 | altNegativeButton: a 15 | altPositiveButton: d 16 | gravity: 3 17 | dead: 0.001 18 | sensitivity: 3 19 | snap: 1 20 | invert: 0 21 | type: 0 22 | axis: 0 23 | joyNum: 0 24 | - serializedVersion: 3 25 | m_Name: Vertical 26 | descriptiveName: 27 | descriptiveNegativeName: 28 | negativeButton: down 29 | positiveButton: up 30 | altNegativeButton: s 31 | altPositiveButton: w 32 | gravity: 3 33 | dead: 0.001 34 | sensitivity: 3 35 | snap: 1 36 | invert: 0 37 | type: 0 38 | axis: 0 39 | joyNum: 0 40 | - serializedVersion: 3 41 | m_Name: Fire1 42 | descriptiveName: 43 | descriptiveNegativeName: 44 | negativeButton: 45 | positiveButton: left ctrl 46 | altNegativeButton: 47 | altPositiveButton: mouse 0 48 | gravity: 1000 49 | dead: 0.001 50 | sensitivity: 1000 51 | snap: 0 52 | invert: 0 53 | type: 0 54 | axis: 0 55 | joyNum: 0 56 | - serializedVersion: 3 57 | m_Name: Fire2 58 | descriptiveName: 59 | descriptiveNegativeName: 60 | negativeButton: 61 | positiveButton: left alt 62 | altNegativeButton: 63 | altPositiveButton: mouse 1 64 | gravity: 1000 65 | dead: 0.001 66 | sensitivity: 1000 67 | snap: 0 68 | invert: 0 69 | type: 0 70 | axis: 0 71 | joyNum: 0 72 | - serializedVersion: 3 73 | m_Name: Fire3 74 | descriptiveName: 75 | descriptiveNegativeName: 76 | negativeButton: 77 | positiveButton: left shift 78 | altNegativeButton: 79 | altPositiveButton: mouse 2 80 | gravity: 1000 81 | dead: 0.001 82 | sensitivity: 1000 83 | snap: 0 84 | invert: 0 85 | type: 0 86 | axis: 0 87 | joyNum: 0 88 | - serializedVersion: 3 89 | m_Name: Jump 90 | descriptiveName: 91 | descriptiveNegativeName: 92 | negativeButton: 93 | positiveButton: space 94 | altNegativeButton: 95 | altPositiveButton: 96 | gravity: 1000 97 | dead: 0.001 98 | sensitivity: 1000 99 | snap: 0 100 | invert: 0 101 | type: 0 102 | axis: 0 103 | joyNum: 0 104 | - serializedVersion: 3 105 | m_Name: Mouse X 106 | descriptiveName: 107 | descriptiveNegativeName: 108 | negativeButton: 109 | positiveButton: 110 | altNegativeButton: 111 | altPositiveButton: 112 | gravity: 0 113 | dead: 0 114 | sensitivity: 0.1 115 | snap: 0 116 | invert: 0 117 | type: 1 118 | axis: 0 119 | joyNum: 0 120 | - serializedVersion: 3 121 | m_Name: Mouse Y 122 | descriptiveName: 123 | descriptiveNegativeName: 124 | negativeButton: 125 | positiveButton: 126 | altNegativeButton: 127 | altPositiveButton: 128 | gravity: 0 129 | dead: 0 130 | sensitivity: 0.1 131 | snap: 0 132 | invert: 0 133 | type: 1 134 | axis: 1 135 | joyNum: 0 136 | - serializedVersion: 3 137 | m_Name: Mouse ScrollWheel 138 | descriptiveName: 139 | descriptiveNegativeName: 140 | negativeButton: 141 | positiveButton: 142 | altNegativeButton: 143 | altPositiveButton: 144 | gravity: 0 145 | dead: 0 146 | sensitivity: 0.1 147 | snap: 0 148 | invert: 0 149 | type: 1 150 | axis: 2 151 | joyNum: 0 152 | - serializedVersion: 3 153 | m_Name: Horizontal 154 | descriptiveName: 155 | descriptiveNegativeName: 156 | negativeButton: 157 | positiveButton: 158 | altNegativeButton: 159 | altPositiveButton: 160 | gravity: 0 161 | dead: 0.19 162 | sensitivity: 1 163 | snap: 0 164 | invert: 0 165 | type: 2 166 | axis: 0 167 | joyNum: 0 168 | - serializedVersion: 3 169 | m_Name: Vertical 170 | descriptiveName: 171 | descriptiveNegativeName: 172 | negativeButton: 173 | positiveButton: 174 | altNegativeButton: 175 | altPositiveButton: 176 | gravity: 0 177 | dead: 0.19 178 | sensitivity: 1 179 | snap: 0 180 | invert: 1 181 | type: 2 182 | axis: 1 183 | joyNum: 0 184 | - serializedVersion: 3 185 | m_Name: Fire1 186 | descriptiveName: 187 | descriptiveNegativeName: 188 | negativeButton: 189 | positiveButton: joystick button 0 190 | altNegativeButton: 191 | altPositiveButton: 192 | gravity: 1000 193 | dead: 0.001 194 | sensitivity: 1000 195 | snap: 0 196 | invert: 0 197 | type: 0 198 | axis: 0 199 | joyNum: 0 200 | - serializedVersion: 3 201 | m_Name: Fire2 202 | descriptiveName: 203 | descriptiveNegativeName: 204 | negativeButton: 205 | positiveButton: joystick button 1 206 | altNegativeButton: 207 | altPositiveButton: 208 | gravity: 1000 209 | dead: 0.001 210 | sensitivity: 1000 211 | snap: 0 212 | invert: 0 213 | type: 0 214 | axis: 0 215 | joyNum: 0 216 | - serializedVersion: 3 217 | m_Name: Fire3 218 | descriptiveName: 219 | descriptiveNegativeName: 220 | negativeButton: 221 | positiveButton: joystick button 2 222 | altNegativeButton: 223 | altPositiveButton: 224 | gravity: 1000 225 | dead: 0.001 226 | sensitivity: 1000 227 | snap: 0 228 | invert: 0 229 | type: 0 230 | axis: 0 231 | joyNum: 0 232 | - serializedVersion: 3 233 | m_Name: Jump 234 | descriptiveName: 235 | descriptiveNegativeName: 236 | negativeButton: 237 | positiveButton: joystick button 3 238 | altNegativeButton: 239 | altPositiveButton: 240 | gravity: 1000 241 | dead: 0.001 242 | sensitivity: 1000 243 | snap: 0 244 | invert: 0 245 | type: 0 246 | axis: 0 247 | joyNum: 0 248 | - serializedVersion: 3 249 | m_Name: Submit 250 | descriptiveName: 251 | descriptiveNegativeName: 252 | negativeButton: 253 | positiveButton: return 254 | altNegativeButton: 255 | altPositiveButton: joystick button 0 256 | gravity: 1000 257 | dead: 0.001 258 | sensitivity: 1000 259 | snap: 0 260 | invert: 0 261 | type: 0 262 | axis: 0 263 | joyNum: 0 264 | - serializedVersion: 3 265 | m_Name: Submit 266 | descriptiveName: 267 | descriptiveNegativeName: 268 | negativeButton: 269 | positiveButton: enter 270 | altNegativeButton: 271 | altPositiveButton: space 272 | gravity: 1000 273 | dead: 0.001 274 | sensitivity: 1000 275 | snap: 0 276 | invert: 0 277 | type: 0 278 | axis: 0 279 | joyNum: 0 280 | - serializedVersion: 3 281 | m_Name: Cancel 282 | descriptiveName: 283 | descriptiveNegativeName: 284 | negativeButton: 285 | positiveButton: escape 286 | altNegativeButton: 287 | altPositiveButton: joystick button 1 288 | gravity: 1000 289 | dead: 0.001 290 | sensitivity: 1000 291 | snap: 0 292 | invert: 0 293 | type: 0 294 | axis: 0 295 | joyNum: 0 296 | -------------------------------------------------------------------------------- /ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!126 &1 4 | NavMeshProjectSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | areas: 8 | - name: Walkable 9 | cost: 1 10 | - name: Not Walkable 11 | cost: 1 12 | - name: Jump 13 | cost: 2 14 | - name: 15 | cost: 1 16 | - name: 17 | cost: 1 18 | - name: 19 | cost: 1 20 | - name: 21 | cost: 1 22 | - name: 23 | cost: 1 24 | - name: 25 | cost: 1 26 | - name: 27 | cost: 1 28 | - name: 29 | cost: 1 30 | - name: 31 | cost: 1 32 | - name: 33 | cost: 1 34 | - name: 35 | cost: 1 36 | - name: 37 | cost: 1 38 | - name: 39 | cost: 1 40 | - name: 41 | cost: 1 42 | - name: 43 | cost: 1 44 | - name: 45 | cost: 1 46 | - name: 47 | cost: 1 48 | - name: 49 | cost: 1 50 | - name: 51 | cost: 1 52 | - name: 53 | cost: 1 54 | - name: 55 | cost: 1 56 | - name: 57 | cost: 1 58 | - name: 59 | cost: 1 60 | - name: 61 | cost: 1 62 | - name: 63 | cost: 1 64 | - name: 65 | cost: 1 66 | - name: 67 | cost: 1 68 | - name: 69 | cost: 1 70 | - name: 71 | cost: 1 72 | m_LastAgentTypeID: -887442657 73 | m_Settings: 74 | - serializedVersion: 2 75 | agentTypeID: 0 76 | agentRadius: 0.5 77 | agentHeight: 2 78 | agentSlope: 45 79 | agentClimb: 0.75 80 | ledgeDropHeight: 0 81 | maxJumpAcrossDistance: 0 82 | minRegionArea: 2 83 | manualCellSize: 0 84 | cellSize: 0.16666667 85 | manualTileSize: 0 86 | tileSize: 256 87 | accuratePlacement: 0 88 | debug: 89 | m_Flags: 0 90 | m_SettingNames: 91 | - Humanoid 92 | -------------------------------------------------------------------------------- /ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!149 &1 4 | NetworkManager: 5 | m_ObjectHideFlags: 0 6 | m_DebugLevel: 0 7 | m_Sendrate: 15 8 | m_AssetToPrefab: {} 9 | -------------------------------------------------------------------------------- /ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!19 &1 4 | Physics2DSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 4 7 | m_Gravity: {x: 0, y: -9.81} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_VelocityIterations: 8 10 | m_PositionIterations: 3 11 | m_VelocityThreshold: 1 12 | m_MaxLinearCorrection: 0.2 13 | m_MaxAngularCorrection: 8 14 | m_MaxTranslationSpeed: 100 15 | m_MaxRotationSpeed: 360 16 | m_BaumgarteScale: 0.2 17 | m_BaumgarteTimeOfImpactScale: 0.75 18 | m_TimeToSleep: 0.5 19 | m_LinearSleepTolerance: 0.01 20 | m_AngularSleepTolerance: 2 21 | m_DefaultContactOffset: 0.01 22 | m_JobOptions: 23 | serializedVersion: 2 24 | useMultithreading: 0 25 | useConsistencySorting: 0 26 | m_InterpolationPosesPerJob: 100 27 | m_NewContactsPerJob: 30 28 | m_CollideContactsPerJob: 100 29 | m_ClearFlagsPerJob: 200 30 | m_ClearBodyForcesPerJob: 200 31 | m_SyncDiscreteFixturesPerJob: 50 32 | m_SyncContinuousFixturesPerJob: 50 33 | m_FindNearestContactsPerJob: 100 34 | m_UpdateTriggerContactsPerJob: 100 35 | m_IslandSolverCostThreshold: 100 36 | m_IslandSolverBodyCostScale: 1 37 | m_IslandSolverContactCostScale: 10 38 | m_IslandSolverJointCostScale: 10 39 | m_IslandSolverBodiesPerJob: 50 40 | m_IslandSolverContactsPerJob: 50 41 | m_AutoSimulation: 1 42 | m_QueriesHitTriggers: 1 43 | m_QueriesStartInColliders: 1 44 | m_CallbacksOnDisable: 1 45 | m_ReuseCollisionCallbacks: 0 46 | m_AutoSyncTransforms: 0 47 | m_AlwaysShowColliders: 0 48 | m_ShowColliderSleep: 1 49 | m_ShowColliderContacts: 0 50 | m_ShowColliderAABB: 0 51 | m_ContactArrowScale: 0.2 52 | m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412} 53 | m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432} 54 | m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745} 55 | m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804} 56 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 57 | -------------------------------------------------------------------------------- /ProjectSettings/PresetManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1386491679 &1 4 | PresetManager: 5 | m_ObjectHideFlags: 0 6 | m_DefaultList: [] 7 | -------------------------------------------------------------------------------- /ProjectSettings/ProjectSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!129 &1 4 | PlayerSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 20 7 | productGUID: c3a578fac935f2b42adef9f9e2468ef4 8 | AndroidProfiler: 0 9 | AndroidFilterTouchesWhenObscured: 0 10 | AndroidEnableSustainedPerformanceMode: 0 11 | defaultScreenOrientation: 4 12 | targetDevice: 2 13 | useOnDemandResources: 0 14 | accelerometerFrequency: 60 15 | companyName: DefaultCompany 16 | productName: Serializable Collections 17 | defaultCursor: {fileID: 0} 18 | cursorHotspot: {x: 0, y: 0} 19 | m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1} 20 | m_ShowUnitySplashScreen: 1 21 | m_ShowUnitySplashLogo: 1 22 | m_SplashScreenOverlayOpacity: 1 23 | m_SplashScreenAnimation: 1 24 | m_SplashScreenLogoStyle: 1 25 | m_SplashScreenDrawMode: 0 26 | m_SplashScreenBackgroundAnimationZoom: 1 27 | m_SplashScreenLogoAnimationZoom: 1 28 | m_SplashScreenBackgroundLandscapeAspect: 1 29 | m_SplashScreenBackgroundPortraitAspect: 1 30 | m_SplashScreenBackgroundLandscapeUvs: 31 | serializedVersion: 2 32 | x: 0 33 | y: 0 34 | width: 1 35 | height: 1 36 | m_SplashScreenBackgroundPortraitUvs: 37 | serializedVersion: 2 38 | x: 0 39 | y: 0 40 | width: 1 41 | height: 1 42 | m_SplashScreenLogos: [] 43 | m_VirtualRealitySplashScreen: {fileID: 0} 44 | m_HolographicTrackingLossScreen: {fileID: 0} 45 | defaultScreenWidth: 1024 46 | defaultScreenHeight: 768 47 | defaultScreenWidthWeb: 960 48 | defaultScreenHeightWeb: 600 49 | m_StereoRenderingPath: 0 50 | m_ActiveColorSpace: 0 51 | m_MTRendering: 1 52 | m_StackTraceTypes: 010000000100000001000000010000000100000001000000 53 | iosShowActivityIndicatorOnLoading: -1 54 | androidShowActivityIndicatorOnLoading: -1 55 | iosUseCustomAppBackgroundBehavior: 0 56 | iosAllowHTTPDownload: 1 57 | allowedAutorotateToPortrait: 1 58 | allowedAutorotateToPortraitUpsideDown: 1 59 | allowedAutorotateToLandscapeRight: 1 60 | allowedAutorotateToLandscapeLeft: 1 61 | useOSAutorotation: 1 62 | use32BitDisplayBuffer: 1 63 | preserveFramebufferAlpha: 0 64 | disableDepthAndStencilBuffers: 0 65 | androidStartInFullscreen: 1 66 | androidRenderOutsideSafeArea: 1 67 | androidUseSwappy: 0 68 | androidBlitType: 0 69 | defaultIsNativeResolution: 1 70 | macRetinaSupport: 1 71 | runInBackground: 1 72 | captureSingleScreen: 0 73 | muteOtherAudioSources: 0 74 | Prepare IOS For Recording: 0 75 | Force IOS Speakers When Recording: 0 76 | deferSystemGesturesMode: 0 77 | hideHomeButton: 0 78 | submitAnalytics: 1 79 | usePlayerLog: 1 80 | bakeCollisionMeshes: 0 81 | forceSingleInstance: 0 82 | useFlipModelSwapchain: 1 83 | resizableWindow: 0 84 | useMacAppStoreValidation: 0 85 | macAppStoreCategory: public.app-category.games 86 | gpuSkinning: 0 87 | xboxPIXTextureCapture: 0 88 | xboxEnableAvatar: 0 89 | xboxEnableKinect: 0 90 | xboxEnableKinectAutoTracking: 0 91 | xboxEnableFitness: 0 92 | visibleInBackground: 1 93 | allowFullscreenSwitch: 1 94 | fullscreenMode: 1 95 | xboxSpeechDB: 0 96 | xboxEnableHeadOrientation: 0 97 | xboxEnableGuest: 0 98 | xboxEnablePIXSampling: 0 99 | metalFramebufferOnly: 0 100 | xboxOneResolution: 0 101 | xboxOneSResolution: 0 102 | xboxOneXResolution: 3 103 | xboxOneMonoLoggingLevel: 0 104 | xboxOneLoggingLevel: 1 105 | xboxOneDisableEsram: 0 106 | xboxOnePresentImmediateThreshold: 0 107 | switchQueueCommandMemory: 0 108 | switchQueueControlMemory: 16384 109 | switchQueueComputeMemory: 262144 110 | switchNVNShaderPoolsGranularity: 33554432 111 | switchNVNDefaultPoolsGranularity: 16777216 112 | switchNVNOtherPoolsGranularity: 16777216 113 | vulkanNumSwapchainBuffers: 2 114 | vulkanEnableSetSRGBWrite: 0 115 | m_SupportedAspectRatios: 116 | 4:3: 1 117 | 5:4: 1 118 | 16:10: 1 119 | 16:9: 1 120 | Others: 1 121 | bundleVersion: 0.1 122 | preloadedAssets: [] 123 | metroInputSource: 0 124 | wsaTransparentSwapchain: 0 125 | m_HolographicPauseOnTrackingLoss: 1 126 | xboxOneDisableKinectGpuReservation: 1 127 | xboxOneEnable7thCore: 1 128 | vrSettings: 129 | cardboard: 130 | depthFormat: 0 131 | enableTransitionView: 0 132 | daydream: 133 | depthFormat: 0 134 | useSustainedPerformanceMode: 0 135 | enableVideoLayer: 0 136 | useProtectedVideoMemory: 0 137 | minimumSupportedHeadTracking: 0 138 | maximumSupportedHeadTracking: 1 139 | hololens: 140 | depthFormat: 1 141 | depthBufferSharingEnabled: 1 142 | lumin: 143 | depthFormat: 0 144 | frameTiming: 2 145 | enableGLCache: 0 146 | glCacheMaxBlobSize: 524288 147 | glCacheMaxFileSize: 8388608 148 | oculus: 149 | sharedDepthBuffer: 1 150 | dashSupport: 1 151 | lowOverheadMode: 0 152 | protectedContext: 0 153 | v2Signing: 1 154 | enable360StereoCapture: 0 155 | isWsaHolographicRemotingEnabled: 0 156 | enableFrameTimingStats: 0 157 | useHDRDisplay: 0 158 | D3DHDRBitDepth: 0 159 | m_ColorGamuts: 00000000 160 | targetPixelDensity: 30 161 | resolutionScalingMode: 0 162 | androidSupportedAspectRatio: 1 163 | androidMaxAspectRatio: 2.1 164 | applicationIdentifier: 165 | Standalone: com.Company.ProductName 166 | buildNumber: {} 167 | AndroidBundleVersionCode: 1 168 | AndroidMinSdkVersion: 19 169 | AndroidTargetSdkVersion: 0 170 | AndroidPreferredInstallLocation: 1 171 | aotOptions: 172 | stripEngineCode: 1 173 | iPhoneStrippingLevel: 0 174 | iPhoneScriptCallOptimization: 0 175 | ForceInternetPermission: 0 176 | ForceSDCardPermission: 0 177 | CreateWallpaper: 0 178 | APKExpansionFiles: 0 179 | keepLoadedShadersAlive: 0 180 | StripUnusedMeshComponents: 1 181 | VertexChannelCompressionMask: 4054 182 | iPhoneSdkVersion: 988 183 | iOSTargetOSVersionString: 10.0 184 | tvOSSdkVersion: 0 185 | tvOSRequireExtendedGameController: 0 186 | tvOSTargetOSVersionString: 10.0 187 | uIPrerenderedIcon: 0 188 | uIRequiresPersistentWiFi: 0 189 | uIRequiresFullScreen: 1 190 | uIStatusBarHidden: 1 191 | uIExitOnSuspend: 0 192 | uIStatusBarStyle: 0 193 | iPhoneSplashScreen: {fileID: 0} 194 | iPhoneHighResSplashScreen: {fileID: 0} 195 | iPhoneTallHighResSplashScreen: {fileID: 0} 196 | iPhone47inSplashScreen: {fileID: 0} 197 | iPhone55inPortraitSplashScreen: {fileID: 0} 198 | iPhone55inLandscapeSplashScreen: {fileID: 0} 199 | iPhone58inPortraitSplashScreen: {fileID: 0} 200 | iPhone58inLandscapeSplashScreen: {fileID: 0} 201 | iPadPortraitSplashScreen: {fileID: 0} 202 | iPadHighResPortraitSplashScreen: {fileID: 0} 203 | iPadLandscapeSplashScreen: {fileID: 0} 204 | iPadHighResLandscapeSplashScreen: {fileID: 0} 205 | iPhone65inPortraitSplashScreen: {fileID: 0} 206 | iPhone65inLandscapeSplashScreen: {fileID: 0} 207 | iPhone61inPortraitSplashScreen: {fileID: 0} 208 | iPhone61inLandscapeSplashScreen: {fileID: 0} 209 | appleTVSplashScreen: {fileID: 0} 210 | appleTVSplashScreen2x: {fileID: 0} 211 | tvOSSmallIconLayers: [] 212 | tvOSSmallIconLayers2x: [] 213 | tvOSLargeIconLayers: [] 214 | tvOSLargeIconLayers2x: [] 215 | tvOSTopShelfImageLayers: [] 216 | tvOSTopShelfImageLayers2x: [] 217 | tvOSTopShelfImageWideLayers: [] 218 | tvOSTopShelfImageWideLayers2x: [] 219 | iOSLaunchScreenType: 0 220 | iOSLaunchScreenPortrait: {fileID: 0} 221 | iOSLaunchScreenLandscape: {fileID: 0} 222 | iOSLaunchScreenBackgroundColor: 223 | serializedVersion: 2 224 | rgba: 0 225 | iOSLaunchScreenFillPct: 100 226 | iOSLaunchScreenSize: 100 227 | iOSLaunchScreenCustomXibPath: 228 | iOSLaunchScreeniPadType: 0 229 | iOSLaunchScreeniPadImage: {fileID: 0} 230 | iOSLaunchScreeniPadBackgroundColor: 231 | serializedVersion: 2 232 | rgba: 0 233 | iOSLaunchScreeniPadFillPct: 100 234 | iOSLaunchScreeniPadSize: 100 235 | iOSLaunchScreeniPadCustomXibPath: 236 | iOSUseLaunchScreenStoryboard: 0 237 | iOSLaunchScreenCustomStoryboardPath: 238 | iOSDeviceRequirements: [] 239 | iOSURLSchemes: [] 240 | iOSBackgroundModes: 0 241 | iOSMetalForceHardShadows: 0 242 | metalEditorSupport: 1 243 | metalAPIValidation: 1 244 | iOSRenderExtraFrameOnPause: 0 245 | appleDeveloperTeamID: 246 | iOSManualSigningProvisioningProfileID: 247 | tvOSManualSigningProvisioningProfileID: 248 | iOSManualSigningProvisioningProfileType: 0 249 | tvOSManualSigningProvisioningProfileType: 0 250 | appleEnableAutomaticSigning: 0 251 | iOSRequireARKit: 0 252 | iOSAutomaticallyDetectAndAddCapabilities: 1 253 | appleEnableProMotion: 0 254 | clonedFromGUID: 5f34be1353de5cf4398729fda238591b 255 | templatePackageId: com.unity.template.2d@2.3.2 256 | templateDefaultScene: Assets/Scenes/SampleScene.unity 257 | AndroidTargetArchitectures: 1 258 | AndroidSplashScreenScale: 0 259 | androidSplashScreen: {fileID: 0} 260 | AndroidKeystoreName: '{inproject}: ' 261 | AndroidKeyaliasName: 262 | AndroidBuildApkPerCpuArchitecture: 0 263 | AndroidTVCompatibility: 0 264 | AndroidIsGame: 1 265 | AndroidEnableTango: 0 266 | androidEnableBanner: 1 267 | androidUseLowAccuracyLocation: 0 268 | androidUseCustomKeystore: 0 269 | m_AndroidBanners: 270 | - width: 320 271 | height: 180 272 | banner: {fileID: 0} 273 | androidGamepadSupportLevel: 0 274 | AndroidValidateAppBundleSize: 1 275 | AndroidAppBundleSizeToValidate: 150 276 | m_BuildTargetIcons: [] 277 | m_BuildTargetPlatformIcons: [] 278 | m_BuildTargetBatching: [] 279 | m_BuildTargetGraphicsJobs: 280 | - m_BuildTarget: MacStandaloneSupport 281 | m_GraphicsJobs: 0 282 | - m_BuildTarget: Switch 283 | m_GraphicsJobs: 0 284 | - m_BuildTarget: MetroSupport 285 | m_GraphicsJobs: 0 286 | - m_BuildTarget: AppleTVSupport 287 | m_GraphicsJobs: 0 288 | - m_BuildTarget: BJMSupport 289 | m_GraphicsJobs: 0 290 | - m_BuildTarget: LinuxStandaloneSupport 291 | m_GraphicsJobs: 0 292 | - m_BuildTarget: PS4Player 293 | m_GraphicsJobs: 0 294 | - m_BuildTarget: iOSSupport 295 | m_GraphicsJobs: 0 296 | - m_BuildTarget: WindowsStandaloneSupport 297 | m_GraphicsJobs: 0 298 | - m_BuildTarget: XboxOnePlayer 299 | m_GraphicsJobs: 0 300 | - m_BuildTarget: LuminSupport 301 | m_GraphicsJobs: 0 302 | - m_BuildTarget: AndroidPlayer 303 | m_GraphicsJobs: 0 304 | - m_BuildTarget: WebGLSupport 305 | m_GraphicsJobs: 0 306 | m_BuildTargetGraphicsJobMode: 307 | - m_BuildTarget: PS4Player 308 | m_GraphicsJobMode: 0 309 | - m_BuildTarget: XboxOnePlayer 310 | m_GraphicsJobMode: 0 311 | m_BuildTargetGraphicsAPIs: 312 | - m_BuildTarget: AndroidPlayer 313 | m_APIs: 150000000b000000 314 | m_Automatic: 0 315 | m_BuildTargetVRSettings: [] 316 | openGLRequireES31: 0 317 | openGLRequireES31AEP: 0 318 | openGLRequireES32: 0 319 | vuforiaEnabled: 0 320 | m_TemplateCustomTags: {} 321 | mobileMTRendering: 322 | Android: 1 323 | iPhone: 1 324 | tvOS: 1 325 | m_BuildTargetGroupLightmapEncodingQuality: [] 326 | m_BuildTargetGroupLightmapSettings: [] 327 | playModeTestRunnerEnabled: 0 328 | runPlayModeTestAsEditModeTest: 0 329 | actionOnDotNetUnhandledException: 1 330 | enableInternalProfiler: 0 331 | logObjCUncaughtExceptions: 1 332 | enableCrashReportAPI: 0 333 | cameraUsageDescription: 334 | locationUsageDescription: 335 | microphoneUsageDescription: 336 | switchNetLibKey: 337 | switchSocketMemoryPoolSize: 6144 338 | switchSocketAllocatorPoolSize: 128 339 | switchSocketConcurrencyLimit: 14 340 | switchScreenResolutionBehavior: 2 341 | switchUseCPUProfiler: 0 342 | switchApplicationID: 0x01004b9000490000 343 | switchNSODependencies: 344 | switchTitleNames_0: 345 | switchTitleNames_1: 346 | switchTitleNames_2: 347 | switchTitleNames_3: 348 | switchTitleNames_4: 349 | switchTitleNames_5: 350 | switchTitleNames_6: 351 | switchTitleNames_7: 352 | switchTitleNames_8: 353 | switchTitleNames_9: 354 | switchTitleNames_10: 355 | switchTitleNames_11: 356 | switchTitleNames_12: 357 | switchTitleNames_13: 358 | switchTitleNames_14: 359 | switchPublisherNames_0: 360 | switchPublisherNames_1: 361 | switchPublisherNames_2: 362 | switchPublisherNames_3: 363 | switchPublisherNames_4: 364 | switchPublisherNames_5: 365 | switchPublisherNames_6: 366 | switchPublisherNames_7: 367 | switchPublisherNames_8: 368 | switchPublisherNames_9: 369 | switchPublisherNames_10: 370 | switchPublisherNames_11: 371 | switchPublisherNames_12: 372 | switchPublisherNames_13: 373 | switchPublisherNames_14: 374 | switchIcons_0: {fileID: 0} 375 | switchIcons_1: {fileID: 0} 376 | switchIcons_2: {fileID: 0} 377 | switchIcons_3: {fileID: 0} 378 | switchIcons_4: {fileID: 0} 379 | switchIcons_5: {fileID: 0} 380 | switchIcons_6: {fileID: 0} 381 | switchIcons_7: {fileID: 0} 382 | switchIcons_8: {fileID: 0} 383 | switchIcons_9: {fileID: 0} 384 | switchIcons_10: {fileID: 0} 385 | switchIcons_11: {fileID: 0} 386 | switchIcons_12: {fileID: 0} 387 | switchIcons_13: {fileID: 0} 388 | switchIcons_14: {fileID: 0} 389 | switchSmallIcons_0: {fileID: 0} 390 | switchSmallIcons_1: {fileID: 0} 391 | switchSmallIcons_2: {fileID: 0} 392 | switchSmallIcons_3: {fileID: 0} 393 | switchSmallIcons_4: {fileID: 0} 394 | switchSmallIcons_5: {fileID: 0} 395 | switchSmallIcons_6: {fileID: 0} 396 | switchSmallIcons_7: {fileID: 0} 397 | switchSmallIcons_8: {fileID: 0} 398 | switchSmallIcons_9: {fileID: 0} 399 | switchSmallIcons_10: {fileID: 0} 400 | switchSmallIcons_11: {fileID: 0} 401 | switchSmallIcons_12: {fileID: 0} 402 | switchSmallIcons_13: {fileID: 0} 403 | switchSmallIcons_14: {fileID: 0} 404 | switchManualHTML: 405 | switchAccessibleURLs: 406 | switchLegalInformation: 407 | switchMainThreadStackSize: 1048576 408 | switchPresenceGroupId: 409 | switchLogoHandling: 0 410 | switchReleaseVersion: 0 411 | switchDisplayVersion: 1.0.0 412 | switchStartupUserAccount: 0 413 | switchTouchScreenUsage: 0 414 | switchSupportedLanguagesMask: 0 415 | switchLogoType: 0 416 | switchApplicationErrorCodeCategory: 417 | switchUserAccountSaveDataSize: 0 418 | switchUserAccountSaveDataJournalSize: 0 419 | switchApplicationAttribute: 0 420 | switchCardSpecSize: -1 421 | switchCardSpecClock: -1 422 | switchRatingsMask: 0 423 | switchRatingsInt_0: 0 424 | switchRatingsInt_1: 0 425 | switchRatingsInt_2: 0 426 | switchRatingsInt_3: 0 427 | switchRatingsInt_4: 0 428 | switchRatingsInt_5: 0 429 | switchRatingsInt_6: 0 430 | switchRatingsInt_7: 0 431 | switchRatingsInt_8: 0 432 | switchRatingsInt_9: 0 433 | switchRatingsInt_10: 0 434 | switchRatingsInt_11: 0 435 | switchLocalCommunicationIds_0: 436 | switchLocalCommunicationIds_1: 437 | switchLocalCommunicationIds_2: 438 | switchLocalCommunicationIds_3: 439 | switchLocalCommunicationIds_4: 440 | switchLocalCommunicationIds_5: 441 | switchLocalCommunicationIds_6: 442 | switchLocalCommunicationIds_7: 443 | switchParentalControl: 0 444 | switchAllowsScreenshot: 1 445 | switchAllowsVideoCapturing: 1 446 | switchAllowsRuntimeAddOnContentInstall: 0 447 | switchDataLossConfirmation: 0 448 | switchUserAccountLockEnabled: 0 449 | switchSystemResourceMemory: 16777216 450 | switchSupportedNpadStyles: 3 451 | switchNativeFsCacheSize: 32 452 | switchIsHoldTypeHorizontal: 0 453 | switchSupportedNpadCount: 8 454 | switchSocketConfigEnabled: 0 455 | switchTcpInitialSendBufferSize: 32 456 | switchTcpInitialReceiveBufferSize: 64 457 | switchTcpAutoSendBufferSizeMax: 256 458 | switchTcpAutoReceiveBufferSizeMax: 256 459 | switchUdpSendBufferSize: 9 460 | switchUdpReceiveBufferSize: 42 461 | switchSocketBufferEfficiency: 4 462 | switchSocketInitializeEnabled: 1 463 | switchNetworkInterfaceManagerInitializeEnabled: 1 464 | switchPlayerConnectionEnabled: 1 465 | ps4NPAgeRating: 12 466 | ps4NPTitleSecret: 467 | ps4NPTrophyPackPath: 468 | ps4ParentalLevel: 11 469 | ps4ContentID: ED1633-NPXX51362_00-0000000000000000 470 | ps4Category: 0 471 | ps4MasterVersion: 01.00 472 | ps4AppVersion: 01.00 473 | ps4AppType: 0 474 | ps4ParamSfxPath: 475 | ps4VideoOutPixelFormat: 0 476 | ps4VideoOutInitialWidth: 1920 477 | ps4VideoOutBaseModeInitialWidth: 1920 478 | ps4VideoOutReprojectionRate: 60 479 | ps4PronunciationXMLPath: 480 | ps4PronunciationSIGPath: 481 | ps4BackgroundImagePath: 482 | ps4StartupImagePath: 483 | ps4StartupImagesFolder: 484 | ps4IconImagesFolder: 485 | ps4SaveDataImagePath: 486 | ps4SdkOverride: 487 | ps4BGMPath: 488 | ps4ShareFilePath: 489 | ps4ShareOverlayImagePath: 490 | ps4PrivacyGuardImagePath: 491 | ps4NPtitleDatPath: 492 | ps4RemotePlayKeyAssignment: -1 493 | ps4RemotePlayKeyMappingDir: 494 | ps4PlayTogetherPlayerCount: 0 495 | ps4EnterButtonAssignment: 1 496 | ps4ApplicationParam1: 0 497 | ps4ApplicationParam2: 0 498 | ps4ApplicationParam3: 0 499 | ps4ApplicationParam4: 0 500 | ps4DownloadDataSize: 0 501 | ps4GarlicHeapSize: 2048 502 | ps4ProGarlicHeapSize: 2560 503 | playerPrefsMaxSize: 32768 504 | ps4Passcode: frAQBc8Wsa1xVPfvJcrgRYwTiizs2trQ 505 | ps4pnSessions: 1 506 | ps4pnPresence: 1 507 | ps4pnFriends: 1 508 | ps4pnGameCustomData: 1 509 | playerPrefsSupport: 0 510 | enableApplicationExit: 0 511 | resetTempFolder: 1 512 | restrictedAudioUsageRights: 0 513 | ps4UseResolutionFallback: 0 514 | ps4ReprojectionSupport: 0 515 | ps4UseAudio3dBackend: 0 516 | ps4SocialScreenEnabled: 0 517 | ps4ScriptOptimizationLevel: 0 518 | ps4Audio3dVirtualSpeakerCount: 14 519 | ps4attribCpuUsage: 0 520 | ps4PatchPkgPath: 521 | ps4PatchLatestPkgPath: 522 | ps4PatchChangeinfoPath: 523 | ps4PatchDayOne: 0 524 | ps4attribUserManagement: 0 525 | ps4attribMoveSupport: 0 526 | ps4attrib3DSupport: 0 527 | ps4attribShareSupport: 0 528 | ps4attribExclusiveVR: 0 529 | ps4disableAutoHideSplash: 0 530 | ps4videoRecordingFeaturesUsed: 0 531 | ps4contentSearchFeaturesUsed: 0 532 | ps4attribEyeToEyeDistanceSettingVR: 0 533 | ps4IncludedModules: [] 534 | monoEnv: 535 | splashScreenBackgroundSourceLandscape: {fileID: 0} 536 | splashScreenBackgroundSourcePortrait: {fileID: 0} 537 | blurSplashScreenBackground: 1 538 | spritePackerPolicy: 539 | webGLMemorySize: 16 540 | webGLExceptionSupport: 1 541 | webGLNameFilesAsHashes: 0 542 | webGLDataCaching: 1 543 | webGLDebugSymbols: 0 544 | webGLEmscriptenArgs: 545 | webGLModulesDirectory: 546 | webGLTemplate: APPLICATION:Default 547 | webGLAnalyzeBuildSize: 0 548 | webGLUseEmbeddedResources: 0 549 | webGLCompressionFormat: 1 550 | webGLLinkerTarget: 1 551 | webGLThreadsSupport: 0 552 | webGLDecompressionFallback: 0 553 | scriptingDefineSymbols: {} 554 | platformArchitecture: {} 555 | scriptingBackend: {} 556 | il2cppCompilerConfiguration: {} 557 | managedStrippingLevel: {} 558 | incrementalIl2cppBuild: {} 559 | allowUnsafeCode: 0 560 | additionalIl2CppArgs: 561 | scriptingRuntimeVersion: 1 562 | gcIncremental: 0 563 | gcWBarrierValidation: 0 564 | apiCompatibilityLevelPerPlatform: 565 | Standalone: 3 566 | m_RenderingPath: 1 567 | m_MobileRenderingPath: 1 568 | metroPackageName: Template_2D 569 | metroPackageVersion: 570 | metroCertificatePath: 571 | metroCertificatePassword: 572 | metroCertificateSubject: 573 | metroCertificateIssuer: 574 | metroCertificateNotAfter: 0000000000000000 575 | metroApplicationDescription: Template_2D 576 | wsaImages: {} 577 | metroTileShortName: 578 | metroTileShowName: 0 579 | metroMediumTileShowName: 0 580 | metroLargeTileShowName: 0 581 | metroWideTileShowName: 0 582 | metroSupportStreamingInstall: 0 583 | metroLastRequiredScene: 0 584 | metroDefaultTileSize: 1 585 | metroTileForegroundText: 2 586 | metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0} 587 | metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, 588 | a: 1} 589 | metroSplashScreenUseBackgroundColor: 0 590 | platformCapabilities: {} 591 | metroTargetDeviceFamilies: {} 592 | metroFTAName: 593 | metroFTAFileTypes: [] 594 | metroProtocolName: 595 | XboxOneProductId: 596 | XboxOneUpdateKey: 597 | XboxOneSandboxId: 598 | XboxOneContentId: 599 | XboxOneTitleId: 600 | XboxOneSCId: 601 | XboxOneGameOsOverridePath: 602 | XboxOnePackagingOverridePath: 603 | XboxOneAppManifestOverridePath: 604 | XboxOneVersion: 1.0.0.0 605 | XboxOnePackageEncryption: 0 606 | XboxOnePackageUpdateGranularity: 2 607 | XboxOneDescription: 608 | XboxOneLanguage: 609 | - enus 610 | XboxOneCapability: [] 611 | XboxOneGameRating: {} 612 | XboxOneIsContentPackage: 0 613 | XboxOneEnableGPUVariability: 1 614 | XboxOneSockets: {} 615 | XboxOneSplashScreen: {fileID: 0} 616 | XboxOneAllowedProductIds: [] 617 | XboxOnePersistentLocalStorageSize: 0 618 | XboxOneXTitleMemory: 8 619 | XboxOneOverrideIdentityName: 620 | vrEditorSettings: 621 | daydream: 622 | daydreamIconForeground: {fileID: 0} 623 | daydreamIconBackground: {fileID: 0} 624 | cloudServicesEnabled: 625 | UNet: 1 626 | luminIcon: 627 | m_Name: 628 | m_ModelFolderPath: 629 | m_PortalFolderPath: 630 | luminCert: 631 | m_CertPath: 632 | m_SignPackage: 1 633 | luminIsChannelApp: 0 634 | luminVersion: 635 | m_VersionCode: 1 636 | m_VersionName: 637 | apiCompatibilityLevel: 6 638 | cloudProjectId: 639 | framebufferDepthMemorylessMode: 0 640 | projectName: 641 | organizationId: 642 | cloudEnabled: 0 643 | enableNativePlatformBackendsForNewInputSystem: 0 644 | disableOldInputManagerSupport: 0 645 | legacyClampBlendShapeWeights: 0 646 | -------------------------------------------------------------------------------- /ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 2020.1.0a7 2 | m_EditorVersionWithRevision: 2020.1.0a7 (d3d2f5b1d33e) 3 | -------------------------------------------------------------------------------- /ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!47 &1 4 | QualitySettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 5 7 | m_CurrentQuality: 3 8 | m_QualitySettings: 9 | - serializedVersion: 2 10 | name: Very Low 11 | pixelLightCount: 0 12 | shadows: 0 13 | shadowResolution: 0 14 | shadowProjection: 1 15 | shadowCascades: 1 16 | shadowDistance: 15 17 | shadowNearPlaneOffset: 3 18 | shadowCascade2Split: 0.33333334 19 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 20 | shadowmaskMode: 0 21 | blendWeights: 1 22 | textureQuality: 1 23 | anisotropicTextures: 0 24 | antiAliasing: 0 25 | softParticles: 0 26 | softVegetation: 0 27 | realtimeReflectionProbes: 0 28 | billboardsFaceCameraPosition: 0 29 | vSyncCount: 0 30 | lodBias: 0.3 31 | maximumLODLevel: 0 32 | particleRaycastBudget: 4 33 | asyncUploadTimeSlice: 2 34 | asyncUploadBufferSize: 16 35 | resolutionScalingFixedDPIFactor: 1 36 | excludedTargetPlatforms: [] 37 | - serializedVersion: 2 38 | name: Low 39 | pixelLightCount: 0 40 | shadows: 0 41 | shadowResolution: 0 42 | shadowProjection: 1 43 | shadowCascades: 1 44 | shadowDistance: 20 45 | shadowNearPlaneOffset: 3 46 | shadowCascade2Split: 0.33333334 47 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 48 | shadowmaskMode: 0 49 | blendWeights: 2 50 | textureQuality: 0 51 | anisotropicTextures: 0 52 | antiAliasing: 0 53 | softParticles: 0 54 | softVegetation: 0 55 | realtimeReflectionProbes: 0 56 | billboardsFaceCameraPosition: 0 57 | vSyncCount: 0 58 | lodBias: 0.4 59 | maximumLODLevel: 0 60 | particleRaycastBudget: 16 61 | asyncUploadTimeSlice: 2 62 | asyncUploadBufferSize: 16 63 | resolutionScalingFixedDPIFactor: 1 64 | excludedTargetPlatforms: [] 65 | - serializedVersion: 2 66 | name: Medium 67 | pixelLightCount: 1 68 | shadows: 0 69 | shadowResolution: 0 70 | shadowProjection: 1 71 | shadowCascades: 1 72 | shadowDistance: 20 73 | shadowNearPlaneOffset: 3 74 | shadowCascade2Split: 0.33333334 75 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 76 | shadowmaskMode: 0 77 | blendWeights: 2 78 | textureQuality: 0 79 | anisotropicTextures: 0 80 | antiAliasing: 0 81 | softParticles: 0 82 | softVegetation: 0 83 | realtimeReflectionProbes: 0 84 | billboardsFaceCameraPosition: 0 85 | vSyncCount: 1 86 | lodBias: 0.7 87 | maximumLODLevel: 0 88 | particleRaycastBudget: 64 89 | asyncUploadTimeSlice: 2 90 | asyncUploadBufferSize: 16 91 | resolutionScalingFixedDPIFactor: 1 92 | excludedTargetPlatforms: [] 93 | - serializedVersion: 2 94 | name: High 95 | pixelLightCount: 2 96 | shadows: 0 97 | shadowResolution: 1 98 | shadowProjection: 1 99 | shadowCascades: 2 100 | shadowDistance: 40 101 | shadowNearPlaneOffset: 3 102 | shadowCascade2Split: 0.33333334 103 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 104 | shadowmaskMode: 1 105 | blendWeights: 2 106 | textureQuality: 0 107 | anisotropicTextures: 0 108 | antiAliasing: 0 109 | softParticles: 0 110 | softVegetation: 1 111 | realtimeReflectionProbes: 0 112 | billboardsFaceCameraPosition: 0 113 | vSyncCount: 1 114 | lodBias: 1 115 | maximumLODLevel: 0 116 | particleRaycastBudget: 256 117 | asyncUploadTimeSlice: 2 118 | asyncUploadBufferSize: 16 119 | resolutionScalingFixedDPIFactor: 1 120 | excludedTargetPlatforms: [] 121 | - serializedVersion: 2 122 | name: Very High 123 | pixelLightCount: 3 124 | shadows: 0 125 | shadowResolution: 2 126 | shadowProjection: 1 127 | shadowCascades: 2 128 | shadowDistance: 70 129 | shadowNearPlaneOffset: 3 130 | shadowCascade2Split: 0.33333334 131 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 132 | shadowmaskMode: 1 133 | blendWeights: 4 134 | textureQuality: 0 135 | anisotropicTextures: 0 136 | antiAliasing: 0 137 | softParticles: 0 138 | softVegetation: 1 139 | realtimeReflectionProbes: 0 140 | billboardsFaceCameraPosition: 0 141 | vSyncCount: 1 142 | lodBias: 1.5 143 | maximumLODLevel: 0 144 | particleRaycastBudget: 1024 145 | asyncUploadTimeSlice: 2 146 | asyncUploadBufferSize: 16 147 | resolutionScalingFixedDPIFactor: 1 148 | excludedTargetPlatforms: [] 149 | - serializedVersion: 2 150 | name: Ultra 151 | pixelLightCount: 4 152 | shadows: 0 153 | shadowResolution: 0 154 | shadowProjection: 1 155 | shadowCascades: 4 156 | shadowDistance: 150 157 | shadowNearPlaneOffset: 3 158 | shadowCascade2Split: 0.33333334 159 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 160 | shadowmaskMode: 1 161 | blendWeights: 4 162 | textureQuality: 0 163 | anisotropicTextures: 0 164 | antiAliasing: 0 165 | softParticles: 0 166 | softVegetation: 1 167 | realtimeReflectionProbes: 0 168 | billboardsFaceCameraPosition: 0 169 | vSyncCount: 1 170 | lodBias: 2 171 | maximumLODLevel: 0 172 | particleRaycastBudget: 4096 173 | asyncUploadTimeSlice: 2 174 | asyncUploadBufferSize: 16 175 | resolutionScalingFixedDPIFactor: 1 176 | excludedTargetPlatforms: [] 177 | m_PerPlatformDefaultQuality: 178 | Android: 2 179 | Nintendo 3DS: 5 180 | Nintendo Switch: 5 181 | PS4: 5 182 | PSM: 5 183 | PSP2: 2 184 | Standalone: 5 185 | Tizen: 2 186 | WebGL: 3 187 | WiiU: 5 188 | Windows Store Apps: 5 189 | XboxOne: 5 190 | iPhone: 2 191 | tvOS: 2 192 | -------------------------------------------------------------------------------- /ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!78 &1 4 | TagManager: 5 | serializedVersion: 2 6 | tags: [] 7 | layers: 8 | - Default 9 | - TransparentFX 10 | - Ignore Raycast 11 | - 12 | - Water 13 | - UI 14 | - 15 | - 16 | - 17 | - 18 | - 19 | - 20 | - 21 | - 22 | - 23 | - 24 | - 25 | - 26 | - 27 | - 28 | - 29 | - 30 | - 31 | - 32 | - 33 | - 34 | - 35 | - 36 | - 37 | - 38 | - 39 | - 40 | m_SortingLayers: 41 | - name: Default 42 | uniqueID: 0 43 | locked: 0 44 | -------------------------------------------------------------------------------- /ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!5 &1 4 | TimeManager: 5 | m_ObjectHideFlags: 0 6 | Fixed Timestep: 0.02 7 | Maximum Allowed Timestep: 0.1 8 | m_TimeScale: 1 9 | Maximum Particle Timestep: 0.03 10 | -------------------------------------------------------------------------------- /ProjectSettings/UnityConnectSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!310 &1 4 | UnityConnectSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 1 7 | m_Enabled: 0 8 | m_TestMode: 0 9 | m_EventOldUrl: https://api.uca.cloud.unity3d.com/v1/events 10 | m_EventUrl: https://cdp.cloud.unity3d.com/v1/events 11 | m_ConfigUrl: https://config.uca.cloud.unity3d.com 12 | m_TestInitMode: 0 13 | CrashReportingSettings: 14 | m_EventUrl: https://perf-events.cloud.unity3d.com 15 | m_Enabled: 0 16 | m_LogBufferSize: 10 17 | m_CaptureEditorExceptions: 1 18 | UnityPurchasingSettings: 19 | m_Enabled: 0 20 | m_TestMode: 0 21 | UnityAnalyticsSettings: 22 | m_Enabled: 0 23 | m_TestMode: 0 24 | m_InitializeOnStartup: 1 25 | UnityAdsSettings: 26 | m_Enabled: 0 27 | m_InitializeOnStartup: 1 28 | m_TestMode: 0 29 | m_IosGameId: 30 | m_AndroidGameId: 31 | m_GameIds: {} 32 | m_GameId: 33 | PerformanceReportingSettings: 34 | m_Enabled: 0 35 | -------------------------------------------------------------------------------- /ProjectSettings/VFXManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!937362698 &1 4 | VFXManager: 5 | m_ObjectHideFlags: 0 6 | m_IndirectShader: {fileID: 0} 7 | m_RenderPipeSettingsPath: 8 | -------------------------------------------------------------------------------- /ProjectSettings/XRSettings.asset: -------------------------------------------------------------------------------- 1 | { 2 | "m_SettingKeys": [ 3 | "VR Device Disabled", 4 | "VR Device User Alert" 5 | ], 6 | "m_SettingValues": [ 7 | "False", 8 | "False" 9 | ] 10 | } -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | Serializable Collections for Unity gives you versions of all the collections in 2 | the .NET System.Collections.Generic namespace. Each of these collections is, as 3 | nearly as possible, a 1:1 version of the collection it's based on; meaning that 4 | you can work with them exactly as you would the normal collection. 5 | 6 | Installation: 7 | 8 | If installing from the repository, copy the SerializableCollections folder from 9 | inside the Packages folder to your project's Packages folder. Then, add the 10 | package using Unity's Package Manager window. 11 | 12 | Usage: 13 | 14 | Mostly, you can use these collections exactly as they're documented on the MSDN 15 | web page (https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic). 16 | The only major difference is that, due to the way Unity handles serialization, 17 | you need to declare a concrete class which makes use of these generics. So, 18 | for example, rather than doing this: 19 | ```cs 20 | private List listOfStrings = new List(); 21 | ``` 22 | You would do this: 23 | ```cs 24 | [Serializable] 25 | public class StringList : List {} 26 | private StringList listOfStrings = new StringList(); 27 | ``` 28 | You can create your classes inside the class you're working in, or you can 29 | create them in their own file for the rest of your program to take advantage 30 | of. 31 | -------------------------------------------------------------------------------- /UserSettings/EditorUserSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DameonL/Serializable-Collections-For-Unity/2c9e5759736c7814dd0564a1eea12a581a6b90a5/UserSettings/EditorUserSettings.asset --------------------------------------------------------------------------------