├── .gitignore ├── Assets ├── Scenes.meta ├── Scenes │ ├── SpriteBatcherJobifiedTest.unity │ ├── SpriteBatcherJobifiedTest.unity.meta │ ├── SpriteBatcherTest.unity │ └── SpriteBatcherTest.unity.meta ├── Scripts.meta ├── Scripts │ ├── Interpolation.cs │ ├── Interpolation.cs.meta │ ├── Jobified.meta │ ├── Jobified │ │ ├── IRenderable.cs │ │ ├── IRenderable.cs.meta │ │ ├── ItemsGroupInfo.cs │ │ ├── ItemsGroupInfo.cs.meta │ │ ├── RenderableJobsUtils.cs │ │ ├── RenderableJobsUtils.cs.meta │ │ ├── SimpleSpritesSimulatorJobified.cs │ │ ├── SimpleSpritesSimulatorJobified.cs.meta │ │ ├── SpriteBatchRenderSetup.cs │ │ ├── SpriteBatchRenderSetup.cs.meta │ │ ├── SpriteBatcher.cs │ │ ├── SpriteBatcher.cs.meta │ │ ├── SpriteData.cs │ │ ├── SpriteData.cs.meta │ │ ├── SpriteList.cs │ │ └── SpriteList.cs.meta │ ├── MathHelpers.cs │ ├── MathHelpers.cs.meta │ ├── SpriteBatcher.cs │ ├── SpriteBatcher.cs.meta │ ├── SpriteQuad.cs │ ├── SpriteQuad.cs.meta │ ├── Tests.meta │ ├── Tests │ │ ├── SimpleSpritesSimulator.cs │ │ └── SimpleSpritesSimulator.cs.meta │ ├── VectorTools.cs │ ├── VectorTools.cs.meta │ ├── WeightedRandomizer.cs │ └── WeightedRandomizer.cs.meta ├── Sprites.meta ├── Sprites │ ├── white_circle.png │ ├── white_circle.png.meta │ ├── white_square.png │ └── white_square.png.meta ├── TestAtlas.spriteatlas └── TestAtlas.spriteatlas.meta ├── LICENSE ├── Packages ├── manifest.json └── packages-lock.json ├── ProjectSettings ├── AudioManager.asset ├── BurstAotSettings_StandaloneWindows.json ├── ClusterInputManager.asset ├── CommonBurstAotSettings.json ├── DynamicsManager.asset ├── EditorBuildSettings.asset ├── EditorSettings.asset ├── GraphicsSettings.asset ├── InputManager.asset ├── NavMeshAreas.asset ├── NetworkManager.asset ├── PackageManagerSettings.asset ├── Physics2DSettings.asset ├── PresetManager.asset ├── ProjectSettings.asset ├── ProjectVersion.txt ├── QualitySettings.asset ├── SceneTemplateSettings.json ├── TagManager.asset ├── TimeManager.asset ├── UnityConnectSettings.asset ├── VFXManager.asset ├── VersionControlSettings.asset └── XRSettings.asset ├── README.md └── UserSettings └── EditorUserSettings.asset /.gitignore: -------------------------------------------------------------------------------- 1 | # This .gitignore file should be placed at the root of your Unity project directory 2 | # 3 | # Get latest from https://github.com/github/gitignore/blob/master/Unity.gitignore 4 | # 5 | /[Ll]ibrary/ 6 | /[Tt]emp/ 7 | /[Oo]bj/ 8 | /[Bb]uild/ 9 | /[Bb]uilds/ 10 | /[Ll]ogs/ 11 | /[Mm]emoryCaptures/ 12 | 13 | # Asset meta data should only be ignored when the corresponding asset is also ignored 14 | !/[Aa]ssets/**/*.meta 15 | 16 | # Uncomment this line if you wish to ignore the asset store tools plugin 17 | # /[Aa]ssets/AssetStoreTools* 18 | 19 | # Autogenerated Jetbrains Rider plugin 20 | [Aa]ssets/Plugins/Editor/JetBrains* 21 | 22 | # Visual Studio cache directory 23 | .vs/ 24 | 25 | # Gradle cache directory 26 | .gradle/ 27 | 28 | # Autogenerated VS/MD/Consulo solution and project files 29 | ExportedObj/ 30 | .consulo/ 31 | *.csproj 32 | *.unityproj 33 | *.sln 34 | *.suo 35 | *.tmp 36 | *.user 37 | *.userprefs 38 | *.pidb 39 | *.booproj 40 | *.svd 41 | *.pdb 42 | *.mdb 43 | *.opendb 44 | *.VC.db 45 | 46 | # Unity3D generated meta files 47 | *.pidb.meta 48 | *.pdb.meta 49 | *.mdb.meta 50 | 51 | # Unity3D generated file on crash reports 52 | sysinfo.txt 53 | 54 | # Builds 55 | *.apk 56 | *.unitypackage 57 | 58 | # Crashlytics generated file 59 | crashlytics-build.properties 60 | 61 | # Jetbrains Rider 62 | .idea/ -------------------------------------------------------------------------------- /Assets/Scenes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6a22426bb45e9f64f91440334fb120e0 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scenes/SpriteBatcherJobifiedTest.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1b5643918639bc942a7ba09890ca0f7c 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/Scenes/SpriteBatcherTest.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: 12 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: 1 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 512 79 | m_PVRBounces: 2 80 | m_PVREnvironmentSampleCount: 256 81 | m_PVREnvironmentReferencePointCount: 2048 82 | m_PVRFilteringMode: 1 83 | m_PVRDenoiserTypeDirect: 1 84 | m_PVRDenoiserTypeIndirect: 1 85 | m_PVRDenoiserTypeAO: 1 86 | m_PVRFilterTypeDirect: 0 87 | m_PVRFilterTypeIndirect: 0 88 | m_PVRFilterTypeAO: 0 89 | m_PVREnvironmentMIS: 1 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_LightingSettings: {fileID: 104539095} 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 | maxJobWorkers: 0 122 | preserveTilesOutsideBounds: 0 123 | debug: 124 | m_Flags: 0 125 | m_NavMeshData: {fileID: 0} 126 | --- !u!850595691 &104539095 127 | LightingSettings: 128 | m_ObjectHideFlags: 0 129 | m_CorrespondingSourceObject: {fileID: 0} 130 | m_PrefabInstance: {fileID: 0} 131 | m_PrefabAsset: {fileID: 0} 132 | m_Name: Settings.lighting 133 | serializedVersion: 3 134 | m_GIWorkflowMode: 1 135 | m_EnableBakedLightmaps: 0 136 | m_EnableRealtimeLightmaps: 0 137 | m_RealtimeEnvironmentLighting: 1 138 | m_BounceScale: 1 139 | m_AlbedoBoost: 1 140 | m_IndirectOutputScale: 1 141 | m_UsingShadowmask: 1 142 | m_BakeBackend: 1 143 | m_LightmapMaxSize: 1024 144 | m_BakeResolution: 40 145 | m_Padding: 2 146 | m_TextureCompression: 1 147 | m_AO: 0 148 | m_AOMaxDistance: 1 149 | m_CompAOExponent: 1 150 | m_CompAOExponentDirect: 0 151 | m_ExtractAO: 0 152 | m_MixedBakeMode: 2 153 | m_LightmapsBakeMode: 1 154 | m_FilterMode: 1 155 | m_LightmapParameters: {fileID: 15204, guid: 0000000000000000f000000000000000, type: 0} 156 | m_ExportTrainingData: 0 157 | m_TrainingDataDestination: TrainingData 158 | m_RealtimeResolution: 2 159 | m_ForceWhiteAlbedo: 0 160 | m_ForceUpdates: 0 161 | m_FinalGather: 0 162 | m_FinalGatherRayCount: 256 163 | m_FinalGatherFiltering: 1 164 | m_PVRCulling: 1 165 | m_PVRSampling: 1 166 | m_PVRDirectSampleCount: 32 167 | m_PVRSampleCount: 512 168 | m_PVREnvironmentSampleCount: 256 169 | m_PVREnvironmentReferencePointCount: 2048 170 | m_LightProbeSampleCountMultiplier: 4 171 | m_PVRBounces: 2 172 | m_PVRMinBounces: 2 173 | m_PVREnvironmentMIS: 1 174 | m_PVRFilteringMode: 1 175 | m_PVRDenoiserTypeDirect: 1 176 | m_PVRDenoiserTypeIndirect: 1 177 | m_PVRDenoiserTypeAO: 1 178 | m_PVRFilterTypeDirect: 0 179 | m_PVRFilterTypeIndirect: 0 180 | m_PVRFilterTypeAO: 0 181 | m_PVRFilteringGaussRadiusDirect: 1 182 | m_PVRFilteringGaussRadiusIndirect: 5 183 | m_PVRFilteringGaussRadiusAO: 2 184 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 185 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 186 | m_PVRFilteringAtrousPositionSigmaAO: 1 187 | --- !u!1 &1084419888 188 | GameObject: 189 | m_ObjectHideFlags: 0 190 | m_CorrespondingSourceObject: {fileID: 0} 191 | m_PrefabInstance: {fileID: 0} 192 | m_PrefabAsset: {fileID: 0} 193 | serializedVersion: 6 194 | m_Component: 195 | - component: {fileID: 1084419891} 196 | - component: {fileID: 1084419890} 197 | - component: {fileID: 1084419889} 198 | m_Layer: 0 199 | m_Name: Main Camera 200 | m_TagString: MainCamera 201 | m_Icon: {fileID: 0} 202 | m_NavMeshLayer: 0 203 | m_StaticEditorFlags: 0 204 | m_IsActive: 1 205 | --- !u!81 &1084419889 206 | AudioListener: 207 | m_ObjectHideFlags: 0 208 | m_CorrespondingSourceObject: {fileID: 0} 209 | m_PrefabInstance: {fileID: 0} 210 | m_PrefabAsset: {fileID: 0} 211 | m_GameObject: {fileID: 1084419888} 212 | m_Enabled: 1 213 | --- !u!20 &1084419890 214 | Camera: 215 | m_ObjectHideFlags: 0 216 | m_CorrespondingSourceObject: {fileID: 0} 217 | m_PrefabInstance: {fileID: 0} 218 | m_PrefabAsset: {fileID: 0} 219 | m_GameObject: {fileID: 1084419888} 220 | m_Enabled: 1 221 | serializedVersion: 2 222 | m_ClearFlags: 1 223 | m_BackGroundColor: {r: 0.26415092, g: 0.26415092, b: 0.26415092, a: 0} 224 | m_projectionMatrixMode: 1 225 | m_GateFitMode: 2 226 | m_FOVAxisMode: 0 227 | m_SensorSize: {x: 36, y: 24} 228 | m_LensShift: {x: 0, y: 0} 229 | m_FocalLength: 50 230 | m_NormalizedViewPortRect: 231 | serializedVersion: 2 232 | x: 0 233 | y: 0 234 | width: 1 235 | height: 1 236 | near clip plane: 0.3 237 | far clip plane: 1000 238 | field of view: 60 239 | orthographic: 1 240 | orthographic size: 8 241 | m_Depth: -1 242 | m_CullingMask: 243 | serializedVersion: 2 244 | m_Bits: 4294967295 245 | m_RenderingPath: -1 246 | m_TargetTexture: {fileID: 0} 247 | m_TargetDisplay: 0 248 | m_TargetEye: 3 249 | m_HDR: 1 250 | m_AllowMSAA: 1 251 | m_AllowDynamicResolution: 0 252 | m_ForceIntoRT: 0 253 | m_OcclusionCulling: 1 254 | m_StereoConvergence: 10 255 | m_StereoSeparation: 0.022 256 | --- !u!4 &1084419891 257 | Transform: 258 | m_ObjectHideFlags: 0 259 | m_CorrespondingSourceObject: {fileID: 0} 260 | m_PrefabInstance: {fileID: 0} 261 | m_PrefabAsset: {fileID: 0} 262 | m_GameObject: {fileID: 1084419888} 263 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 264 | m_LocalPosition: {x: 0, y: 0, z: -36.35} 265 | m_LocalScale: {x: 1, y: 1, z: 1} 266 | m_Children: [] 267 | m_Father: {fileID: 0} 268 | m_RootOrder: 0 269 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 270 | --- !u!1 &1449054495 271 | GameObject: 272 | m_ObjectHideFlags: 0 273 | m_CorrespondingSourceObject: {fileID: 0} 274 | m_PrefabInstance: {fileID: 0} 275 | m_PrefabAsset: {fileID: 0} 276 | serializedVersion: 6 277 | m_Component: 278 | - component: {fileID: 1449054498} 279 | - component: {fileID: 1449054497} 280 | - component: {fileID: 1449054496} 281 | - component: {fileID: 1449054500} 282 | - component: {fileID: 1449054499} 283 | m_Layer: 0 284 | m_Name: SpritesSimulator 285 | m_TagString: Untagged 286 | m_Icon: {fileID: 0} 287 | m_NavMeshLayer: 0 288 | m_StaticEditorFlags: 0 289 | m_IsActive: 1 290 | --- !u!114 &1449054496 291 | MonoBehaviour: 292 | m_ObjectHideFlags: 0 293 | m_CorrespondingSourceObject: {fileID: 0} 294 | m_PrefabInstance: {fileID: 0} 295 | m_PrefabAsset: {fileID: 0} 296 | m_GameObject: {fileID: 1449054495} 297 | m_Enabled: 1 298 | m_EditorHideFlags: 0 299 | m_Script: {fileID: 11500000, guid: 1118bd77a3876a04db7fe3aa12817e8f, type: 3} 300 | m_Name: 301 | m_EditorClassIdentifier: 302 | m_SpriteAtlas: {fileID: 4343727234628468602, guid: 2ab131f5b8bd1c145b1af2cb3467c082, 303 | type: 2} 304 | m_Color: {r: 1, g: 1, b: 1, a: 1} 305 | m_UseExtendedUVs: 0 306 | --- !u!114 &1449054497 307 | MonoBehaviour: 308 | m_ObjectHideFlags: 0 309 | m_CorrespondingSourceObject: {fileID: 0} 310 | m_PrefabInstance: {fileID: 0} 311 | m_PrefabAsset: {fileID: 0} 312 | m_GameObject: {fileID: 1449054495} 313 | m_Enabled: 1 314 | m_EditorHideFlags: 0 315 | m_Script: {fileID: 11500000, guid: 74d4637b96cdbab4b9b7b58fdc4af165, type: 3} 316 | m_Name: 317 | m_EditorClassIdentifier: 318 | m_Camera: {fileID: 1084419890} 319 | m_X_Min: -3 320 | m_X_Max: 3 321 | m_Y_Min: -3 322 | m_Y_Max: 3 323 | m_SpeedMin: 0.1 324 | m_SpeedMax: 1 325 | m_SpritesCount: 10000 326 | m_Batcher: {fileID: 1449054496} 327 | m_DebugUseFixedTimeDelta: 1 328 | --- !u!4 &1449054498 329 | Transform: 330 | m_ObjectHideFlags: 0 331 | m_CorrespondingSourceObject: {fileID: 0} 332 | m_PrefabInstance: {fileID: 0} 333 | m_PrefabAsset: {fileID: 0} 334 | m_GameObject: {fileID: 1449054495} 335 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 336 | m_LocalPosition: {x: 0, y: 0, z: 0} 337 | m_LocalScale: {x: 1, y: 1, z: 1} 338 | m_Children: [] 339 | m_Father: {fileID: 0} 340 | m_RootOrder: 1 341 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 342 | --- !u!23 &1449054499 343 | MeshRenderer: 344 | m_ObjectHideFlags: 0 345 | m_CorrespondingSourceObject: {fileID: 0} 346 | m_PrefabInstance: {fileID: 0} 347 | m_PrefabAsset: {fileID: 0} 348 | m_GameObject: {fileID: 1449054495} 349 | m_Enabled: 1 350 | m_CastShadows: 0 351 | m_ReceiveShadows: 0 352 | m_DynamicOccludee: 0 353 | m_MotionVectors: 2 354 | m_LightProbeUsage: 0 355 | m_ReflectionProbeUsage: 0 356 | m_RayTracingMode: 2 357 | m_RayTraceProcedural: 0 358 | m_RenderingLayerMask: 1 359 | m_RendererPriority: 0 360 | m_Materials: 361 | - {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0} 362 | m_StaticBatchInfo: 363 | firstSubMesh: 0 364 | subMeshCount: 0 365 | m_StaticBatchRoot: {fileID: 0} 366 | m_ProbeAnchor: {fileID: 0} 367 | m_LightProbeVolumeOverride: {fileID: 0} 368 | m_ScaleInLightmap: 1 369 | m_ReceiveGI: 1 370 | m_PreserveUVs: 0 371 | m_IgnoreNormalsForChartDetection: 0 372 | m_ImportantGI: 0 373 | m_StitchLightmapSeams: 1 374 | m_SelectedEditorRenderState: 3 375 | m_MinimumChartSize: 4 376 | m_AutoUVMaxDistance: 0.5 377 | m_AutoUVMaxAngle: 89 378 | m_LightmapParameters: {fileID: 0} 379 | m_SortingLayerID: 0 380 | m_SortingLayer: 0 381 | m_SortingOrder: 0 382 | m_AdditionalVertexStreams: {fileID: 0} 383 | --- !u!33 &1449054500 384 | MeshFilter: 385 | m_ObjectHideFlags: 0 386 | m_CorrespondingSourceObject: {fileID: 0} 387 | m_PrefabInstance: {fileID: 0} 388 | m_PrefabAsset: {fileID: 0} 389 | m_GameObject: {fileID: 1449054495} 390 | m_Mesh: {fileID: 0} 391 | -------------------------------------------------------------------------------- /Assets/Scenes/SpriteBatcherTest.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0bbba7f9fb682364cbcc8dee0e5470d7 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4632c3038aab80d449f91997e8070538 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scripts/Interpolation.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | namespace vadersb.utils 6 | { 7 | public static class Interpolation 8 | { 9 | //======= 10 | // Linear 11 | //======= 12 | 13 | public static float Linear(float p1, float p2, float factor) 14 | { 15 | return p2 * factor + p1 * (1.0f - factor); 16 | } 17 | 18 | public static Vector2 Linear(Vector2 p1, Vector2 p2, float factor) 19 | { 20 | return new Vector2(Linear(p1.x, p2.x, factor), 21 | Linear(p1.y, p2.y, factor)); 22 | } 23 | 24 | public static Vector3 Linear(Vector3 p1, Vector3 p2, float factor) 25 | { 26 | return new Vector3(Linear(p1.x, p2.x, factor), 27 | Linear(p1.y, p2.y, factor), 28 | Linear(p1.z, p2.z, factor)); 29 | } 30 | 31 | 32 | //========== 33 | // Quadratic 34 | //========== 35 | 36 | public static float Quadratic(float p1, float p2, float p3, float factor) 37 | { 38 | float antiFactor = 1.0f - factor; 39 | return p3 * factor * factor + p2 * 2.0f * factor * antiFactor + p1 * antiFactor * antiFactor; 40 | } 41 | 42 | public static Vector2 Quadratic(Vector2 p1, Vector2 p2, Vector2 p3, float factor) 43 | { 44 | return new Vector2(Quadratic(p1.x, p2.x, p3.x, factor), 45 | Quadratic(p1.y, p2.y, p3.y, factor)); 46 | } 47 | 48 | public static Vector3 Quadratic(Vector3 p1, Vector3 p2, Vector3 p3, float factor) 49 | { 50 | return new Vector3(Quadratic(p1.x, p2.x, p3.x, factor), 51 | Quadratic(p1.y, p2.y, p3.y, factor), 52 | Quadratic(p1.z, p2.z, p3.z, factor)); 53 | } 54 | 55 | 56 | //====== 57 | // Cubic 58 | //====== 59 | 60 | public static float Cubic(float p1, float p2, float p3, float p4, float factor) 61 | { 62 | float antiFactor = 1.0f - factor; 63 | return p4 * (factor * factor * factor) + p3 * 3.0f * factor * factor * antiFactor + p2 * 3.0f * factor * antiFactor * antiFactor + p1 * (antiFactor * antiFactor * antiFactor); 64 | } 65 | 66 | public static Vector2 Cubic(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float factor) 67 | { 68 | return new Vector2(Cubic(p1.x, p2.x, p3.x, p4.x, factor), 69 | Cubic(p1.y, p2.y, p3.y, p4.y, factor)); 70 | } 71 | 72 | public static Vector3 Cubic(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, float factor) 73 | { 74 | return new Vector3(Cubic(p1.x, p2.x, p3.x, p4.x, factor), 75 | Cubic(p1.y, p2.y, p3.y, p4.y, factor), 76 | Cubic(p1.z, p2.z, p3.z, p4.z, factor)); 77 | } 78 | 79 | 80 | //============= 81 | // Cubic smooth 82 | //============= 83 | 84 | public static float CubicSmooth(float prevPoint, float startPoint, float endPoint, float nextPoint, float factor) 85 | { 86 | //return p[1] + 0.5 * x*(p[2] - p[0] + x*(2.0*p[0] - 5.0*p[1] + 4.0*p[2] - p[3] + x*(3.0*(p[1] - p[2]) + p[3] - p[0]))); 87 | 88 | //p0 - a_PrevPoint 89 | //p1 - a_StartPoint 90 | //p2 - a_EndPoint 91 | //p3 - a_NextPoint 92 | //x - a_Factor 93 | 94 | return startPoint + 0.5f * factor * (endPoint - prevPoint + factor * (2.0f * prevPoint - 5.0f * startPoint + 4.0f * endPoint - nextPoint + factor * (3.0f * (startPoint - endPoint) + nextPoint - prevPoint))); 95 | } 96 | 97 | public static Vector2 CubicSmooth(Vector2 prevPoint, Vector2 startPoint, Vector2 endPoint, Vector2 nextPoint, float factor) 98 | { 99 | return new Vector2(CubicSmooth(prevPoint.x, startPoint.x, endPoint.x, nextPoint.x, factor), 100 | CubicSmooth(prevPoint.y, startPoint.y, endPoint.y, nextPoint.y, factor)); 101 | } 102 | 103 | public static Vector3 CubicSmooth(Vector3 prevPoint, Vector3 startPoint, Vector3 endPoint, Vector3 nextPoint, float factor) 104 | { 105 | return new Vector3(CubicSmooth(prevPoint.x, startPoint.x, endPoint.x, nextPoint.x, factor), 106 | CubicSmooth(prevPoint.y, startPoint.y, endPoint.y, nextPoint.y, factor), 107 | CubicSmooth(prevPoint.z, startPoint.z, endPoint.z, nextPoint.z, factor)); 108 | } 109 | 110 | 111 | //some special cases 112 | public static float EaseIn(float value) 113 | { 114 | return Quadratic(0.0f, 0.0f, 1.0f, value); 115 | } 116 | } 117 | } -------------------------------------------------------------------------------- /Assets/Scripts/Interpolation.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 066c2f1019c69f045a8d243e5d796557 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Scripts/Jobified.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 74deb56faf8e3684ea92942fd450dfce 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scripts/Jobified/IRenderable.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using Unity.Mathematics; 4 | using UnityEngine; 5 | 6 | namespace vadersb.utils.unity.jobs 7 | { 8 | public interface IRenderable 9 | { 10 | //visibility 11 | bool IsVisible(); 12 | 13 | //sprite index 14 | int GetSpriteIndex(); 15 | 16 | //transform 17 | float2 GetPosition(); 18 | float2 GetScale(); 19 | float GetRotationAngle(); 20 | 21 | //color 22 | Color GetColor(); 23 | } 24 | } -------------------------------------------------------------------------------- /Assets/Scripts/Jobified/IRenderable.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c872e67989585154bb9c597be0d42781 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Scripts/Jobified/ItemsGroupInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | 6 | namespace vadersb.utils.unity.jobs 7 | { 8 | public struct ItemsGroupInfo 9 | { 10 | public int Count { get; } 11 | 12 | public ItemsGroupInfo(int count) 13 | { 14 | Count = count; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Assets/Scripts/Jobified/ItemsGroupInfo.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ca87cc00e827cf54d884feb2bf560272 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Scripts/Jobified/RenderableJobsUtils.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using Unity.Mathematics; 5 | using UnityEngine; 6 | using UnityEngine.Rendering; 7 | 8 | namespace vadersb.utils.unity.jobs 9 | { 10 | public static class RenderableJobsUtils 11 | { 12 | [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)] 13 | public struct VertexData 14 | { 15 | public Vector3 m_Position; 16 | public Color32 m_Color; 17 | public Vector2 m_TextureCoords; 18 | 19 | public VertexData(Vector3 position, Color32 color, Vector2 textureCoords) 20 | { 21 | m_Position = position; 22 | m_Color = color; 23 | m_TextureCoords = textureCoords; 24 | } 25 | } 26 | 27 | [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)] 28 | public struct QuadVertexData 29 | { 30 | private VertexData m_V0; 31 | private VertexData m_V1; 32 | private VertexData m_V2; 33 | private VertexData m_V3; 34 | 35 | 36 | public QuadVertexData(VertexData v0, VertexData v1, VertexData v2, VertexData v3) 37 | { 38 | m_V0 = v0; 39 | m_V1 = v1; 40 | m_V2 = v2; 41 | m_V3 = v3; 42 | } 43 | } 44 | 45 | [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)] 46 | public struct QuadIndexData 47 | { 48 | private uint m_Index0; 49 | private uint m_Index1; 50 | private uint m_Index2; 51 | 52 | private uint m_Index3; 53 | private uint m_Index4; 54 | private uint m_Index5; 55 | 56 | 57 | public QuadIndexData(uint i0, uint i1, uint i2, uint i3, uint i4, uint i5) 58 | { 59 | m_Index0 = i0; 60 | m_Index1 = i1; 61 | m_Index2 = i2; 62 | 63 | m_Index3 = i3; 64 | m_Index4 = i4; 65 | m_Index5 = i5; 66 | } 67 | } 68 | 69 | private static readonly VertexAttributeDescriptor[] s_VertexLayout = new[] 70 | { 71 | new VertexAttributeDescriptor(VertexAttribute.Position, VertexAttributeFormat.Float32, 3), 72 | new VertexAttributeDescriptor(VertexAttribute.Color, VertexAttributeFormat.UNorm8, 4), 73 | new VertexAttributeDescriptor(VertexAttribute.TexCoord0, VertexAttributeFormat.Float32, 2) 74 | }; 75 | 76 | public static VertexAttributeDescriptor[] VertexLayout => s_VertexLayout; 77 | 78 | 79 | public static float2 CalculatePosition(float2 localPosition, float2 worldPosition, float2 scale, float rotationAngle) 80 | { 81 | //scale 82 | float2 result = localPosition * scale; 83 | 84 | //rotation 85 | float curSin = math.sin(rotationAngle); 86 | float curCos = math.cos(rotationAngle); 87 | 88 | float rotatedX = result.x * curCos - result.y * curSin; 89 | float rotatedY = result.x * curSin + result.y * curCos; 90 | 91 | result = new float2(rotatedX, rotatedY); 92 | 93 | //translation 94 | result += worldPosition; 95 | 96 | //finally 97 | return result; 98 | } 99 | 100 | 101 | public static float2 CalculatePosition(float2 localPosition, float2 worldPosition, float2 scale, float rotationAngleSin, float rotationAngleCos) 102 | { 103 | //scale 104 | float2 result = localPosition * scale; 105 | 106 | //rotation 107 | float rotatedX = result.x * rotationAngleCos - result.y * rotationAngleSin; 108 | float rotatedY = result.x * rotationAngleSin + result.y * rotationAngleCos; 109 | 110 | result = new float2(rotatedX, rotatedY); 111 | 112 | //translation 113 | result += worldPosition; 114 | 115 | //finally 116 | return result; 117 | } 118 | } 119 | } 120 | 121 | -------------------------------------------------------------------------------- /Assets/Scripts/Jobified/RenderableJobsUtils.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ccda2c4505b14604fb3c4ca3a075c19e 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Scripts/Jobified/SimpleSpritesSimulatorJobified.cs: -------------------------------------------------------------------------------- 1 | using Unity.Burst; 2 | using Unity.Collections; 3 | using Unity.Jobs; 4 | using Unity.Mathematics; 5 | using UnityEngine; 6 | using vadersb.utils; 7 | using vadersb.utils.unity.jobs; 8 | 9 | public class SimpleSpritesSimulatorJobified : MonoBehaviour 10 | { 11 | private struct Particle : IRenderable 12 | { 13 | public float2 m_Position; 14 | public Color m_Color; 15 | 16 | public bool m_HorLeft; 17 | public bool m_VerUp; 18 | 19 | public float m_SpeedMult; 20 | 21 | public int m_SpriteIndex; 22 | 23 | public float m_Angle; 24 | 25 | public float m_Scale; 26 | 27 | 28 | 29 | 30 | //----- 31 | //IRenderable 32 | 33 | public bool IsVisible() 34 | { 35 | return true; 36 | } 37 | 38 | public int GetSpriteIndex() 39 | { 40 | return m_SpriteIndex; 41 | } 42 | 43 | 44 | public float2 GetPosition() 45 | { 46 | return m_Position; 47 | } 48 | 49 | 50 | public float2 GetScale() 51 | { 52 | return new float2(m_Scale, m_Scale); 53 | } 54 | 55 | 56 | public float GetRotationAngle() 57 | { 58 | return m_Angle; 59 | } 60 | 61 | 62 | public Color GetColor() 63 | { 64 | return m_Color; 65 | } 66 | } 67 | 68 | //settings 69 | [Header("Camera")] 70 | [SerializeField] 71 | private Camera m_Camera; 72 | 73 | [Header("Speed")] 74 | [SerializeField] 75 | private float m_SpeedMin = 0.05f; 76 | 77 | [SerializeField] 78 | private float m_SpeedMax = 1.0f; 79 | 80 | [Header("Scale")] 81 | [SerializeField] 82 | private float m_ScaleMin = 0.5f; 83 | 84 | [SerializeField] 85 | private float m_ScaleMax = 2.0f; 86 | 87 | [Header("Sprites count")] 88 | [SerializeField] 89 | private int m_SpritesCount = 1000; 90 | 91 | [Header("Optimization")] 92 | [SerializeField] 93 | [Range(1, 20000)] 94 | private int m_UpdateBatchCount = 64; 95 | 96 | [SerializeField] 97 | [Range(1, 20000)] 98 | private int m_VertexBatchCount = 1000; 99 | 100 | [SerializeField] 101 | [Range(1, 20000)] 102 | private int m_IndexBatchCount = 1000; 103 | 104 | 105 | [Header("DEBUG")] 106 | [SerializeField] 107 | private bool m_DebugUseFixedTimeDelta = true; 108 | 109 | private SpriteBatchRenderSetup m_BatchRenderSetup; 110 | private SpriteBatcher m_SpriteBatcher; 111 | 112 | private NativeArray m_Particles; 113 | private NativeArray m_ItemsGroupInfo; 114 | 115 | private void Awake() 116 | { 117 | m_BatchRenderSetup = GetComponent(); 118 | Debug.Assert(m_BatchRenderSetup != null); 119 | } 120 | 121 | 122 | private void Start() 123 | { 124 | m_SpriteBatcher = new SpriteBatcher(m_BatchRenderSetup.Mesh); 125 | 126 | GenerateParticles(); 127 | } 128 | 129 | private void Update() 130 | { 131 | if (Input.GetKeyDown(KeyCode.Z) == true) 132 | { 133 | m_DebugUseFixedTimeDelta = !m_DebugUseFixedTimeDelta; 134 | //UpdateDeltaTimeMark(); 135 | } 136 | 137 | float minX = -1.0f; 138 | float maxX = 1.0f; 139 | float minY = -1.0f; 140 | float maxY = 1.0f; 141 | 142 | float deltaTime = Time.deltaTime; 143 | 144 | //getting camera bounds 145 | if (m_Camera) 146 | { 147 | float halfSize = m_Camera.orthographicSize; 148 | float ratio = m_Camera.aspect; 149 | 150 | minY = -halfSize; 151 | maxY = halfSize; 152 | 153 | minX = -halfSize * ratio; 154 | maxX = halfSize * ratio; 155 | } 156 | 157 | 158 | //particles update job 159 | var updateJob = new ParticlesUpdateJob(m_Particles, new float2(minX, maxX), new float2(minY, maxY), deltaTime, m_SpeedMin, m_SpeedMax); 160 | 161 | var updateJobHandle = updateJob.Schedule(m_Particles.Length, m_UpdateBatchCount); 162 | 163 | 164 | //sprite batcher begin 165 | m_SpriteBatcher.BatchStart(m_Particles, m_Particles.Length, m_BatchRenderSetup.SpriteDataArray, updateJobHandle, m_VertexBatchCount, m_IndexBatchCount); 166 | } 167 | 168 | 169 | private void LateUpdate() 170 | { 171 | //sprite batcher finalize 172 | m_SpriteBatcher.BatchFinalize(); 173 | 174 | //todo a good place to run RemoveDeadJob (it will execute while rendering is being done, Complete() will be called in the *next* frame Update(), so it happens kinda "between frames") 175 | } 176 | 177 | 178 | private void OnDestroy() 179 | { 180 | m_Particles.Dispose(); 181 | m_ItemsGroupInfo.Dispose(); 182 | } 183 | 184 | 185 | private void GenerateParticles() 186 | { 187 | WeightedRandomizer randomizer = new WeightedRandomizer(); 188 | 189 | randomizer.AddValue(Color.black, 1.0f); 190 | randomizer.AddValue(Color.blue, 1.0f); 191 | randomizer.AddValue(Color.green, 1.0f); 192 | randomizer.AddValue(Color.red, 1.0f); 193 | randomizer.AddValue(Color.white, 50.0f); 194 | 195 | float minX = -1.0f; 196 | float maxX = 1.0f; 197 | float minY = -1.0f; 198 | float maxY = 1.0f; 199 | 200 | //getting camera bounds 201 | if (m_Camera) 202 | { 203 | float halfSize = m_Camera.orthographicSize; 204 | float ratio = m_Camera.aspect; 205 | 206 | minY = -halfSize; 207 | maxY = halfSize; 208 | 209 | minX = -halfSize * ratio; 210 | maxX = halfSize * ratio; 211 | } 212 | 213 | //generate particles 214 | m_Particles = new NativeArray(m_SpritesCount, Allocator.Persistent); 215 | 216 | for (int i = 0; i < m_SpritesCount; i++) 217 | { 218 | var particle = new Particle(); 219 | 220 | particle.m_Position.x = MathHelpers.Random_Float(minX, maxX); 221 | particle.m_Position.y = MathHelpers.Random_Float(minY, maxY); 222 | particle.m_Color = randomizer.GetRandomValue(); 223 | particle.m_HorLeft = MathHelpers.Random_CheckChance(0.5f); 224 | particle.m_VerUp = MathHelpers.Random_CheckChance(0.5f); 225 | particle.m_SpeedMult = MathHelpers.Random_Factor(); 226 | particle.m_SpeedMult = Interpolation.EaseIn(particle.m_SpeedMult); 227 | particle.m_SpeedMult = Interpolation.EaseIn(particle.m_SpeedMult); 228 | particle.m_SpeedMult = Interpolation.EaseIn(particle.m_SpeedMult); 229 | particle.m_SpriteIndex = MathHelpers.Random_Int(0, 1); 230 | particle.m_Angle = MathHelpers.Random_Angle(); 231 | 232 | particle.m_Scale = Interpolation.Linear(m_ScaleMin, m_ScaleMax, Interpolation.EaseIn(MathHelpers.Random_Factor())); 233 | 234 | m_Particles[i] = particle; 235 | } 236 | 237 | //items group info 238 | m_ItemsGroupInfo = new NativeArray(1, Allocator.Persistent); 239 | m_ItemsGroupInfo[0] = new ItemsGroupInfo(m_SpritesCount); 240 | } 241 | 242 | 243 | 244 | 245 | //update job 246 | [BurstCompile] 247 | private struct ParticlesUpdateJob : IJobParallelFor 248 | { 249 | //----- 250 | //input data 251 | private NativeArray m_Particles; 252 | 253 | private float2 m_BoundsX; 254 | private float2 m_BoundsY; 255 | 256 | private float m_DeltaTime; 257 | 258 | private float m_SpeedMin; 259 | private float m_SpeedMax; 260 | 261 | 262 | public ParticlesUpdateJob(NativeArray particles, float2 boundsX, float2 boundsY, float deltaTime, float speedMin, float speedMax) 263 | { 264 | m_Particles = particles; 265 | 266 | m_BoundsX = boundsX; 267 | m_BoundsY = boundsY; 268 | 269 | m_DeltaTime = deltaTime; 270 | 271 | m_SpeedMin = speedMin; 272 | m_SpeedMax = speedMax; 273 | } 274 | 275 | 276 | public void Execute(int index) 277 | { 278 | var particle = m_Particles[index]; 279 | 280 | //speed 281 | float curSpeed = math.lerp(m_SpeedMin, m_SpeedMax, particle.m_SpeedMult) * m_DeltaTime; 282 | 283 | //moving and bouncing 284 | if (particle.m_HorLeft == true) 285 | { 286 | particle.m_Position.x -= curSpeed; 287 | if (particle.m_Position.x <= m_BoundsX.x) 288 | { 289 | particle.m_HorLeft = false; 290 | } 291 | } 292 | else 293 | { 294 | particle.m_Position.x += curSpeed; 295 | if (particle.m_Position.x >= m_BoundsX.y) 296 | { 297 | particle.m_HorLeft = true; 298 | } 299 | } 300 | 301 | //ver 302 | if (particle.m_VerUp == true) 303 | { 304 | particle.m_Position.y += curSpeed; 305 | if (particle.m_Position.y >= m_BoundsY.y) 306 | { 307 | particle.m_VerUp = false; 308 | } 309 | } 310 | else 311 | { 312 | particle.m_Position.y -= curSpeed; 313 | if (particle.m_Position.y <= m_BoundsY.x) 314 | { 315 | particle.m_VerUp = true; 316 | } 317 | } 318 | 319 | //rotation 320 | //todo expand 321 | particle.m_Angle += 0.2f * m_DeltaTime; 322 | 323 | 324 | //finally - storing the updated particle 325 | m_Particles[index] = particle; 326 | } 327 | } 328 | 329 | } 330 | -------------------------------------------------------------------------------- /Assets/Scripts/Jobified/SimpleSpritesSimulatorJobified.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2f242ab6ba2fe704090e6b6a53f6cb94 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Scripts/Jobified/SpriteBatchRenderSetup.cs: -------------------------------------------------------------------------------- 1 | using Unity.Collections; 2 | using UnityEngine; 3 | using UnityEngine.Rendering; 4 | 5 | 6 | namespace vadersb.utils.unity.jobs 7 | { 8 | [RequireComponent(typeof(MeshRenderer), typeof(MeshFilter))] 9 | public class SpriteBatchRenderSetup : MonoBehaviour 10 | { 11 | //from: https://thomasmountainborn.com/2016/05/25/materialpropertyblocks/ 12 | //Using renderer.SetPropertyBlock(), we can apply our new values to the renderer. 13 | //Job done! However, it is important to note that setting a property block on a renderer 14 | //overwrites any other data set by property blocks on that renderer. 15 | //If your new property block doesn't hold a value that was present before, that value will be reset. 16 | 17 | [SerializeField] 18 | private SpriteList m_SpriteList; 19 | 20 | [SerializeField] 21 | private Color m_Color = Color.white; 22 | 23 | 24 | //refs 25 | private MeshRenderer m_MeshRenderer; 26 | private MeshFilter m_MeshFilter; 27 | 28 | //mesh 29 | private Mesh m_Mesh; 30 | 31 | //material properties block 32 | private MaterialPropertyBlock m_MaterialPropertyBlock; 33 | 34 | 35 | private static readonly int s_ColorProperty = Shader.PropertyToID("_RendererColor"); 36 | private static readonly int s_TextureProperty = Shader.PropertyToID("_MainTex"); 37 | 38 | 39 | void Awake() 40 | { 41 | m_MeshRenderer = GetComponent(); 42 | Debug.Assert(m_MeshRenderer != null); 43 | 44 | m_MeshFilter = GetComponent(); 45 | Debug.Assert(m_MeshFilter != null); 46 | 47 | #if DEBUG 48 | if (m_MeshFilter.sharedMesh != null) 49 | { 50 | Debug.LogWarning("Mesh filter contains some mesh that will be overridden by sprite batcher!"); 51 | } 52 | #endif 53 | 54 | m_Mesh = new Mesh(); 55 | m_Mesh.indexFormat = IndexFormat.UInt32; 56 | m_Mesh.MarkDynamic(); 57 | 58 | m_MeshFilter.sharedMesh = m_Mesh; 59 | 60 | m_MaterialPropertyBlock = new MaterialPropertyBlock(); 61 | 62 | m_SpriteList.Init(); 63 | 64 | RefreshMaterialPropertyTexture(); 65 | RefreshMaterialPropertyColor(); 66 | ApplyMaterialPropertyBlock(); 67 | } 68 | 69 | 70 | private void OnValidate() 71 | { 72 | //Debug.Log("SpriteBatchRenderSetup.OnValidate()"); 73 | bool applyPropertyBlock = m_MaterialPropertyBlock != null && m_MeshRenderer != null; 74 | 75 | if (m_SpriteList != null) 76 | { 77 | //m_SpriteList.Init(); 78 | 79 | if (applyPropertyBlock) 80 | { 81 | RefreshMaterialPropertyTexture(); 82 | } 83 | } 84 | 85 | if (applyPropertyBlock) 86 | { 87 | RefreshMaterialPropertyColor(); 88 | ApplyMaterialPropertyBlock(); 89 | } 90 | } 91 | 92 | 93 | private void OnDestroy() 94 | { 95 | m_SpriteList.Dispose(); 96 | } 97 | 98 | 99 | public Mesh Mesh => m_Mesh; 100 | 101 | 102 | public MaterialPropertyBlock MaterialPropertyBlock => m_MaterialPropertyBlock; 103 | 104 | 105 | public NativeArray SpriteDataArray => m_SpriteList.SpriteDataArray; 106 | 107 | public Color Color 108 | { 109 | get => m_Color; 110 | set 111 | { 112 | m_Color = value; 113 | RefreshMaterialPropertyColor(); 114 | ApplyMaterialPropertyBlock(); 115 | } 116 | } 117 | 118 | 119 | private void RefreshMaterialPropertyTexture() 120 | { 121 | Debug.Assert(m_MaterialPropertyBlock != null); 122 | 123 | Texture texture = m_SpriteList.Texture; 124 | 125 | m_MaterialPropertyBlock.SetTexture(s_TextureProperty, texture); 126 | } 127 | 128 | 129 | private void RefreshMaterialPropertyColor() 130 | { 131 | Debug.Assert(m_MaterialPropertyBlock != null); 132 | 133 | m_MaterialPropertyBlock.SetColor(s_ColorProperty, m_Color); 134 | } 135 | 136 | 137 | private void ApplyMaterialPropertyBlock() 138 | { 139 | Debug.Assert(m_MaterialPropertyBlock != null); 140 | Debug.Assert(m_MeshRenderer != null); 141 | 142 | m_MeshRenderer.SetPropertyBlock(m_MaterialPropertyBlock); 143 | } 144 | } 145 | } -------------------------------------------------------------------------------- /Assets/Scripts/Jobified/SpriteBatchRenderSetup.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: da26c2f9f4a82e846a10cc1d99462fbe 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Scripts/Jobified/SpriteBatcher.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using Unity.Burst; 5 | using Unity.Collections; 6 | using Unity.Jobs; 7 | using Unity.Mathematics; 8 | using UnityEngine; 9 | using UnityEngine.Rendering; 10 | 11 | namespace vadersb.utils.unity.jobs 12 | { 13 | public class SpriteBatcher where T: struct, IRenderable 14 | { 15 | public const int BatchCountVertex = 256; 16 | public const int BatchCountIndex = 512; 17 | 18 | private static readonly int VertexDataSize = Marshal.SizeOf(); 19 | private static readonly int QuadVertexDataSize = Marshal.SizeOf(); 20 | 21 | private static readonly int IndexDataSize = sizeof(uint); 22 | private static readonly int QuadIndexDataSize = Marshal.SizeOf(); 23 | 24 | 25 | private readonly Mesh m_Mesh; 26 | 27 | private NativeArray m_VerticesArray; 28 | private NativeArray m_IndicesArray; 29 | 30 | private JobHandle m_VertexJobHandle; 31 | private JobHandle m_IndexJobHandle; 32 | 33 | private bool m_IsBatching; 34 | 35 | 36 | public SpriteBatcher(Mesh mesh) 37 | { 38 | Debug.Assert(VertexDataSize * 4 == QuadVertexDataSize); 39 | Debug.Assert(IndexDataSize * 6 == QuadIndexDataSize); 40 | 41 | Debug.Log("Vertex data size: " + VertexDataSize); 42 | Debug.Log("Quad vertex data size: " + QuadVertexDataSize); 43 | 44 | Debug.Log("Index data size: " + IndexDataSize); 45 | Debug.Log("Quad index data size: " + QuadIndexDataSize); 46 | 47 | Debug.Assert(mesh != null); 48 | Debug.Assert(mesh.indexFormat == IndexFormat.UInt32); 49 | 50 | m_Mesh = mesh; 51 | //m_Mesh = new Mesh(); 52 | //m_Mesh.indexFormat = IndexFormat.UInt32; 53 | //m_Mesh.MarkDynamic(); 54 | 55 | m_IsBatching = false; 56 | } 57 | 58 | 59 | public void BatchStart(NativeArray items, int itemsCount, NativeArray sprites, JobHandle jobToWaitFor, int batchCountVertex = BatchCountVertex, int batchCountIndex = BatchCountIndex) 60 | { 61 | Debug.Assert(m_IsBatching == false); 62 | Debug.Assert(itemsCount <= items.Length); 63 | Debug.Assert(itemsCount >= 0); 64 | 65 | int verticesCount = itemsCount * 4; 66 | int indicesCount = itemsCount * 6; 67 | 68 | //arrays allocation 69 | m_VerticesArray = new NativeArray(itemsCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); 70 | m_IndicesArray = new NativeArray(itemsCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); 71 | 72 | //vertices job 73 | var vertexJob = new VertexJob(items, sprites, m_VerticesArray); 74 | m_VertexJobHandle = vertexJob.Schedule(itemsCount, batchCountVertex, jobToWaitFor); 75 | 76 | //indices job 77 | var indexJob = new IndexJob(m_IndicesArray); 78 | m_IndexJobHandle = indexJob.Schedule(itemsCount, batchCountIndex, jobToWaitFor); 79 | 80 | m_IsBatching = true; 81 | } 82 | 83 | 84 | public void BatchFinalize() 85 | { 86 | if (m_IsBatching == false) 87 | { 88 | return; 89 | } 90 | 91 | m_Mesh.Clear(); 92 | 93 | //vertex buffer 94 | m_VertexJobHandle.Complete(); 95 | 96 | int verticesCount = m_VerticesArray.Length * 4; 97 | 98 | var verticesArray = m_VerticesArray.Reinterpret(QuadVertexDataSize); 99 | 100 | m_Mesh.SetVertexBufferParams(verticesCount, RenderableJobsUtils.VertexLayout); 101 | 102 | //todo maybe add some flags 103 | m_Mesh.SetVertexBufferData(verticesArray, 0, 0, verticesCount); 104 | 105 | 106 | //index buffer 107 | m_IndexJobHandle.Complete(); 108 | 109 | int indicesCount = m_IndicesArray.Length * 6; 110 | 111 | var indicesArray = m_IndicesArray.Reinterpret(QuadIndexDataSize); 112 | 113 | m_Mesh.SetIndexBufferParams(indicesCount, IndexFormat.UInt32); 114 | m_Mesh.SetIndexBufferData(indicesArray, 0, 0, indicesCount); 115 | 116 | 117 | 118 | 119 | // SubMesh definition 120 | var meshDesc = new SubMeshDescriptor(0, indicesCount, MeshTopology.Triangles); 121 | m_Mesh.SetSubMesh(0, meshDesc); 122 | 123 | 124 | //arrays dispose 125 | m_VerticesArray.Dispose(); 126 | m_IndicesArray.Dispose(); 127 | 128 | 129 | //finally 130 | m_IsBatching = false; 131 | } 132 | 133 | 134 | public void Dispose() 135 | { 136 | if (m_IsBatching) 137 | { 138 | BatchFinalize(); 139 | } 140 | } 141 | 142 | //------------------------------------------------------------------------------ 143 | //JOBS 144 | [BurstCompile] 145 | struct VertexJob : IJobParallelFor 146 | { 147 | [ReadOnly] 148 | private NativeArray m_Items; 149 | 150 | [ReadOnly] 151 | private NativeArray m_Sprites; 152 | 153 | [WriteOnly] 154 | private NativeArray m_Output; 155 | 156 | 157 | public VertexJob(NativeArray items, NativeArray sprites, NativeArray output) 158 | { 159 | m_Items = items; 160 | m_Sprites = sprites; 161 | m_Output = output; 162 | } 163 | 164 | 165 | public void Execute(int index) 166 | { 167 | var item = m_Items[index]; 168 | 169 | //vertex array indices 170 | // int indexV0 = index * 4; 171 | // int indexV1 = indexV0 + 1; 172 | // int indexV2 = indexV1 + 1; 173 | // int indexV3 = indexV2 + 1; 174 | 175 | float2 v0; 176 | float2 v1; 177 | float2 v2; 178 | float2 v3; 179 | 180 | Color32 color; 181 | 182 | float2 t0; 183 | float2 t1; 184 | float2 t2; 185 | float2 t3; 186 | 187 | if (item.IsVisible() == true) 188 | { 189 | var sprite = m_Sprites[item.GetSpriteIndex()]; 190 | 191 | //position 192 | var worldPosition = item.GetPosition(); 193 | var scale = item.GetScale(); 194 | var rotationAngle = item.GetRotationAngle(); 195 | var rotationAngleSin = math.sin(rotationAngle); 196 | var rotationAngleCos = math.cos(rotationAngle); 197 | 198 | 199 | v0 = RenderableJobsUtils.CalculatePosition(sprite.v0, worldPosition, scale, rotationAngleSin, rotationAngleCos); 200 | v1 = RenderableJobsUtils.CalculatePosition(sprite.v1, worldPosition, scale, rotationAngleSin, rotationAngleCos); 201 | v2 = RenderableJobsUtils.CalculatePosition(sprite.v2, worldPosition, scale, rotationAngleSin, rotationAngleCos); 202 | v3 = RenderableJobsUtils.CalculatePosition(sprite.v3, worldPosition, scale, rotationAngleSin, rotationAngleCos); 203 | 204 | //color 205 | color = item.GetColor(); 206 | 207 | //texture coords 208 | t0 = sprite.t0; 209 | t1 = sprite.t1; 210 | t2 = sprite.t2; 211 | t3 = sprite.t3; 212 | } 213 | else 214 | { 215 | //position 216 | v0 = item.GetPosition(); 217 | v1 = v0; 218 | v2 = v0; 219 | v3 = v0; 220 | 221 | //color 222 | color = new Color32(0, 0, 0, 0); 223 | 224 | //texture coords 225 | t0 = new Vector2(0.0f, 0.0f); 226 | t1 = t0; 227 | t2 = t0; 228 | t3 = t0; 229 | } 230 | 231 | //output 232 | m_Output[index] = new RenderableJobsUtils.QuadVertexData( 233 | new RenderableJobsUtils.VertexData(new Vector3(v0.x, v0.y, 0.0f), color, t0), 234 | new RenderableJobsUtils.VertexData(new Vector3(v1.x, v1.y, 0.0f), color, t1), 235 | new RenderableJobsUtils.VertexData(new Vector3(v2.x, v2.y, 0.0f), color, t2), 236 | new RenderableJobsUtils.VertexData(new Vector3(v3.x, v3.y, 0.0f), color, t3)); 237 | } 238 | } 239 | 240 | [BurstCompile] 241 | struct IndexJob : IJobParallelFor 242 | { 243 | [WriteOnly] 244 | private NativeArray m_Output; 245 | 246 | 247 | public IndexJob(NativeArray output) 248 | { 249 | m_Output = output; 250 | } 251 | 252 | 253 | public void Execute(int index) 254 | { 255 | //vertex array indices 256 | uint vertex0 = (uint)index * 4; 257 | uint vertex1 = vertex0 + 1; 258 | uint vertex2 = vertex1 + 1; 259 | uint vertex3 = vertex2 + 1; 260 | 261 | //index array indices 262 | // int index0 = index * 6; 263 | // int index1 = index0 + 1; 264 | // int index2 = index1 + 1; 265 | // int index3 = index2 + 1; 266 | // int index4 = index3 + 1; 267 | // int index5 = index4 + 1; 268 | 269 | //0 1 2 270 | //2 1 3 271 | 272 | // m_Output[index0] = vertex0; 273 | // m_Output[index1] = vertex1; 274 | // m_Output[index2] = vertex2; 275 | // 276 | // m_Output[index3] = vertex2; 277 | // m_Output[index4] = vertex1; 278 | // m_Output[index5] = vertex3; 279 | 280 | m_Output[index] = new RenderableJobsUtils.QuadIndexData(vertex0, vertex1, vertex2, vertex2, vertex1, vertex3); 281 | 282 | } 283 | } 284 | } 285 | 286 | } -------------------------------------------------------------------------------- /Assets/Scripts/Jobified/SpriteBatcher.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1bf76e64d5056fa48985d9dad8128cc7 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Scripts/Jobified/SpriteData.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using Unity.Mathematics; 4 | using UnityEngine; 5 | 6 | namespace vadersb.utils.unity.jobs 7 | { 8 | public struct SpriteData 9 | { 10 | //vertices 11 | public float2 v0 { get; } 12 | public float2 v1 { get; } 13 | public float2 v2 { get; } 14 | public float2 v3 { get; } 15 | 16 | //texture coords 17 | public Vector2 t0 { get; } 18 | public Vector2 t1 { get; } 19 | public Vector2 t2 { get; } 20 | public Vector2 t3 { get; } 21 | 22 | public SpriteData(Sprite sprite) 23 | { 24 | //validation 25 | Debug.Assert(sprite != null); 26 | Debug.Assert(sprite.vertices.Length == 4); 27 | 28 | //vertices 29 | v0 = sprite.vertices[0]; 30 | v1 = sprite.vertices[1]; 31 | v2 = sprite.vertices[2]; 32 | v3 = sprite.vertices[3]; 33 | 34 | //texture coords 35 | t0 = sprite.uv[0]; 36 | t1 = sprite.uv[1]; 37 | t2 = sprite.uv[2]; 38 | t3 = sprite.uv[3]; 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /Assets/Scripts/Jobified/SpriteData.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c1e84de82fecf19429dff00ddfe53d0d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Scripts/Jobified/SpriteList.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using Unity.Collections; 5 | using UnityEngine; 6 | 7 | namespace vadersb.utils.unity.jobs 8 | { 9 | [Serializable] 10 | public class SpriteList 11 | { 12 | [SerializeField] 13 | private List m_Sprites; 14 | 15 | private NativeArray m_SpriteDataArray; 16 | 17 | private Texture m_Texture = null; 18 | 19 | public void Init() 20 | { 21 | Debug.Assert(m_Sprites != null); 22 | 23 | //0. texture 24 | if (m_Sprites.Count == 0) 25 | { 26 | m_Texture = null; 27 | } 28 | else 29 | { 30 | m_Texture = m_Sprites[0].texture; 31 | } 32 | 33 | //1. sprites list validation 34 | foreach (var sprite in m_Sprites) 35 | { 36 | if (sprite.packed == false) 37 | { 38 | Debug.LogError("Sprite " + sprite.name + " is not packed!"); 39 | } 40 | 41 | if (sprite.texture != m_Texture) 42 | { 43 | Debug.LogError("Sprite texture is " + sprite.texture.name + " which differs from the first sprite texture: "); 44 | 45 | if (m_Texture != null) 46 | { 47 | Debug.LogError(m_Texture.name + ". All sprites should have the same texture (belong to the same atlas)!"); 48 | } 49 | } 50 | 51 | if (sprite.vertices.Length != 4) 52 | { 53 | Debug.LogError("Sprite " + sprite.name + " is tightly packed! Only rectangle packing is supported for sprite batching!"); 54 | } 55 | } 56 | 57 | //2. sprite data array init 58 | if (m_SpriteDataArray.IsCreated) 59 | { 60 | m_SpriteDataArray.Dispose(); 61 | } 62 | 63 | m_SpriteDataArray = new NativeArray(m_Sprites.Count, Allocator.Persistent, NativeArrayOptions.ClearMemory); 64 | 65 | for (int i = 0; i < m_Sprites.Count; i++) 66 | { 67 | m_SpriteDataArray[i] = new SpriteData(m_Sprites[i]); 68 | } 69 | } 70 | 71 | 72 | public void Dispose() 73 | { 74 | m_SpriteDataArray.Dispose(); 75 | } 76 | 77 | public int SpritesCount 78 | { 79 | get 80 | { 81 | if (m_Sprites == null) 82 | { 83 | return 0; 84 | } 85 | else 86 | { 87 | return m_Sprites.Count; 88 | } 89 | } 90 | } 91 | 92 | public NativeArray SpriteDataArray => m_SpriteDataArray; 93 | 94 | public Texture Texture => m_Texture; 95 | 96 | 97 | } 98 | 99 | } -------------------------------------------------------------------------------- /Assets/Scripts/Jobified/SpriteList.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d6e92c234e98acc46ae87af5e09d2c66 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Scripts/MathHelpers.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | 6 | namespace vadersb.utils 7 | { 8 | public static class MathHelpers 9 | { 10 | //----- 11 | //pi consts 12 | public const float Pi = Mathf.PI; 13 | 14 | public const float Pi_Double = Pi * 2.0f; 15 | public const float Pi_Half = Pi * 0.50f; 16 | public const float Pi_OneAndHalf = Pi * 1.50f; 17 | public const float Pi_OneFourth = Pi / 4.0f; 18 | public const float Pi_OneSixth = Pi / 6.0f; 19 | 20 | public const float ConvertAngle_ToRadians = Pi / 180.0f; 21 | public const float ConvertAngle_ToDegrees = 180.0f / Pi; 22 | 23 | 24 | //================ 25 | //random functions 26 | //================ 27 | 28 | #region Random Functions 29 | 30 | /// 31 | /// Returns random float in range [0.0; 1.0] 32 | /// 33 | public static float Random_Factor() 34 | { 35 | return Random.Range(0.0f, 1.0f); 36 | } 37 | 38 | /// 39 | /// Returns random float in range [0.0; 1.0) 40 | /// 41 | public static float Random_Factor_Looped() 42 | { 43 | var result = Random.Range(0.0f, 1.0f); 44 | 45 | if (result >= 1.0f) 46 | { 47 | result -= 1.0f; 48 | } 49 | 50 | return result; 51 | } 52 | 53 | /// 54 | /// Returns random float in specified range [min; max] 55 | /// 56 | /// 57 | /// 58 | public static float Random_Float(float min, float max) 59 | { 60 | return Random.Range(min, max); 61 | } 62 | 63 | /// 64 | /// Returns random float in specified range [center - radius; center + radius] 65 | /// 66 | /// 67 | /// 68 | public static float Random_Float_FromCenter(float center, float radius) 69 | { 70 | return Random.Range(center - radius, center + radius); 71 | } 72 | 73 | /// 74 | /// Returns random int in specified range [min; max] 75 | /// 76 | /// 77 | /// 78 | public static int Random_Int(int min, int max) 79 | { 80 | return Random.Range(min, max + 1); 81 | } 82 | 83 | /// 84 | /// Returns random int in specified range [center - radius; center + radius] 85 | /// 86 | /// 87 | /// 88 | public static int Random_Int_FromCenter(int center, int radius) 89 | { 90 | return Random.Range(center - radius, center + radius + 1); 91 | } 92 | 93 | /// 94 | /// Returns random angle in range [0; 2Pi] 95 | /// 96 | /// 97 | /// Float value of the random angle. 98 | /// 99 | public static float Random_Angle() 100 | { 101 | return Random_Factor() * Pi_Double; 102 | } 103 | 104 | /// 105 | /// Returns random angle in range [0; 2Pi) 106 | /// 107 | /// 108 | /// Float value of the random angle. 109 | /// 110 | public static float Random_Angle_Looped() 111 | { 112 | return Random_Factor_Looped() * Pi_Double; 113 | } 114 | 115 | /// 116 | /// Checks if a probable event happened. 117 | /// 118 | /// Probability of the event. Expected range is in [0.0; 1.0] range. 119 | /// 120 | /// Boolean value: is event happened or not. 121 | /// Always returns false if probability is less or equal 0 122 | /// Always returns true if probability is more or equal 1 123 | /// 124 | public static bool Random_CheckChance(float probability) 125 | { 126 | if (probability >= 1.0f) return true; 127 | if (probability <= 0.0f) return false; 128 | 129 | return probability >= Random.Range(0.0f, 1.0f); 130 | } 131 | 132 | //Random Functions 133 | #endregion 134 | 135 | //===== 136 | //clamp 137 | //===== 138 | 139 | 140 | public static float Clamp_InRangeLooped(float valueToClamp, float range) 141 | { 142 | while (valueToClamp < 0.0f) 143 | { 144 | valueToClamp += range; 145 | } 146 | 147 | while (valueToClamp >= range) 148 | { 149 | valueToClamp -= range; 150 | } 151 | 152 | return valueToClamp; 153 | } 154 | 155 | /// 156 | /// Clamps float number into [0.0; 1.0] range 157 | /// 158 | /// 159 | public static float Clamp_Factor(float factor) 160 | { 161 | if (factor < 0.0f) return 0.0f; 162 | if (factor > 1.0f) return 1.0f; 163 | return factor; 164 | } 165 | 166 | /// 167 | /// Clamps float number into [0.0; 1.0) range 168 | /// 169 | /// 170 | public static float Clamp_Factor_Looped(float factor) 171 | { 172 | while (factor < 0.0f) 173 | { 174 | factor += 1.0f; 175 | } 176 | 177 | while (factor >= 1.0f) 178 | { 179 | factor -= 1.0f; 180 | } 181 | 182 | return factor; 183 | } 184 | 185 | /// 186 | /// Clamps float number into [0.0; 2Pi] range 187 | /// 188 | /// 189 | public static float Clamp_Angle(float angle) 190 | { 191 | while (angle < 0.0f) 192 | { 193 | angle += Pi_Double; 194 | } 195 | 196 | while (angle > Pi_Double) 197 | { 198 | angle -= Pi_Double; 199 | } 200 | 201 | return angle; 202 | } 203 | 204 | /// 205 | /// Clamps float number into [0.0; 2Pi) range 206 | /// 207 | /// 208 | public static float Clamp_Angle_Looped(float angle) 209 | { 210 | while (angle < 0.0f) 211 | { 212 | angle += Pi_Double; 213 | } 214 | 215 | while (angle >= Pi_Double) 216 | { 217 | angle -= Pi_Double; 218 | } 219 | 220 | return angle; 221 | } 222 | 223 | 224 | //====== 225 | //factor 226 | //====== 227 | 228 | /// 229 | /// Returns a factor of a value inside specified range. 230 | /// 231 | /// range start 232 | /// range end 233 | /// value on the range 234 | public static float Factor_FromRange(float rangeFrom, float rangeTo, float curValue) 235 | { 236 | if (Mathf.Approximately(rangeFrom, rangeTo)) 237 | { 238 | return 1.0f; 239 | } 240 | 241 | return (curValue - rangeFrom) / (rangeTo - rangeFrom); 242 | } 243 | 244 | 245 | public static float Factor_FromRange_Clamped(float rangeFrom, float rangeTo, float curValue) 246 | { 247 | return MathHelpers.Clamp_Factor(Factor_FromRange(rangeFrom, rangeTo, curValue)); 248 | } 249 | 250 | 251 | /// 252 | /// Returns a sub-factor of a value inside specified sub-factor range. 253 | /// 254 | /// range start 255 | /// range end 256 | /// value on the range 257 | public static float Factor_SubFactor(float factor, float subFrom, float subTo) 258 | { 259 | float length = subTo - subFrom; 260 | 261 | if (length <= 0.0f) 262 | { 263 | #if DEBUG 264 | Debug.LogWarning("subfactor length <= 0.0f. subFrom: " + subFrom + " subTo: " + subTo); 265 | #endif 266 | return 1.0f; 267 | } 268 | 269 | return (factor - subFrom) / length; 270 | } 271 | 272 | /// 273 | /// Takes a factor going 0.0->1.0 and makes it 0.0->1.0->0.0 274 | /// 275 | /// souce factor 276 | /// auto clamp source factor in looped way 277 | public static float Factor_ToTwoWay(float factor, bool autoClamp = true) 278 | { 279 | if (autoClamp == true) 280 | { 281 | while (factor < 0.0f) factor += 1.0f; 282 | while (factor > 1.0f) factor -= 1.0f; 283 | } 284 | 285 | if (factor < 0.5f) 286 | { 287 | return factor * 2.0f; 288 | } 289 | else 290 | { 291 | return (1.0f - factor) * 2.0f; 292 | } 293 | } 294 | 295 | 296 | public static float Factor_Repeated(float factor, int repetitionsCount, bool isPingPong) 297 | { 298 | if (repetitionsCount < 2) 299 | { 300 | #if DEBUG 301 | Debug.LogError("repetitionsCount: " + repetitionsCount); 302 | #endif 303 | return factor; 304 | } 305 | 306 | float repetitionsCountFloat = repetitionsCount; 307 | float curStep = (int)(repetitionsCountFloat * factor); 308 | 309 | if (factor >= 1.0f) 310 | { 311 | if (isPingPong == true) 312 | { 313 | if (repetitionsCount % 2 == 0) 314 | { 315 | return 0.0f; 316 | } 317 | } 318 | return 1.0f; 319 | } 320 | 321 | 322 | float factorStep = 1.0f / repetitionsCountFloat; 323 | 324 | float result = (factor - (curStep * factorStep)) / factorStep; 325 | 326 | if (isPingPong == true) 327 | { 328 | if (((int)(curStep)) % 2 == 1) 329 | { 330 | result = 1.0f - result; 331 | } 332 | } 333 | 334 | return result; 335 | 336 | } 337 | 338 | //======== 339 | //sequence 340 | //======== 341 | /// 342 | /// Returns an element index in a sequence [0; stepsCount - 1] based on current time and full time. Clamps if current time is out of bounds. 343 | /// 344 | /// 345 | /// 346 | /// 347 | public static int Sequence_Timed_Clamped(float curTime, float fullTime, int stepsCount) 348 | { 349 | Debug.Assert(fullTime > 0.0f); 350 | Debug.Assert(stepsCount > 0); 351 | 352 | int result = (int)(((float)(stepsCount)) * (curTime / fullTime)); 353 | 354 | result = Mathf.Clamp(result, 0, stepsCount - 1); 355 | 356 | return result; 357 | } 358 | 359 | /// 360 | /// Returns an element index in a sequence [0; stepsCount - 1] based on current time and full time. Loops if current time is out of bounds. 361 | /// 362 | /// 363 | /// 364 | /// 365 | public static int Sequence_Timed_Looped(float curTime, float fullTime, int stepsCount) 366 | { 367 | Debug.Assert(fullTime > 0.0f); 368 | Debug.Assert(stepsCount > 0); 369 | 370 | int result = (int)(((float)(stepsCount)) * (curTime / fullTime)); 371 | 372 | while (result >= stepsCount) 373 | { 374 | result -= stepsCount; 375 | } 376 | 377 | while (result < 0) 378 | { 379 | result += stepsCount; 380 | } 381 | 382 | return result; 383 | } 384 | 385 | /// 386 | /// Returns an element index in a sequence [0; stepsCount - 1] based on factor. Clamps if factor is out of bounds. 387 | /// 388 | /// 389 | /// 390 | public static int Sequence_FromFactor_Clamped(float curFactor, int stepsCount) 391 | { 392 | Debug.Assert(stepsCount > 0); 393 | 394 | int result = (int)(((float)(stepsCount)) * curFactor); 395 | 396 | result = Mathf.Clamp(result, 0, stepsCount - 1); 397 | 398 | return result; 399 | } 400 | 401 | /// 402 | /// Returns an element index in a sequence [0; stepsCount - 1] based on factor. Loops if factor is out of bounds. 403 | /// 404 | /// 405 | /// 406 | public static int Sequence_FromFactor_Looped(float curFactor, int stepsCount) 407 | { 408 | Debug.Assert(stepsCount > 0); 409 | 410 | int result = (int)(((float)(stepsCount)) * curFactor); 411 | 412 | while (result >= stepsCount) 413 | { 414 | result -= stepsCount; 415 | } 416 | 417 | while (result < 0) 418 | { 419 | result += stepsCount; 420 | } 421 | 422 | return result; 423 | } 424 | 425 | 426 | public static float Sequence_Interpolated_Looped(float curFactor, int stepsCount, out int stepFrom, out int stepTo) 427 | { 428 | #if DEBUG 429 | if (curFactor < 0.0f || curFactor >= 1.0f) 430 | { 431 | Debug.LogError("invalid curFactor: " + curFactor + ". factor should be clamped as looped! [0.0f; 1.0f)"); 432 | } 433 | #endif 434 | 435 | if (stepsCount < 2) 436 | { 437 | stepFrom = 0; 438 | stepTo = 0; 439 | return 0.0f; 440 | } 441 | 442 | float localFactorLength = 1.0f / stepsCount; 443 | 444 | stepFrom = 0; 445 | 446 | while (curFactor > localFactorLength) 447 | { 448 | curFactor -= localFactorLength; 449 | stepFrom++; 450 | } 451 | 452 | if (stepFrom == stepsCount) 453 | { 454 | stepFrom = 0; 455 | stepTo = 1; 456 | return 0.0f; 457 | } 458 | 459 | //step to 460 | stepTo = stepFrom + 1; 461 | 462 | if (stepTo == stepsCount) 463 | { 464 | stepTo = 0; 465 | } 466 | 467 | //returning local factor 468 | return curFactor / localFactorLength; 469 | } 470 | 471 | 472 | public static float Sequence_Interpolated(float curFactor, int stepsCount, out int stepFrom, out int stepTo) 473 | { 474 | if (stepsCount < 2) 475 | { 476 | stepFrom = 0; 477 | stepTo = 0; 478 | return 0.0f; 479 | } 480 | 481 | //start 482 | if (curFactor <= 0.0f) 483 | { 484 | stepFrom = 0; 485 | stepTo = 1; 486 | return 0.0f; 487 | } 488 | 489 | //end 490 | if (curFactor >= 1.0f) 491 | { 492 | stepFrom = stepsCount - 2; 493 | stepTo = stepsCount - 1; 494 | return 1.0f; 495 | } 496 | 497 | //middle 498 | float localFactorLength = 1.0f / (stepsCount - 1); 499 | 500 | stepFrom = 0; 501 | 502 | while (curFactor > localFactorLength) 503 | { 504 | curFactor -= localFactorLength; 505 | stepFrom++; 506 | } 507 | 508 | //step to 509 | stepTo = stepFrom + 1; 510 | 511 | if (stepTo == stepsCount) 512 | { 513 | stepTo = stepFrom; 514 | } 515 | 516 | //returning local factor 517 | return curFactor / localFactorLength; 518 | } 519 | 520 | //==== 521 | //swap 522 | //==== 523 | /// 524 | /// Swaps two values passed by reference 525 | /// 526 | /// 527 | /// 528 | public static void Swap(ref T a, ref T b) 529 | { 530 | var tmp = a; 531 | a = b; 532 | b = tmp; 533 | } 534 | 535 | 536 | //==== 537 | //misc 538 | //==== 539 | public static int DigitsInInteger(int number) 540 | { 541 | // In case of negative numbers 542 | number = Mathf.Abs(number); 543 | 544 | int digits = 1; 545 | 546 | while (number >= 10) 547 | { 548 | digits++; 549 | number /= 10; 550 | } 551 | 552 | return digits; 553 | } 554 | 555 | } 556 | } -------------------------------------------------------------------------------- /Assets/Scripts/MathHelpers.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b6c9afa083be9314fa2cdcd331f3463b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Scripts/SpriteBatcher.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | using UnityEngine.U2D; 4 | 5 | 6 | namespace vadersb.utils.unity 7 | { 8 | public class SpriteBatcher : MonoBehaviour 9 | { 10 | private const string ColorProperty = "_RendererColor"; 11 | private const string TextureProperty = "_MainTex"; 12 | 13 | private const int DefaultCapacity = 4096; 14 | 15 | [SerializeField] 16 | private SpriteAtlas m_SpriteAtlas = null; 17 | 18 | [SerializeField] 19 | private Color m_Color = Color.white; 20 | 21 | [SerializeField] 22 | private bool m_UseExtendedUVs = false; 23 | 24 | //material property block 25 | private MaterialPropertyBlock m_MaterialPropertyBlock; 26 | 27 | 28 | //sprite data 29 | private Sprite[] m_Sprites; 30 | private Vector2[][] m_Sprites_Vertices; 31 | private Vector2[][] m_Sprites_UVs; 32 | private ushort[][] m_Sprites_Triangles; 33 | 34 | //dynamic mesh 35 | private Mesh m_Mesh; 36 | 37 | private int m_Dynamic_IndexOffset; 38 | private List m_Dynamic_Vertices; 39 | 40 | private List m_Dynamic_UV1; 41 | private List m_Dynamic_UV2; 42 | private List m_Dynamic_UV3; 43 | private List m_Dynamic_UV4; 44 | 45 | private List m_Dynamic_Colors; 46 | private List m_Dynamic_Triangles; 47 | 48 | 49 | private void Awake() 50 | { 51 | RefreshSpritesList(); 52 | RefreshMaterialPropertyBlock(); 53 | ApplyMaterialPropertyBlock(); 54 | 55 | //creating a mesh 56 | m_Mesh = new Mesh(); 57 | m_Mesh.name = "SpriteBatcher dynamic mesh"; 58 | m_Mesh.MarkDynamic(); 59 | 60 | //mesh filter 61 | var meshFilter = GetComponent(); 62 | 63 | Debug.Assert(meshFilter != null); 64 | 65 | meshFilter.mesh = m_Mesh; 66 | 67 | //creating dynamic buffers 68 | m_Dynamic_IndexOffset = 0; 69 | m_Dynamic_Vertices = new List(DefaultCapacity); 70 | m_Dynamic_UV1 = new List(DefaultCapacity); 71 | m_Dynamic_UV2 = new List(DefaultCapacity); 72 | m_Dynamic_UV3 = new List(DefaultCapacity); 73 | m_Dynamic_UV4 = new List(DefaultCapacity); 74 | m_Dynamic_Colors = new List(DefaultCapacity); 75 | m_Dynamic_Triangles = new List(DefaultCapacity); 76 | } 77 | 78 | 79 | private void OnValidate() 80 | { 81 | RefreshSpritesList(); 82 | 83 | if (m_MaterialPropertyBlock != null) 84 | { 85 | RefreshMaterialPropertyBlock(); 86 | ApplyMaterialPropertyBlock(); 87 | } 88 | } 89 | 90 | //---------------------------------------------------------------------- 91 | //Settings 92 | public Color Color 93 | { 94 | get => m_Color; 95 | set 96 | { 97 | m_Color = value; 98 | if (m_MaterialPropertyBlock != null) 99 | { 100 | // ReSharper disable once Unity.PreferAddressByIdToGraphicsParams 101 | m_MaterialPropertyBlock.SetColor(ColorProperty, m_Color); 102 | ApplyMaterialPropertyBlock(); 103 | } 104 | } 105 | } 106 | 107 | //---------------------------------------------------------------------- 108 | //Finalizing the mesh 109 | public void CompleteMesh() 110 | { 111 | if (m_Dynamic_Triangles.Count == 0) 112 | { 113 | if (m_Mesh.vertexCount > 0) 114 | { 115 | m_Mesh.Clear(); 116 | } 117 | 118 | return; 119 | } 120 | 121 | m_Mesh.Clear(); 122 | 123 | m_Mesh.SetVertices(m_Dynamic_Vertices); 124 | m_Mesh.SetColors(m_Dynamic_Colors); 125 | m_Mesh.SetUVs(0, m_Dynamic_UV1); 126 | 127 | if (m_UseExtendedUVs == true) 128 | { 129 | m_Mesh.SetUVs(1, m_Dynamic_UV2); 130 | m_Mesh.SetUVs(2, m_Dynamic_UV3); 131 | m_Mesh.SetUVs(3, m_Dynamic_UV4); 132 | } 133 | 134 | m_Mesh.SetTriangles(m_Dynamic_Triangles, 0, false); 135 | 136 | m_Dynamic_Vertices.Clear(); 137 | m_Dynamic_Colors.Clear(); 138 | m_Dynamic_UV1.Clear(); 139 | m_Dynamic_UV2.Clear(); 140 | m_Dynamic_UV3.Clear(); 141 | m_Dynamic_UV4.Clear(); 142 | m_Dynamic_Triangles.Clear(); 143 | m_Dynamic_IndexOffset = 0; 144 | } 145 | 146 | public bool IsComplete => m_Dynamic_Vertices.Count == 0; 147 | 148 | //---------------------------------------------------------------------- 149 | //Getting sprite index 150 | public int GetSpriteIndex(Sprite sprite) 151 | { 152 | int nameSearchResult = GetSpriteIndex(sprite.name); 153 | 154 | if (nameSearchResult != -1) 155 | { 156 | return nameSearchResult; 157 | } 158 | 159 | for (int i = 0; i < m_SpriteAtlas.spriteCount; i++) 160 | { 161 | if (m_Sprites[i] == sprite) 162 | { 163 | return i; 164 | } 165 | } 166 | 167 | #if DEBUG 168 | Debug.LogError("Failed to find sprite: " + sprite.name + " in atlas: " + m_SpriteAtlas.name); 169 | #endif 170 | 171 | return -1; 172 | } 173 | 174 | public int GetSpriteIndex(string spriteName) 175 | { 176 | spriteName += "(Clone)"; 177 | 178 | for (int i = 0; i < m_SpriteAtlas.spriteCount; i++) 179 | { 180 | if (m_Sprites[i].name == spriteName) 181 | { 182 | return i; 183 | } 184 | } 185 | 186 | #if DEBUG 187 | Debug.LogError("Failed to find sprite: " + spriteName + " in atlas: " + m_SpriteAtlas.name); 188 | #endif 189 | 190 | return -1; 191 | } 192 | 193 | public Sprite GetSprite(string spriteName) 194 | { 195 | spriteName += "(Clone)"; 196 | 197 | for (int i = 0; i < m_SpriteAtlas.spriteCount; i++) 198 | { 199 | if (m_Sprites[i].name == spriteName) 200 | { 201 | return m_Sprites[i]; 202 | } 203 | } 204 | 205 | #if DEBUG 206 | Debug.LogError("Failed to find sprite: " + spriteName + " in atlas: " + m_SpriteAtlas.name); 207 | #endif 208 | 209 | return null; 210 | } 211 | 212 | //---------------------------------------------------------------------- 213 | //Drawing Sprites 214 | private static readonly Vector2 s_DefaultExtraUV = new Vector2(0.0f,0.0f); 215 | 216 | public void DrawSprite(int spriteIndex, Vector2 position, Color color) 217 | { 218 | //----- 219 | //index test 220 | if (spriteIndex < 0 || spriteIndex >= m_Sprites_Vertices.Length) 221 | { 222 | #if DEBUG 223 | Debug.LogError("invalid spriteIndex: " + spriteIndex + ""); 224 | #endif 225 | return; 226 | } 227 | 228 | //----- 229 | //Adding sprite geometry 230 | var vertices = m_Sprites_Vertices[spriteIndex]; 231 | var uvs = m_Sprites_UVs[spriteIndex]; 232 | var triangles = m_Sprites_Triangles[spriteIndex]; 233 | 234 | int count = vertices.Length; 235 | 236 | for (int i = 0; i < count; i++) 237 | { 238 | //vertex position 239 | var curVertex = vertices[i]; 240 | 241 | curVertex += position; //translation 242 | 243 | m_Dynamic_Vertices.Add(new Vector3(curVertex.x, curVertex.y, 0.0f)); 244 | 245 | //uv 246 | var curUV = uvs[i]; 247 | 248 | m_Dynamic_UV1.Add(curUV); 249 | 250 | //color 251 | m_Dynamic_Colors.Add(color); 252 | } 253 | 254 | //extra UVs 255 | if (m_UseExtendedUVs == true) 256 | { 257 | for (int i = 0; i < count; i++) 258 | { 259 | m_Dynamic_UV2.Add(s_DefaultExtraUV); 260 | m_Dynamic_UV3.Add(s_DefaultExtraUV); 261 | m_Dynamic_UV4.Add(s_DefaultExtraUV); 262 | } 263 | } 264 | 265 | count = triangles.Length; 266 | 267 | for (int i = 0; i < count; i++) 268 | { 269 | //index 270 | int curIndex = triangles[i]; 271 | 272 | m_Dynamic_Triangles.Add(curIndex + m_Dynamic_IndexOffset); 273 | } 274 | 275 | m_Dynamic_IndexOffset += vertices.Length; 276 | } 277 | 278 | public void DrawSprite(int spriteIndex, Vector2 position, float rotationAngle, Color color) 279 | { 280 | //----- 281 | //index test 282 | if (spriteIndex < 0 || spriteIndex >= m_Sprites_Vertices.Length) 283 | { 284 | #if DEBUG 285 | Debug.LogError("invalid spriteIndex: " + spriteIndex + ""); 286 | #endif 287 | return; 288 | } 289 | 290 | //rotationAngle = -rotationAngle; //to Unity coordinate system 291 | 292 | //----- 293 | //Adding sprite geometry 294 | var vertices = m_Sprites_Vertices[spriteIndex]; 295 | var uvs = m_Sprites_UVs[spriteIndex]; 296 | var triangles = m_Sprites_Triangles[spriteIndex]; 297 | 298 | int count = vertices.Length; 299 | 300 | for (int i = 0; i < count; i++) 301 | { 302 | //vertex position 303 | var curVertex = vertices[i]; 304 | 305 | curVertex = VectorTools.Rotate(curVertex, rotationAngle); //rotation 306 | 307 | curVertex += position; //translation 308 | 309 | m_Dynamic_Vertices.Add(new Vector3(curVertex.x, curVertex.y, 0.0f)); 310 | 311 | //uv 312 | var curUV = uvs[i]; 313 | 314 | m_Dynamic_UV1.Add(curUV); 315 | 316 | //color 317 | m_Dynamic_Colors.Add(color); 318 | } 319 | 320 | //extra UVs 321 | if (m_UseExtendedUVs == true) 322 | { 323 | for (int i = 0; i < count; i++) 324 | { 325 | m_Dynamic_UV2.Add(s_DefaultExtraUV); 326 | m_Dynamic_UV3.Add(s_DefaultExtraUV); 327 | m_Dynamic_UV4.Add(s_DefaultExtraUV); 328 | } 329 | } 330 | 331 | 332 | count = triangles.Length; 333 | 334 | for (int i = 0; i < count; i++) 335 | { 336 | //index 337 | int curIndex = triangles[i]; 338 | 339 | m_Dynamic_Triangles.Add(curIndex + m_Dynamic_IndexOffset); 340 | } 341 | 342 | m_Dynamic_IndexOffset += vertices.Length; 343 | } 344 | 345 | public void DrawSprite(int spriteIndex, Vector2 position, float rotationAngle, Vector2 scale, Color color) 346 | { 347 | //----- 348 | //index test 349 | if (spriteIndex < 0 || spriteIndex >= m_Sprites_Vertices.Length) 350 | { 351 | #if DEBUG 352 | Debug.LogError("invalid spriteIndex: " + spriteIndex + ""); 353 | #endif 354 | return; 355 | } 356 | 357 | //rotationAngle = -rotationAngle; //to Unity coordinate system 358 | 359 | //----- 360 | //Adding sprite geometry 361 | var vertices = m_Sprites_Vertices[spriteIndex]; 362 | var uvs = m_Sprites_UVs[spriteIndex]; 363 | var triangles = m_Sprites_Triangles[spriteIndex]; 364 | 365 | int count = vertices.Length; 366 | 367 | for (int i = 0; i < count; i++) 368 | { 369 | //vertex position 370 | var curVertex = vertices[i]; 371 | 372 | curVertex = VectorTools.Rotate(curVertex, rotationAngle); //rotation 373 | 374 | curVertex *= scale; //scale 375 | 376 | curVertex += position; //translation 377 | 378 | m_Dynamic_Vertices.Add(new Vector3(curVertex.x, curVertex.y, 0.0f)); 379 | 380 | //uv 381 | var curUV = uvs[i]; 382 | 383 | m_Dynamic_UV1.Add(curUV); 384 | 385 | //color 386 | m_Dynamic_Colors.Add(color); 387 | } 388 | 389 | //extra UVs 390 | if (m_UseExtendedUVs == true) 391 | { 392 | for (int i = 0; i < count; i++) 393 | { 394 | m_Dynamic_UV2.Add(s_DefaultExtraUV); 395 | m_Dynamic_UV3.Add(s_DefaultExtraUV); 396 | m_Dynamic_UV4.Add(s_DefaultExtraUV); 397 | } 398 | } 399 | 400 | count = triangles.Length; 401 | 402 | for (int i = 0; i < count; i++) 403 | { 404 | //index 405 | int curIndex = triangles[i]; 406 | 407 | m_Dynamic_Triangles.Add(curIndex + m_Dynamic_IndexOffset); 408 | } 409 | 410 | m_Dynamic_IndexOffset += vertices.Length; 411 | } 412 | 413 | public void DrawSprite(int spriteIndex, Vector2 position, float rotationAngle, float scale, Color color) 414 | { 415 | //----- 416 | //index test 417 | if (spriteIndex < 0 || spriteIndex >= m_Sprites_Vertices.Length) 418 | { 419 | #if DEBUG 420 | Debug.LogError("invalid spriteIndex: " + spriteIndex + ""); 421 | #endif 422 | return; 423 | } 424 | 425 | //rotationAngle = -rotationAngle; //to Unity coordinate system 426 | 427 | //----- 428 | //Adding sprite geometry 429 | var vertices = m_Sprites_Vertices[spriteIndex]; 430 | var uvs = m_Sprites_UVs[spriteIndex]; 431 | var triangles = m_Sprites_Triangles[spriteIndex]; 432 | 433 | int count = vertices.Length; 434 | 435 | for (int i = 0; i < count; i++) 436 | { 437 | //vertex position 438 | var curVertex = vertices[i]; 439 | 440 | curVertex = VectorTools.Rotate(curVertex, rotationAngle); //rotation 441 | 442 | curVertex *= scale; //scale 443 | 444 | curVertex += position; //translation 445 | 446 | m_Dynamic_Vertices.Add(new Vector3(curVertex.x, curVertex.y, 0.0f)); 447 | 448 | //uv 449 | var curUV = uvs[i]; 450 | 451 | m_Dynamic_UV1.Add(curUV); 452 | 453 | //color 454 | m_Dynamic_Colors.Add(color); 455 | } 456 | 457 | //extra UVs 458 | if (m_UseExtendedUVs == true) 459 | { 460 | for (int i = 0; i < count; i++) 461 | { 462 | m_Dynamic_UV2.Add(s_DefaultExtraUV); 463 | m_Dynamic_UV3.Add(s_DefaultExtraUV); 464 | m_Dynamic_UV4.Add(s_DefaultExtraUV); 465 | } 466 | } 467 | 468 | count = triangles.Length; 469 | 470 | for (int i = 0; i < count; i++) 471 | { 472 | //index 473 | int curIndex = triangles[i]; 474 | 475 | m_Dynamic_Triangles.Add(curIndex + m_Dynamic_IndexOffset); 476 | } 477 | 478 | m_Dynamic_IndexOffset += vertices.Length; 479 | } 480 | 481 | public void DrawSpriteQuad(SpriteQuad spriteQuad) 482 | { 483 | //----- 484 | //index test 485 | if (spriteQuad == null) 486 | { 487 | #if DEBUG 488 | Debug.LogError("spriteQuad is null!"); 489 | #endif 490 | return; 491 | } 492 | 493 | //----- 494 | //Adding sprite geometry 495 | 496 | for (int i = 0; i < SpriteQuad.VerticesCount; i++) 497 | { 498 | //vertex position 499 | m_Dynamic_Vertices.Add(spriteQuad.m_Vertices[i]); 500 | 501 | //uv 502 | m_Dynamic_UV1.Add(spriteQuad.m_UV1[i]); 503 | 504 | //color 505 | m_Dynamic_Colors.Add(spriteQuad.m_Colors[i]); 506 | } 507 | 508 | //uv2 509 | if (m_UseExtendedUVs == true) 510 | { 511 | for (int i = 0; i < SpriteQuad.VerticesCount; i++) 512 | { 513 | m_Dynamic_UV2.Add(spriteQuad.m_UV2[i]); 514 | m_Dynamic_UV3.Add(spriteQuad.m_UV3[i]); 515 | m_Dynamic_UV4.Add(spriteQuad.m_UV4[i]); 516 | } 517 | } 518 | 519 | for (int i = 0; i < SpriteQuad.IndicesCount; i++) 520 | { 521 | //index 522 | m_Dynamic_Triangles.Add(spriteQuad.m_Triangles[i] + m_Dynamic_IndexOffset); 523 | } 524 | 525 | m_Dynamic_IndexOffset += SpriteQuad.VerticesCount; 526 | } 527 | 528 | public void DrawMesh(Vector2[] vertices, Vector2[] uv1, Color[] colors, int[] triangles, Vector2[] uv2 = null, Vector2[] uv3 = null, Vector2[] uv4 = null) 529 | { 530 | var verticesCount = vertices.Length; 531 | 532 | if (verticesCount == 0) 533 | { 534 | return; 535 | } 536 | 537 | Debug.Assert(uv1.Length == verticesCount); 538 | Debug.Assert(colors.Length == verticesCount); 539 | 540 | var indicesCount = triangles.Length; 541 | 542 | if (indicesCount == 0) 543 | { 544 | return; 545 | } 546 | 547 | //----- 548 | //Adding sprite geometry 549 | 550 | for (int i = 0; i < verticesCount; i++) 551 | { 552 | //vertex position 553 | m_Dynamic_Vertices.Add(vertices[i]); 554 | 555 | //uv 556 | m_Dynamic_UV1.Add(uv1[i]); 557 | 558 | //color 559 | m_Dynamic_Colors.Add(colors[i]); 560 | } 561 | 562 | //extended uvs 563 | if (m_UseExtendedUVs == true) 564 | { 565 | Debug.Assert(uv2 != null); 566 | Debug.Assert(uv2.Length == verticesCount); 567 | 568 | Debug.Assert(uv3 != null); 569 | Debug.Assert(uv3.Length == verticesCount); 570 | 571 | Debug.Assert(uv4 != null); 572 | Debug.Assert(uv4.Length == verticesCount); 573 | 574 | for (int i = 0; i < verticesCount; i++) 575 | { 576 | m_Dynamic_UV2.Add(uv2[i]); 577 | m_Dynamic_UV3.Add(uv3[i]); 578 | m_Dynamic_UV4.Add(uv4[i]); 579 | } 580 | } 581 | 582 | for (int i = 0; i < indicesCount; i++) 583 | { 584 | //index 585 | m_Dynamic_Triangles.Add(triangles[i] + m_Dynamic_IndexOffset); 586 | } 587 | 588 | m_Dynamic_IndexOffset += verticesCount; 589 | } 590 | 591 | public void DrawMesh(Vector2[] vertices, Vector2[] uv1, Color color, int[] triangles, Vector2[] uv2 = null, Vector2[] uv3 = null, Vector2[] uv4 = null) 592 | { 593 | var verticesCount = vertices.Length; 594 | 595 | if (verticesCount == 0) 596 | { 597 | return; 598 | } 599 | 600 | Debug.Assert(uv1.Length == verticesCount); 601 | 602 | var indicesCount = triangles.Length; 603 | 604 | if (indicesCount == 0) 605 | { 606 | return; 607 | } 608 | 609 | //----- 610 | //Adding sprite geometry 611 | 612 | for (int i = 0; i < verticesCount; i++) 613 | { 614 | //vertex position 615 | m_Dynamic_Vertices.Add(vertices[i]); 616 | 617 | //uv 618 | m_Dynamic_UV1.Add(uv1[i]); 619 | 620 | //color 621 | m_Dynamic_Colors.Add(color); 622 | } 623 | 624 | //extended uvs 625 | if (m_UseExtendedUVs == true) 626 | { 627 | Debug.Assert(uv2 != null); 628 | Debug.Assert(uv2.Length == verticesCount); 629 | 630 | Debug.Assert(uv3 != null); 631 | Debug.Assert(uv3.Length == verticesCount); 632 | 633 | Debug.Assert(uv4 != null); 634 | Debug.Assert(uv4.Length == verticesCount); 635 | 636 | for (int i = 0; i < verticesCount; i++) 637 | { 638 | m_Dynamic_UV2.Add(uv2[i]); 639 | m_Dynamic_UV3.Add(uv3[i]); 640 | m_Dynamic_UV4.Add(uv4[i]); 641 | } 642 | } 643 | 644 | for (int i = 0; i < indicesCount; i++) 645 | { 646 | //index 647 | m_Dynamic_Triangles.Add(triangles[i] + m_Dynamic_IndexOffset); 648 | } 649 | 650 | m_Dynamic_IndexOffset += verticesCount; 651 | } 652 | 653 | public void DrawMesh(List vertices, List uv1, List colors, List triangles, List uv2 = null, List uv3 = null, List uv4 = null) 654 | { 655 | if (vertices == null) return; 656 | 657 | var verticesCount = vertices.Count; 658 | 659 | if (verticesCount == 0) 660 | { 661 | return; 662 | } 663 | 664 | Debug.Assert(uv1.Count == verticesCount); 665 | Debug.Assert(colors.Count == verticesCount); 666 | 667 | var indicesCount = triangles.Count; 668 | 669 | if (indicesCount == 0) 670 | { 671 | return; 672 | } 673 | 674 | //----- 675 | //Adding sprite geometry 676 | 677 | for (int i = 0; i < verticesCount; i++) 678 | { 679 | //vertex position 680 | m_Dynamic_Vertices.Add(vertices[i]); 681 | 682 | //uv 683 | m_Dynamic_UV1.Add(uv1[i]); 684 | 685 | //color 686 | m_Dynamic_Colors.Add(colors[i]); 687 | } 688 | 689 | //extended uvs 690 | if (m_UseExtendedUVs == true) 691 | { 692 | Debug.Assert(uv2 != null); 693 | Debug.Assert(uv2.Count == verticesCount); 694 | 695 | Debug.Assert(uv3 != null); 696 | Debug.Assert(uv3.Count == verticesCount); 697 | 698 | Debug.Assert(uv4 != null); 699 | Debug.Assert(uv4.Count == verticesCount); 700 | 701 | for (int i = 0; i < verticesCount; i++) 702 | { 703 | m_Dynamic_UV2.Add(uv2[i]); 704 | m_Dynamic_UV3.Add(uv3[i]); 705 | m_Dynamic_UV4.Add(uv4[i]); 706 | } 707 | } 708 | 709 | for (int i = 0; i < indicesCount; i++) 710 | { 711 | //index 712 | m_Dynamic_Triangles.Add(triangles[i] + m_Dynamic_IndexOffset); 713 | } 714 | 715 | m_Dynamic_IndexOffset += verticesCount; 716 | } 717 | 718 | public void DrawMesh(List vertices, List uv1, Color color, List triangles, List uv2 = null, List uv3 = null, List uv4 = null) 719 | { 720 | if (vertices == null) return; 721 | 722 | var verticesCount = vertices.Count; 723 | 724 | if (verticesCount == 0) 725 | { 726 | return; 727 | } 728 | 729 | Debug.Assert(uv1.Count == verticesCount); 730 | 731 | var indicesCount = triangles.Count; 732 | 733 | if (indicesCount == 0) 734 | { 735 | return; 736 | } 737 | 738 | //----- 739 | //Adding sprite geometry 740 | 741 | for (int i = 0; i < verticesCount; i++) 742 | { 743 | //vertex position 744 | m_Dynamic_Vertices.Add(vertices[i]); 745 | 746 | //uv 747 | m_Dynamic_UV1.Add(uv1[i]); 748 | 749 | //color 750 | m_Dynamic_Colors.Add(color); 751 | } 752 | 753 | //extended uvs 754 | if (m_UseExtendedUVs == true) 755 | { 756 | Debug.Assert(uv2 != null); 757 | Debug.Assert(uv2.Count == verticesCount); 758 | 759 | Debug.Assert(uv3 != null); 760 | Debug.Assert(uv3.Count == verticesCount); 761 | 762 | Debug.Assert(uv4 != null); 763 | Debug.Assert(uv4.Count == verticesCount); 764 | 765 | for (int i = 0; i < verticesCount; i++) 766 | { 767 | m_Dynamic_UV2.Add(uv2[i]); 768 | m_Dynamic_UV3.Add(uv3[i]); 769 | m_Dynamic_UV4.Add(uv4[i]); 770 | } 771 | } 772 | 773 | for (int i = 0; i < indicesCount; i++) 774 | { 775 | //index 776 | m_Dynamic_Triangles.Add(triangles[i] + m_Dynamic_IndexOffset); 777 | } 778 | 779 | m_Dynamic_IndexOffset += verticesCount; 780 | } 781 | 782 | //---------------------------------------------------------------------- 783 | //Helper functions 784 | private void RefreshSpritesList() 785 | { 786 | m_Sprites = null; 787 | 788 | if (m_SpriteAtlas == null) return; 789 | 790 | m_Sprites = new Sprite[m_SpriteAtlas.spriteCount]; 791 | 792 | m_SpriteAtlas.GetSprites(m_Sprites); 793 | 794 | //sprites vertices 795 | m_Sprites_Vertices = new Vector2[m_Sprites.Length][]; 796 | 797 | for (int i = 0; i < m_Sprites.Length; i++) 798 | { 799 | m_Sprites_Vertices[i] = m_Sprites[i].vertices; 800 | } 801 | 802 | //sprites uvs 803 | m_Sprites_UVs = new Vector2[m_Sprites.Length][]; 804 | 805 | for (int i = 0; i < m_Sprites.Length; i++) 806 | { 807 | m_Sprites_UVs[i] = m_Sprites[i].uv; 808 | } 809 | 810 | //sprites triangles 811 | m_Sprites_Triangles = new ushort[m_Sprites.Length][]; 812 | 813 | for (int i = 0; i < m_Sprites.Length; i++) 814 | { 815 | m_Sprites_Triangles[i] = m_Sprites[i].triangles; 816 | } 817 | } 818 | 819 | 820 | private void RefreshMaterialPropertyBlock() 821 | { 822 | m_MaterialPropertyBlock = new MaterialPropertyBlock(); 823 | 824 | Texture2D texture = null; 825 | 826 | if (m_Sprites.Length > 0) 827 | { 828 | texture = m_Sprites[0].texture; 829 | } 830 | 831 | // ReSharper disable once Unity.PreferAddressByIdToGraphicsParams 832 | m_MaterialPropertyBlock.SetTexture(TextureProperty, texture); 833 | // ReSharper disable once Unity.PreferAddressByIdToGraphicsParams 834 | m_MaterialPropertyBlock.SetColor(ColorProperty, m_Color); 835 | 836 | //test flip 837 | //m_MaterialPropertyBlock.SetVector("_Flip", new Vector4(1.0f, 1.0f, 0.0f, 0.0f)); 838 | } 839 | 840 | 841 | private void ApplyMaterialPropertyBlock() 842 | { 843 | var myRenderer = GetComponent(); 844 | 845 | if (myRenderer != null) 846 | { 847 | myRenderer.SetPropertyBlock(m_MaterialPropertyBlock, 0); 848 | } 849 | } 850 | } 851 | } -------------------------------------------------------------------------------- /Assets/Scripts/SpriteBatcher.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1118bd77a3876a04db7fe3aa12817e8f 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Scripts/SpriteQuad.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using vadersb.utils; 3 | 4 | namespace vadersb.utils.unity 5 | { 6 | public class SpriteQuad 7 | { 8 | public const int VerticesCount = 4; 9 | public const int IndicesCount = 6; 10 | 11 | public const int Index_TopLeft = 0; 12 | public const int Index_TopRight = 1; 13 | public const int Index_BottomLeft = 2; 14 | public const int Index_BottomRight = 3; 15 | 16 | //INDICES: 17 | //0 1 2 18 | //2 1 3 19 | 20 | //VERTICES 21 | //0---1 22 | //| /| 23 | //| / | 24 | //|/ | 25 | //2---3 26 | 27 | //UVS 28 | //[0;1] [1;1] 29 | // 30 | // 31 | //[0;0] [1;0] 32 | public readonly Vector2[] m_Vertices_Original; 33 | public readonly Vector2[] m_Vertices; 34 | public readonly Vector2[] m_UV1_Original; 35 | public readonly Vector2[] m_UV1; 36 | 37 | public readonly Vector2[] m_UV2; 38 | public readonly Vector2[] m_UV3; 39 | public readonly Vector2[] m_UV4; 40 | 41 | public readonly Color[] m_Colors; 42 | public readonly ushort[] m_Triangles; 43 | 44 | private float m_Width; 45 | private float m_Height; 46 | 47 | public float Width => m_Width; 48 | public float Height => m_Height; 49 | 50 | public SpriteQuad() 51 | { 52 | m_Vertices_Original = new Vector2[VerticesCount]; 53 | m_Vertices = new Vector2[VerticesCount]; 54 | m_UV1_Original = new Vector2[VerticesCount]; 55 | m_UV1 = new Vector2[VerticesCount]; 56 | m_UV2 = new Vector2[VerticesCount]; 57 | m_UV3 = new Vector2[VerticesCount]; 58 | m_UV4 = new Vector2[VerticesCount]; 59 | m_Colors = new Color[VerticesCount]; 60 | m_Triangles = new ushort[IndicesCount]; 61 | m_Width = m_Height = 0; 62 | 63 | //triangles 64 | m_Triangles[0] = 0; 65 | m_Triangles[1] = 1; 66 | m_Triangles[2] = 2; 67 | m_Triangles[3] = 2; 68 | m_Triangles[4] = 1; 69 | m_Triangles[5] = 3; 70 | } 71 | 72 | 73 | public void Reset() 74 | { 75 | //vertices 76 | m_Vertices_Original[Index_TopLeft] = new Vector2(-0.5f, 0.5f); 77 | m_Vertices_Original[Index_TopRight] = new Vector2(0.5f, 0.5f); 78 | m_Vertices_Original[Index_BottomLeft] = new Vector2(-0.5f, -0.5f); 79 | m_Vertices_Original[Index_BottomRight] = new Vector2(0.5f, -0.5f); 80 | 81 | Recalculate_WidthHeight(); 82 | Vertices_Reset(); 83 | 84 | //uvs 85 | m_UV1_Original[Index_TopLeft] = new Vector2(0.0f, 1.0f); 86 | m_UV1_Original[Index_TopRight] = new Vector2(1.0f, 1.0f); 87 | m_UV1_Original[Index_BottomLeft] = new Vector2(0.0f, 0.0f); 88 | m_UV1_Original[Index_BottomRight] = new Vector2(1.0f, 0.0f); 89 | 90 | UV1_Reset(); 91 | 92 | //uv2 93 | UV2_Reset(); 94 | 95 | //uv3 96 | UV3_Reset(); 97 | 98 | //uv4 99 | UV4_Reset(); 100 | 101 | //colors 102 | Colors_Reset(); 103 | 104 | //triangles 105 | m_Triangles[0] = 0; 106 | m_Triangles[1] = 1; 107 | m_Triangles[2] = 2; 108 | m_Triangles[3] = 2; 109 | m_Triangles[4] = 1; 110 | m_Triangles[5] = 3; 111 | } 112 | 113 | //------------------------------------------------------------ 114 | //Vertices 115 | public void Vertices_Reset() 116 | { 117 | for (int i = 0; i < VerticesCount; i++) 118 | { 119 | m_Vertices[i] = m_Vertices_Original[i]; 120 | } 121 | } 122 | 123 | public void Vertices_Move(Vector2 delta) 124 | { 125 | for (int i = 0; i < VerticesCount; i++) 126 | { 127 | m_Vertices[i] += delta; 128 | } 129 | } 130 | 131 | public void Vertices_MoveX(float deltaX) 132 | { 133 | for (int i = 0; i < VerticesCount; i++) 134 | { 135 | m_Vertices[i].x += deltaX; 136 | } 137 | } 138 | 139 | public void Vertices_MoveY(float deltaY) 140 | { 141 | for (int i = 0; i < VerticesCount; i++) 142 | { 143 | m_Vertices[i].y += deltaY; 144 | } 145 | } 146 | 147 | /// 148 | /// Rotates vertices by supplied angle in radians 149 | /// 150 | /// angle in radians. positive angle == CCW rotation in Unity! 151 | public void Vertices_Rotate(float angle) 152 | { 153 | //angle = -angle; //cw rotation is negative in Unity 154 | 155 | for (int i = 0; i < VerticesCount; i++) 156 | { 157 | m_Vertices[i] = VectorTools.Rotate(m_Vertices[i], angle); 158 | } 159 | } 160 | 161 | public void Vertices_Scale(Vector2 scale) 162 | { 163 | for (int i = 0; i < VerticesCount; i++) 164 | { 165 | m_Vertices[i] *= scale; 166 | } 167 | } 168 | 169 | public void Vertices_Scale(float scale) 170 | { 171 | for (int i = 0; i < VerticesCount; i++) 172 | { 173 | m_Vertices[i] *= scale; 174 | } 175 | } 176 | 177 | public void Vertices_ScaleX(float scaleX) 178 | { 179 | for (int i = 0; i < VerticesCount; i++) 180 | { 181 | m_Vertices[i].x *= scaleX; 182 | } 183 | } 184 | 185 | public void Vertices_ScaleY(float scaleY) 186 | { 187 | for (int i = 0; i < VerticesCount; i++) 188 | { 189 | m_Vertices[i].y *= scaleY; 190 | } 191 | } 192 | 193 | /// 194 | /// Setup quad as a line from one point to another with width == SpriteQuad.Width 195 | /// 196 | /// a point between vertices 2 and 3 197 | /// a point between vertices 0 and 1 198 | public void Vertices_FromTo(Vector2 from, Vector2 to) 199 | { 200 | Vector2 fromTo = to - from; 201 | 202 | Vector2 normal = fromTo.GetNormal(); 203 | normal *= (m_Width * 0.5f); 204 | 205 | //from: vertices 2 and 3 206 | m_Vertices[Index_BottomLeft] = from - normal; 207 | m_Vertices[Index_BottomRight] = from + normal; 208 | 209 | //to: vertices 0 and 1 210 | m_Vertices[Index_TopLeft] = to - normal; 211 | m_Vertices[Index_TopRight] = to + normal; 212 | } 213 | 214 | /// 215 | /// Setup quad as a line from one point to another with width == SpriteQuad.Width 216 | /// 217 | /// a point between vertices 2 and 3 218 | /// a point between vertices 0 and 1 219 | /// from side width 220 | /// to side width 221 | public void Vertices_FromTo(Vector2 from, Vector2 to, float fromWidth, float toWidth) 222 | { 223 | Vector2 fromTo = to - from; 224 | 225 | Vector2 normal = fromTo.GetNormal(); 226 | Vector2 normalFrom = normal *= (fromWidth * 0.5f); 227 | Vector2 normalTo = normal *= (toWidth * 0.5f); 228 | 229 | //from: vertices 2 and 3 230 | m_Vertices[Index_BottomLeft] = from - normalFrom; 231 | m_Vertices[Index_BottomRight] = from + normalFrom; 232 | 233 | //to: vertices 0 and 1 234 | m_Vertices[Index_TopLeft] = to - normalTo; 235 | m_Vertices[Index_TopRight] = to + normalTo; 236 | } 237 | 238 | //------------------------------------------------------------ 239 | //UVs 240 | public void UV1_Reset() 241 | { 242 | for (int i = 0; i < VerticesCount; i++) 243 | { 244 | m_UV1[i] = m_UV1_Original[i]; 245 | } 246 | } 247 | 248 | public void UV1_Move(Vector2 delta) 249 | { 250 | for (int i = 0; i < VerticesCount; i++) 251 | { 252 | m_UV1[i] += delta; 253 | } 254 | } 255 | 256 | public void UV1_MoveX(float delta) 257 | { 258 | for (int i = 0; i < VerticesCount; i++) 259 | { 260 | m_UV1[i].x += delta; 261 | } 262 | } 263 | 264 | public void UV1_MoveY(float delta) 265 | { 266 | for (int i = 0; i < VerticesCount; i++) 267 | { 268 | m_UV1[i].y += delta; 269 | } 270 | } 271 | 272 | 273 | public void UV1_SetUniform(Vector2 value) 274 | { 275 | for (int i = 0; i < VerticesCount; i++) 276 | { 277 | m_UV1[i] = value; 278 | } 279 | } 280 | 281 | public void UV1_SetFromAnotherOriginal(SpriteQuad anotherQuad) 282 | { 283 | Debug.Assert(anotherQuad != null); 284 | 285 | m_UV1[Index_TopLeft] = anotherQuad.m_UV1_Original[Index_TopLeft]; 286 | m_UV1[Index_TopRight] = anotherQuad.m_UV1_Original[Index_TopRight]; 287 | m_UV1[Index_BottomLeft] = anotherQuad.m_UV1_Original[Index_BottomLeft]; 288 | m_UV1[Index_BottomRight] = anotherQuad.m_UV1_Original[Index_BottomRight]; 289 | } 290 | 291 | //------------------------------------------------------------ 292 | //UV2 293 | public void UV2_Reset() 294 | { 295 | m_UV2[Index_TopLeft] = new Vector2(0.0f, 1.0f); 296 | m_UV2[Index_TopRight] = new Vector2(1.0f, 1.0f); 297 | m_UV2[Index_BottomLeft] = new Vector2(0.0f, 0.0f); 298 | m_UV2[Index_BottomRight] = new Vector2(1.0f, 0.0f); 299 | } 300 | 301 | public void UV2_SetFromOriginal() 302 | { 303 | m_UV2[Index_TopLeft] = m_UV1_Original[Index_TopLeft]; 304 | m_UV2[Index_TopRight] = m_UV1_Original[Index_TopRight]; 305 | m_UV2[Index_BottomLeft] = m_UV1_Original[Index_BottomLeft]; 306 | m_UV2[Index_BottomRight] = m_UV1_Original[Index_BottomRight]; 307 | } 308 | 309 | public void UV2_SetFromAnotherOriginal(SpriteQuad anotherQuad) 310 | { 311 | Debug.Assert(anotherQuad != null); 312 | 313 | m_UV2[Index_TopLeft] = anotherQuad.m_UV1_Original[Index_TopLeft]; 314 | m_UV2[Index_TopRight] = anotherQuad.m_UV1_Original[Index_TopRight]; 315 | m_UV2[Index_BottomLeft] = anotherQuad.m_UV1_Original[Index_BottomLeft]; 316 | m_UV2[Index_BottomRight] = anotherQuad.m_UV1_Original[Index_BottomRight]; 317 | } 318 | 319 | public void UV2_SetUniform(Vector2 value) 320 | { 321 | for (int i = 0; i < VerticesCount; i++) 322 | { 323 | m_UV2[i] = value; 324 | } 325 | } 326 | 327 | //------------------------------------------------------------ 328 | //UV3 329 | public void UV3_Reset() 330 | { 331 | m_UV3[Index_TopLeft] = new Vector2(0.0f, 1.0f); 332 | m_UV3[Index_TopRight] = new Vector2(1.0f, 1.0f); 333 | m_UV3[Index_BottomLeft] = new Vector2(0.0f, 0.0f); 334 | m_UV3[Index_BottomRight] = new Vector2(1.0f, 0.0f); 335 | } 336 | 337 | public void UV3_SetFromOriginal() 338 | { 339 | m_UV3[Index_TopLeft] = m_UV1_Original[Index_TopLeft]; 340 | m_UV3[Index_TopRight] = m_UV1_Original[Index_TopRight]; 341 | m_UV3[Index_BottomLeft] = m_UV1_Original[Index_BottomLeft]; 342 | m_UV3[Index_BottomRight] = m_UV1_Original[Index_BottomRight]; 343 | } 344 | 345 | public void UV3_SetFromAnotherOriginal(SpriteQuad anotherQuad) 346 | { 347 | Debug.Assert(anotherQuad != null); 348 | 349 | m_UV3[Index_TopLeft] = anotherQuad.m_UV1_Original[Index_TopLeft]; 350 | m_UV3[Index_TopRight] = anotherQuad.m_UV1_Original[Index_TopRight]; 351 | m_UV3[Index_BottomLeft] = anotherQuad.m_UV1_Original[Index_BottomLeft]; 352 | m_UV3[Index_BottomRight] = anotherQuad.m_UV1_Original[Index_BottomRight]; 353 | } 354 | 355 | public void UV3_SetUniform(Vector2 value) 356 | { 357 | for (int i = 0; i < VerticesCount; i++) 358 | { 359 | m_UV3[i] = value; 360 | } 361 | } 362 | 363 | //------------------------------------------------------------ 364 | //UV4 365 | public void UV4_Reset() 366 | { 367 | m_UV4[Index_TopLeft] = new Vector2(0.0f, 1.0f); 368 | m_UV4[Index_TopRight] = new Vector2(1.0f, 1.0f); 369 | m_UV4[Index_BottomLeft] = new Vector2(0.0f, 0.0f); 370 | m_UV4[Index_BottomRight] = new Vector2(1.0f, 0.0f); 371 | } 372 | 373 | public void UV4_SetFromOriginal() 374 | { 375 | m_UV4[Index_TopLeft] = m_UV1_Original[Index_TopLeft]; 376 | m_UV4[Index_TopRight] = m_UV1_Original[Index_TopRight]; 377 | m_UV4[Index_BottomLeft] = m_UV1_Original[Index_BottomLeft]; 378 | m_UV4[Index_BottomRight] = m_UV1_Original[Index_BottomRight]; 379 | } 380 | 381 | public void UV4_SetFromAnotherOriginal(SpriteQuad anotherQuad) 382 | { 383 | Debug.Assert(anotherQuad != null); 384 | 385 | m_UV4[Index_TopLeft] = anotherQuad.m_UV1_Original[Index_TopLeft]; 386 | m_UV4[Index_TopRight] = anotherQuad.m_UV1_Original[Index_TopRight]; 387 | m_UV4[Index_BottomLeft] = anotherQuad.m_UV1_Original[Index_BottomLeft]; 388 | m_UV4[Index_BottomRight] = anotherQuad.m_UV1_Original[Index_BottomRight]; 389 | } 390 | 391 | public void UV4_SetUniform(Vector2 value) 392 | { 393 | for (int i = 0; i < VerticesCount; i++) 394 | { 395 | m_UV4[i] = value; 396 | } 397 | } 398 | 399 | //------------------------------------------------------------ 400 | //Colors 401 | public void Colors_Reset() 402 | { 403 | for (int i = 0; i < VerticesCount; i++) 404 | { 405 | m_Colors[i] = Color.white; 406 | } 407 | } 408 | 409 | public void Colors_Reset(Color color) 410 | { 411 | for (int i = 0; i < VerticesCount; i++) 412 | { 413 | m_Colors[i] = color; 414 | } 415 | } 416 | 417 | public void Colors_SetAlpha(float alpha) 418 | { 419 | for (int i = 0; i < VerticesCount; i++) 420 | { 421 | m_Colors[i].a = alpha; 422 | } 423 | } 424 | 425 | 426 | public void Colors_SetAlphaFromTo(float fromAlpha, float toAlpha) 427 | { 428 | m_Colors[Index_BottomLeft].a = fromAlpha; 429 | m_Colors[Index_BottomRight].a = fromAlpha; 430 | m_Colors[Index_TopLeft].a = toAlpha; 431 | m_Colors[Index_TopRight].a = toAlpha; 432 | } 433 | 434 | //------------------------------------------------------------ 435 | //Setup 436 | public void SetupFromSprite(Sprite sprite) 437 | { 438 | if (sprite == null) 439 | { 440 | Debug.LogError("sprite is null!"); 441 | Reset(); 442 | return; 443 | } 444 | 445 | if (sprite.packingMode != SpritePackingMode.Rectangle) 446 | { 447 | Debug.LogError("Unsupported sprite packing mode: " + sprite.packingMode + " in sprite: " + sprite.name); 448 | Reset(); 449 | return; 450 | } 451 | 452 | //----- 453 | //vertices 454 | var spriteVertices = sprite.vertices; 455 | 456 | Debug.Assert(spriteVertices.Length == VerticesCount); 457 | 458 | //uvs 459 | var spriteUVs = sprite.uv; 460 | 461 | Debug.Assert(spriteUVs.Length == VerticesCount); 462 | 463 | 464 | //copying vertices and uvs 465 | for (int i = 0; i < VerticesCount; i++) 466 | { 467 | m_Vertices_Original[i] = spriteVertices[i]; 468 | m_UV1_Original[i] = spriteUVs[i]; 469 | } 470 | 471 | Recalculate_WidthHeight(); 472 | Vertices_Reset(); 473 | UV1_Reset(); 474 | UV2_Reset(); 475 | UV3_Reset(); 476 | UV4_Reset(); 477 | 478 | //----- 479 | //triangles 480 | var spriteTriangles = sprite.triangles; 481 | 482 | Debug.Assert(spriteTriangles.Length == IndicesCount); 483 | 484 | //copying triangles 485 | for (int i = 0; i < IndicesCount; i++) 486 | { 487 | #if DEBUG 488 | if (m_Triangles[i] != spriteTriangles[i]) 489 | { 490 | Debug.LogWarning("Unexpected index data in sprite!"); 491 | } 492 | #endif 493 | m_Triangles[i] = spriteTriangles[i]; 494 | } 495 | 496 | //----- 497 | //colors reset 498 | Colors_Reset(); 499 | } 500 | 501 | public void SetupFromSpriteBatcher(SpriteBatcher spriteBatcher, string spriteName) 502 | { 503 | var curSprite = spriteBatcher.GetSprite(spriteName); 504 | 505 | if (curSprite != null) 506 | { 507 | SetupFromSprite(curSprite); 508 | } 509 | else 510 | { 511 | Debug.LogError("Failed to find sprite " + spriteName + " in SpriteBatcher!"); 512 | } 513 | } 514 | 515 | 516 | //------------------------------------------------------------ 517 | //Helpers 518 | public void Recalculate_WidthHeight() 519 | { 520 | m_Width = m_Vertices_Original[0].GetDistanceTo(m_Vertices_Original[1]); 521 | m_Height = m_Vertices_Original[0].GetDistanceTo(m_Vertices_Original[2]); 522 | } 523 | } 524 | } -------------------------------------------------------------------------------- /Assets/Scripts/SpriteQuad.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6b8ce8ecc47327a4e92d6cda3e74415b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Scripts/Tests.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 89f6ff72f1303804a86980a16afd9e63 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scripts/Tests/SimpleSpritesSimulator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using vadersb.utils; 5 | using vadersb.utils.unity; 6 | 7 | public class SimpleSpritesSimulator : MonoBehaviour 8 | { 9 | public Camera m_Camera; 10 | 11 | public float m_X_Min = -3; 12 | public float m_X_Max = 3; 13 | 14 | public float m_Y_Min = -3; 15 | public float m_Y_Max = 3; 16 | 17 | public float m_SpeedMin = 0.1f; 18 | public float m_SpeedMax = 1.0f; 19 | 20 | public int m_SpritesCount = 1000; 21 | 22 | public SpriteBatcher m_Batcher; 23 | 24 | public bool m_DebugUseFixedTimeDelta = true; 25 | 26 | private class SpriteData 27 | { 28 | public Vector2 m_Coords; 29 | public Color m_Color; 30 | 31 | public bool m_HorLeft; 32 | public bool m_VerUp; 33 | 34 | public float m_SpeedMult; 35 | 36 | public int m_SpriteIndex; 37 | 38 | public float m_Angle; 39 | 40 | public float m_Scale; 41 | } 42 | 43 | private List m_Sprites; 44 | 45 | // Start is called before the first frame update 46 | void Start() 47 | { 48 | 49 | WeightedRandomizer m_Randomizer = new WeightedRandomizer(); 50 | 51 | m_Randomizer.AddValue(Color.black, 1.0f); 52 | m_Randomizer.AddValue(Color.blue, 1.0f); 53 | m_Randomizer.AddValue(Color.green, 1.0f); 54 | m_Randomizer.AddValue(Color.red, 1.0f); 55 | m_Randomizer.AddValue(Color.white, 50.0f); 56 | 57 | float minX = m_X_Min; 58 | float maxX = m_X_Max; 59 | float minY = m_Y_Min; 60 | float maxY = m_Y_Max; 61 | 62 | //getting camera bounds 63 | if (m_Camera) 64 | { 65 | float halfSize = m_Camera.orthographicSize; 66 | float ratio = m_Camera.aspect; 67 | 68 | minY = -halfSize; 69 | maxY = halfSize; 70 | 71 | minX = -halfSize * ratio; 72 | maxX = halfSize * ratio; 73 | } 74 | 75 | 76 | //generate sprites 77 | m_Sprites = new List(m_SpritesCount); 78 | 79 | for (int i = 0; i < m_SpritesCount; i++) 80 | { 81 | var newSprite = new SpriteData(); 82 | 83 | newSprite.m_Coords.x = MathHelpers.Random_Float(minX, maxX); 84 | newSprite.m_Coords.y = MathHelpers.Random_Float(minY, maxY); 85 | newSprite.m_Color = m_Randomizer.GetRandomValue(); 86 | newSprite.m_HorLeft = MathHelpers.Random_CheckChance(0.5f); 87 | newSprite.m_VerUp = MathHelpers.Random_CheckChance(0.5f); 88 | newSprite.m_SpeedMult = MathHelpers.Random_Factor(); 89 | newSprite.m_SpeedMult = newSprite.m_SpeedMult * newSprite.m_SpeedMult * newSprite.m_SpeedMult * newSprite.m_SpeedMult * newSprite.m_SpeedMult * newSprite.m_SpeedMult; 90 | newSprite.m_SpriteIndex = MathHelpers.Random_Int(0, 1); 91 | newSprite.m_Angle = MathHelpers.Random_Angle(); 92 | 93 | newSprite.m_Scale = Interpolation.Linear(0.5f, 2.0f, (Mathf.Pow(MathHelpers.Random_Factor(), 3.0f))); 94 | 95 | m_Sprites.Add(newSprite); 96 | 97 | 98 | 99 | } 100 | 101 | } 102 | 103 | 104 | // Update is called once per frame 105 | void Update() 106 | { 107 | 108 | float minX = m_X_Min; 109 | float maxX = m_X_Max; 110 | float minY = m_Y_Min; 111 | float maxY = m_Y_Max; 112 | 113 | float deltaTime = Time.deltaTime; 114 | 115 | //getting camera bounds 116 | if (m_Camera) 117 | { 118 | float halfSize = m_Camera.orthographicSize; 119 | float ratio = m_Camera.aspect; 120 | 121 | minY = -halfSize; 122 | maxY = halfSize; 123 | 124 | minX = -halfSize * ratio; 125 | maxX = halfSize * ratio; 126 | } 127 | 128 | //updating the sprites 129 | for (int i = 0; i < m_SpritesCount; i++) 130 | { 131 | float curSpeed = Interpolation.Linear(m_SpeedMin, m_SpeedMax, m_Sprites[i].m_SpeedMult) * deltaTime; 132 | 133 | var curSprite = m_Sprites[i]; 134 | 135 | 136 | //hor 137 | if (curSprite.m_HorLeft == true) 138 | { 139 | curSprite.m_Coords.x -= curSpeed; 140 | if (curSprite.m_Coords.x <= minX) 141 | { 142 | curSprite.m_HorLeft = false; 143 | } 144 | } 145 | else 146 | { 147 | curSprite.m_Coords.x += curSpeed; 148 | if (curSprite.m_Coords.x >= maxX) 149 | { 150 | curSprite.m_HorLeft = true; 151 | } 152 | } 153 | 154 | //ver 155 | if (curSprite.m_VerUp == true) 156 | { 157 | curSprite.m_Coords.y += curSpeed; 158 | if (curSprite.m_Coords.y >= maxY) 159 | { 160 | curSprite.m_VerUp = false; 161 | } 162 | } 163 | else 164 | { 165 | curSprite.m_Coords.y -= curSpeed; 166 | if (curSprite.m_Coords.y <= minY) 167 | { 168 | curSprite.m_VerUp = true; 169 | } 170 | } 171 | 172 | //rotation 173 | curSprite.m_Angle += 0.2f * deltaTime; 174 | } 175 | 176 | //rendering the sprites 177 | if (m_Batcher == null) return; 178 | 179 | for (int i = 0; i < m_SpritesCount; i++) 180 | { 181 | var curSprite = m_Sprites[i]; 182 | m_Batcher.DrawSprite(curSprite.m_SpriteIndex, curSprite.m_Coords, curSprite.m_Angle, curSprite.m_Scale, curSprite.m_Color); 183 | } 184 | 185 | m_Batcher.CompleteMesh(); 186 | } 187 | } -------------------------------------------------------------------------------- /Assets/Scripts/Tests/SimpleSpritesSimulator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 74d4637b96cdbab4b9b7b58fdc4af165 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Scripts/VectorTools.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | namespace vadersb.utils 6 | { 7 | public static class VectorTools 8 | { 9 | public static readonly Vector2 ZeroAngleVector = new Vector2(1.0f, 0.0f); 10 | 11 | 12 | public static Vector3 ToVector3(this Vector2 src) 13 | { 14 | return new Vector3(src.x, src.y, 0.0f); 15 | } 16 | 17 | /////// 18 | //setup 19 | /////// 20 | public static Vector2 Setup_ByCoords(float x, float y) 21 | { 22 | return new Vector2(x, y); 23 | } 24 | 25 | public static Vector2 Setup_ByFromTo(Vector2 from, Vector2 to) 26 | { 27 | return to - from; 28 | } 29 | 30 | public static Vector2 Setup_ByInvertedCopy(Vector2 src) 31 | { 32 | return new Vector2(-src.x, -src.y); 33 | } 34 | 35 | public static Vector2 Setup_ByAngle(float angle) 36 | { 37 | return new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)); 38 | } 39 | 40 | public static Vector2 Setup_ByAngleMagnitude(float angle, float magnitude) 41 | { 42 | var result = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)); 43 | result *= magnitude; 44 | return result; 45 | } 46 | 47 | //============ 48 | //modification 49 | //============ 50 | public static Vector2 Invert(Vector2 src) 51 | { 52 | return new Vector2(-src.x, -src.y); 53 | } 54 | 55 | /// 56 | /// Rotates point by supplied angle in radians, around the origin point [0;0] 57 | /// 58 | /// angle in radians. positive angle == CCW rotation in Unity! and CW rotation in Pixel Coords! 59 | public static Vector2 Rotate(Vector2 src, float angle) 60 | { 61 | float curSin = Mathf.Sin(angle); 62 | float curCos = Mathf.Cos(angle); 63 | 64 | return new Vector2((src.x * curCos) - (src.y * curSin), (src.x * curSin) + (src.y * curCos)); 65 | } 66 | 67 | public static Vector2 RotateAroundCenter(Vector2 src, Vector2 center, float angle) 68 | { 69 | var tmp = src - center; 70 | var curSin = Mathf.Sin(angle); 71 | var curCos = Mathf.Cos(angle); 72 | return new Vector2(center.x + ((tmp.x * curCos) - (tmp.y * curSin)), center.y + ((tmp.x * curSin) + (tmp.y * curCos))); 73 | } 74 | 75 | public static Vector2 ScaleAgainstCenter(Vector2 src, Vector2 center, float scaleFactor) 76 | { 77 | return new Vector2(center.x + ((src.x - center.x) * scaleFactor), center.y + ((src.y - center.y) * scaleFactor)); 78 | } 79 | 80 | public static Vector2 ScaleXAgainstCenter(Vector2 src, float centerX, float scaleFactor) 81 | { 82 | src.x = centerX + ((src.x - centerX) * scaleFactor); 83 | return src; 84 | } 85 | 86 | public static Vector2 ScaleYAgainstCenter(Vector2 src, float centerY, float scaleFactor) 87 | { 88 | src.y = centerY + ((src.y - centerY) * scaleFactor); 89 | return src; 90 | } 91 | 92 | public static Vector2 Mirror(Vector2 src, Vector2 center) 93 | { 94 | src.x = center.x + (center.x - src.x); 95 | src.y = center.y + (center.y - src.y); 96 | return src; 97 | } 98 | 99 | public static Vector2 MirrorX(Vector2 src, float centerX) 100 | { 101 | src.x = centerX + (centerX - src.x); 102 | return src; 103 | } 104 | 105 | public static Vector2 MirrorY(Vector2 src, float centerY) 106 | { 107 | src.y = centerY + (centerY - src.y); 108 | return src; 109 | } 110 | 111 | //============ 112 | //clamp 113 | //============ 114 | 115 | 116 | public static Vector2 Clamp_MagnitudeRange(Vector2 src, float minMagnitude, float maxMagnitude) 117 | { 118 | float magnitude = src.magnitude; 119 | 120 | var result = src; 121 | 122 | if (magnitude < minMagnitude) 123 | { 124 | result /= magnitude; 125 | result *= minMagnitude; 126 | } 127 | else if (magnitude > maxMagnitude) 128 | { 129 | result /= magnitude; 130 | result *= maxMagnitude; 131 | } 132 | 133 | return result; 134 | } 135 | 136 | //============ 137 | //calculations 138 | //============ 139 | 140 | public static bool IsZero(this Vector2 src) 141 | { 142 | return src == Vector2.zero; 143 | } 144 | 145 | 146 | public static bool IsZero(this Vector3 src) 147 | { 148 | return Mathf.Approximately(src.x, 0.0f) == true && 149 | Mathf.Approximately(src.y, 0.0f) == true && 150 | Mathf.Approximately(src.z, 0.0f) == true; 151 | } 152 | 153 | /// 154 | /// -90 degrees perpendicular in pixels coords (Y goes down) 155 | /// +90 degrees perpendicular in Unity coords (Y goes up) 156 | /// 157 | public static Vector2 GetNormal(this Vector2 src) 158 | { 159 | float tx = src.x; 160 | src.x = src.y; 161 | src.y = -tx; 162 | src.Normalize(); 163 | return src; 164 | } 165 | 166 | public static float GetDistanceTo(this Vector2 from, Vector2 to) 167 | { 168 | return Vector2.Distance(from, to); 169 | } 170 | 171 | public static float GetDistanceSquareTo(this Vector2 from, Vector2 to) 172 | { 173 | float dx = to.x - from.x; 174 | float dy = to.y - from.y; 175 | 176 | return dx * dx + dy * dy; 177 | } 178 | 179 | public static float GetAngleAgainstVector(this Vector2 src, Vector2 anotherVector) 180 | { 181 | src.Normalize(); 182 | anotherVector.Normalize(); 183 | 184 | return Mathf.Acos(Vector2.Dot(src, anotherVector)); 185 | } 186 | 187 | public static float GetAngleAgainstVector_Signed(this Vector2 src, Vector2 anotherVector) 188 | { 189 | src.Normalize(); 190 | anotherVector.Normalize(); 191 | 192 | float result = Mathf.Acos(Vector2.Dot(src, anotherVector)); 193 | 194 | var n = anotherVector.GetNormal(); 195 | 196 | if (Vector2.Dot(n, src) > 0.0f) 197 | { 198 | result = -result; 199 | } 200 | 201 | return result; 202 | } 203 | 204 | public static float GetAngleCommon(this Vector2 src) 205 | { 206 | src.Normalize(); 207 | 208 | float result = Mathf.Acos(Vector2.Dot(src, ZeroAngleVector)); 209 | 210 | if (src.y < 0.0f) 211 | { 212 | result = MathHelpers.Pi_Double - result; 213 | } 214 | 215 | return result; 216 | } 217 | 218 | //====== 219 | //paths length 220 | //====== 221 | 222 | 223 | public static float GetPathLength_CubicInterpolation(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, int stepsCount = 32) 224 | { 225 | Debug.Assert(stepsCount > 0); 226 | 227 | if (stepsCount < 1) 228 | { 229 | return 0.01f; 230 | } 231 | 232 | float curFactor = 0.0f; 233 | float curStep = 1.0f / ((float)stepsCount); 234 | 235 | int i; 236 | 237 | float result = 0.0f; 238 | 239 | Vector2 curPoint = Interpolation.Cubic(p1, p2, p3, p4, curFactor); 240 | 241 | for (i = 0; i < stepsCount; i++) 242 | { 243 | curFactor += curStep; 244 | 245 | Vector2 nextPoint = Interpolation.Cubic(p1, p2, p3, p4, curFactor + curStep); 246 | 247 | result += curPoint.GetDistanceTo(nextPoint); 248 | 249 | curPoint = nextPoint; 250 | } 251 | 252 | return result; 253 | } 254 | 255 | //====== 256 | //random 257 | //====== 258 | public static Vector2 Random_InRect(Rect bounds) 259 | { 260 | Vector2 result = new Vector2(MathHelpers.Random_Float(bounds.xMin, bounds.xMax), 261 | MathHelpers.Random_Float(bounds.yMin, bounds.yMax)); 262 | 263 | return result; 264 | } 265 | 266 | public static Vector2 Random_InCircle(Vector2 center, float radius, float radiusMin = 0.0f) 267 | { 268 | Vector2 result = center; 269 | 270 | Vector2 move = Setup_ByAngleMagnitude(MathHelpers.Random_Angle_Looped(), Interpolation.Linear(radiusMin, radius, MathHelpers.Random_Factor())); 271 | 272 | result += move; 273 | 274 | return result; 275 | } 276 | 277 | public static Vector2 Random_OnSegment(Vector2 segmentFrom, Vector2 segmentTo) 278 | { 279 | return Interpolation.Linear(segmentFrom, segmentTo, MathHelpers.Random_Factor()); 280 | } 281 | 282 | 283 | public static Vector2 Random_Deviation(Vector2 deviation, Vector2 center = default) 284 | { 285 | Vector2 result = center; 286 | result.x += MathHelpers.Random_Float(-deviation.x, deviation.x); 287 | result.y += MathHelpers.Random_Float(-deviation.y, deviation.y); 288 | return result; 289 | } 290 | 291 | } 292 | 293 | public static class VectorDynamics 294 | { 295 | public static void Velocity_ApplyFriction(this Vector2 target, float frictionFactor, float timeDelta) 296 | { 297 | frictionFactor *= timeDelta; 298 | 299 | if (frictionFactor > target.magnitude) 300 | { 301 | target.Set(0.0f, 0.0f); 302 | return; 303 | } 304 | 305 | Vector2 frictionVector = VectorTools.Invert(target); 306 | 307 | frictionVector.Normalize(); 308 | frictionVector *= frictionFactor; 309 | 310 | target += frictionVector; 311 | } 312 | 313 | 314 | public static void Velocity_ApplyImpulse(this ref Vector2 target, Vector2 impulse) 315 | { 316 | target += impulse; 317 | } 318 | 319 | 320 | public static void Velocity_ApplyAcceleration(this ref Vector2 target, Vector2 acceleration, float timeDelta) 321 | { 322 | target += acceleration * timeDelta; 323 | } 324 | 325 | 326 | public static void Position_ApplyVelocity(this ref Vector2 target, Vector2 velocity, float timeDelta) 327 | { 328 | target += velocity * timeDelta; 329 | } 330 | 331 | 332 | public static float CalculateCollisionVelocity(Vector2 velocityA, Vector2 velocityB, Vector2 normalFromA) 333 | { 334 | float result = 0.0f; 335 | 336 | //a contribution 337 | result += Vector2.Dot(velocityA, normalFromA); 338 | 339 | //b contribution 340 | result += Vector2.Dot(velocityB, -normalFromA); 341 | 342 | return result; 343 | } 344 | 345 | } 346 | } 347 | -------------------------------------------------------------------------------- /Assets/Scripts/VectorTools.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a3bcc85e4c0f18a499bec4dc6ec86bb5 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Scripts/WeightedRandomizer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | namespace vadersb.utils 5 | { 6 | public class WeightedRandomizer 7 | { 8 | private List m_Values; 9 | private List m_Weights; 10 | private float m_TotalWeight; 11 | private int m_Count; 12 | 13 | public WeightedRandomizer(int sizeToReserve = 10) 14 | { 15 | Reset(sizeToReserve); 16 | } 17 | 18 | public WeightedRandomizer(WeightedRandomizer anotherRandomizer) 19 | { 20 | SetupByCopy(anotherRandomizer); 21 | } 22 | 23 | public void SetupByCopy(WeightedRandomizer anotherRandomizer) 24 | { 25 | if (anotherRandomizer == null) 26 | { 27 | Debug.LogError("another Randomizer is null!"); 28 | Reset(); 29 | return; 30 | } 31 | 32 | m_Values = new List(anotherRandomizer.m_Count); 33 | m_Weights = new List(anotherRandomizer.m_Count); 34 | m_TotalWeight = anotherRandomizer.m_TotalWeight; 35 | m_Count = anotherRandomizer.m_Count; 36 | 37 | for (int i = 0; i < m_Count; i++) 38 | { 39 | m_Values[i] = anotherRandomizer.m_Values[i]; 40 | m_Weights[i] = anotherRandomizer.m_Weights[i]; 41 | } 42 | } 43 | 44 | public void Reset(int sizeToReserve = 10) 45 | { 46 | m_Values = new List(sizeToReserve); 47 | m_Weights = new List(sizeToReserve); 48 | m_TotalWeight = 0.0f; 49 | m_Count = 0; 50 | } 51 | 52 | public T GetValue(int index) 53 | { 54 | if (m_Count == 0) 55 | { 56 | Debug.LogError("WeightedRandomizer is empty!"); 57 | return default(T); 58 | } 59 | 60 | if (index < 0 || index >= m_Count) 61 | { 62 | Debug.Log("Invalid index: " + index + ". count: " + m_Count); 63 | return default(T); 64 | } 65 | 66 | return m_Values[index]; 67 | } 68 | 69 | public float GetWeight(int index) 70 | { 71 | if (m_Count == 0) 72 | { 73 | Debug.LogError("WeightedRandomizer is empty!"); 74 | return 0.0f; 75 | } 76 | 77 | if (index < 0 || index >= m_Count) 78 | { 79 | Debug.Log("Invalid index: " + index + ". count: " + m_Count); 80 | return 0.0f; 81 | } 82 | 83 | return m_Weights[index]; 84 | } 85 | 86 | public void AddValue(T valueToAdd, float weight, bool strict = false) 87 | { 88 | if (weight <= 0.0f) 89 | { 90 | Debug.LogError("Can't add value to randomizer. Invalid weight: " + weight); 91 | return; 92 | } 93 | 94 | if (strict == true) 95 | { 96 | if (m_Values.Contains(valueToAdd) == true) 97 | { 98 | Debug.Log("Can't add value to randomizer. Same value is already added."); 99 | return; 100 | } 101 | } 102 | 103 | m_Values.Add(valueToAdd); 104 | m_Weights.Add(weight); 105 | m_TotalWeight += weight; 106 | m_Count++; 107 | } 108 | 109 | public int Count 110 | { 111 | get { return m_Count; } 112 | } 113 | 114 | public T GetRandomValue() 115 | { 116 | if (m_Count <= 0) 117 | { 118 | Debug.LogError("randomizer is empty!"); 119 | return default(T); 120 | } 121 | 122 | if (m_Count == 1) 123 | { 124 | return m_Values[0]; 125 | } 126 | 127 | float randomWeight = MathHelpers.Random_Factor_Looped() * m_TotalWeight; 128 | 129 | float curAccumulatedWeight = 0.0f; 130 | 131 | for (int i = 0; i < m_Count; i++) 132 | { 133 | curAccumulatedWeight += m_Weights[i]; 134 | 135 | if (curAccumulatedWeight > randomWeight) 136 | { 137 | return m_Values[i]; 138 | } 139 | } 140 | 141 | return m_Values[m_Count - 1]; 142 | } 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /Assets/Scripts/WeightedRandomizer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2ccf0a409a6b03a4aa8860f303d95aed 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Sprites.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e9d60bb5f92502b4aa32c3013fb51c0a 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Sprites/white_circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vadersb/Unity_SpriteBatcherTest/d8e2d5fa7dcd6675089caad1912a4407cf7fb307/Assets/Sprites/white_circle.png -------------------------------------------------------------------------------- /Assets/Sprites/white_circle.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fb4df692a9fe0e84792c37cd79816b8d 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 10 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: 2 35 | aniso: -1 36 | mipBias: -100 37 | wrapU: 1 38 | wrapV: 1 39 | wrapW: 1 40 | nPOTScale: 0 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 1 44 | spriteExtrude: 0 45 | spriteMeshType: 0 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 1 53 | spriteTessellationDetail: -1 54 | textureType: 8 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | platformSettings: 61 | - serializedVersion: 3 62 | buildTarget: DefaultTexturePlatform 63 | maxTextureSize: 2048 64 | resizeAlgorithm: 1 65 | textureFormat: 4 66 | textureCompression: 1 67 | compressionQuality: 50 68 | crunchedCompression: 0 69 | allowsAlphaSplitting: 0 70 | overridden: 0 71 | androidETC2FallbackOverride: 0 72 | forceMaximumCompressionQuality_BC6H_BC7: 0 73 | - serializedVersion: 3 74 | buildTarget: Standalone 75 | maxTextureSize: 2048 76 | resizeAlgorithm: 1 77 | textureFormat: 4 78 | textureCompression: 1 79 | compressionQuality: 50 80 | crunchedCompression: 0 81 | allowsAlphaSplitting: 0 82 | overridden: 0 83 | androidETC2FallbackOverride: 0 84 | forceMaximumCompressionQuality_BC6H_BC7: 0 85 | spriteSheet: 86 | serializedVersion: 2 87 | sprites: [] 88 | outline: [] 89 | physicsShape: [] 90 | bones: [] 91 | spriteID: 5e97eb03825dee720800000000000000 92 | internalID: 0 93 | vertices: [] 94 | indices: 95 | edges: [] 96 | weights: [] 97 | secondaryTextures: [] 98 | spritePackingTag: 99 | pSDRemoveMatte: 0 100 | pSDShowRemoveMatteOption: 0 101 | userData: 102 | assetBundleName: 103 | assetBundleVariant: 104 | -------------------------------------------------------------------------------- /Assets/Sprites/white_square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vadersb/Unity_SpriteBatcherTest/d8e2d5fa7dcd6675089caad1912a4407cf7fb307/Assets/Sprites/white_square.png -------------------------------------------------------------------------------- /Assets/Sprites/white_square.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2b985a7bba9c5be43bcbeb5c5c62b94b 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 10 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: 2 35 | aniso: -1 36 | mipBias: -100 37 | wrapU: 1 38 | wrapV: 1 39 | wrapW: 1 40 | nPOTScale: 0 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 1 44 | spriteExtrude: 0 45 | spriteMeshType: 0 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 1 53 | spriteTessellationDetail: -1 54 | textureType: 8 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | platformSettings: 61 | - serializedVersion: 3 62 | buildTarget: DefaultTexturePlatform 63 | maxTextureSize: 2048 64 | resizeAlgorithm: 1 65 | textureFormat: 4 66 | textureCompression: 1 67 | compressionQuality: 50 68 | crunchedCompression: 0 69 | allowsAlphaSplitting: 0 70 | overridden: 0 71 | androidETC2FallbackOverride: 0 72 | forceMaximumCompressionQuality_BC6H_BC7: 0 73 | - serializedVersion: 3 74 | buildTarget: Standalone 75 | maxTextureSize: 2048 76 | resizeAlgorithm: 1 77 | textureFormat: 4 78 | textureCompression: 1 79 | compressionQuality: 50 80 | crunchedCompression: 0 81 | allowsAlphaSplitting: 0 82 | overridden: 0 83 | androidETC2FallbackOverride: 0 84 | forceMaximumCompressionQuality_BC6H_BC7: 0 85 | spriteSheet: 86 | serializedVersion: 2 87 | sprites: [] 88 | outline: [] 89 | physicsShape: [] 90 | bones: [] 91 | spriteID: 5e97eb03825dee720800000000000000 92 | internalID: 0 93 | vertices: [] 94 | indices: 95 | edges: [] 96 | weights: [] 97 | secondaryTextures: [] 98 | spritePackingTag: 99 | pSDRemoveMatte: 0 100 | pSDShowRemoveMatteOption: 0 101 | userData: 102 | assetBundleName: 103 | assetBundleVariant: 104 | -------------------------------------------------------------------------------- /Assets/TestAtlas.spriteatlas: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!687078895 &4343727234628468602 4 | SpriteAtlas: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_Name: TestAtlas 10 | m_EditorData: 11 | serializedVersion: 2 12 | textureSettings: 13 | serializedVersion: 2 14 | anisoLevel: 0 15 | compressionQuality: 50 16 | maxTextureSize: 2048 17 | textureCompression: 0 18 | filterMode: 2 19 | generateMipMaps: 1 20 | readable: 0 21 | crunchedCompression: 0 22 | sRGB: 1 23 | platformSettings: 24 | - serializedVersion: 3 25 | m_BuildTarget: DefaultTexturePlatform 26 | m_MaxTextureSize: 2048 27 | m_ResizeAlgorithm: 0 28 | m_TextureFormat: 4 29 | m_TextureCompression: 1 30 | m_CompressionQuality: 50 31 | m_CrunchedCompression: 0 32 | m_AllowsAlphaSplitting: 0 33 | m_Overridden: 0 34 | m_AndroidETC2FallbackOverride: 0 35 | m_ForceMaximumCompressionQuality_BC6H_BC7: 0 36 | packingSettings: 37 | serializedVersion: 2 38 | padding: 4 39 | blockOffset: 4 40 | allowAlphaSplitting: 0 41 | enableRotation: 1 42 | enableTightPacking: 1 43 | secondaryTextureSettings: {} 44 | variantMultiplier: 1 45 | packables: 46 | - {fileID: 102900000, guid: e9d60bb5f92502b4aa32c3013fb51c0a, type: 3} 47 | bindAsDefault: 1 48 | isAtlasV2: 0 49 | cachedData: {fileID: 0} 50 | m_MasterAtlas: {fileID: 0} 51 | m_PackedSprites: 52 | - {fileID: 21300000, guid: fb4df692a9fe0e84792c37cd79816b8d, type: 3} 53 | - {fileID: 21300000, guid: 2b985a7bba9c5be43bcbeb5c5c62b94b, type: 3} 54 | m_PackedSpriteNamesToIndex: 55 | - white_circle 56 | - white_square 57 | m_RenderDataMap: {} 58 | m_Tag: TestAtlas 59 | m_IsVariant: 0 60 | -------------------------------------------------------------------------------- /Assets/TestAtlas.spriteatlas.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2ab131f5b8bd1c145b1af2cb3467c082 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 4343727234628468602 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Alexander 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/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "com.unity.2d.sprite": "1.0.0", 4 | "com.unity.2d.tilemap": "1.0.0", 5 | "com.unity.burst": "1.6.5", 6 | "com.unity.collab-proxy": "1.15.15", 7 | "com.unity.ext.nunit": "1.0.6", 8 | "com.unity.ide.rider": "2.0.7", 9 | "com.unity.ide.visualstudio": "2.0.14", 10 | "com.unity.ide.vscode": "1.2.5", 11 | "com.unity.jobs": "0.50.0-preview.8", 12 | "com.unity.mathematics": "1.2.6", 13 | "com.unity.test-framework": "1.1.31", 14 | "com.unity.textmeshpro": "3.0.6", 15 | "com.unity.timeline": "1.4.8", 16 | "com.unity.ugui": "1.0.0", 17 | "com.unity.modules.ai": "1.0.0", 18 | "com.unity.modules.androidjni": "1.0.0", 19 | "com.unity.modules.animation": "1.0.0", 20 | "com.unity.modules.assetbundle": "1.0.0", 21 | "com.unity.modules.audio": "1.0.0", 22 | "com.unity.modules.cloth": "1.0.0", 23 | "com.unity.modules.director": "1.0.0", 24 | "com.unity.modules.imageconversion": "1.0.0", 25 | "com.unity.modules.imgui": "1.0.0", 26 | "com.unity.modules.jsonserialize": "1.0.0", 27 | "com.unity.modules.particlesystem": "1.0.0", 28 | "com.unity.modules.physics": "1.0.0", 29 | "com.unity.modules.physics2d": "1.0.0", 30 | "com.unity.modules.screencapture": "1.0.0", 31 | "com.unity.modules.terrain": "1.0.0", 32 | "com.unity.modules.terrainphysics": "1.0.0", 33 | "com.unity.modules.tilemap": "1.0.0", 34 | "com.unity.modules.ui": "1.0.0", 35 | "com.unity.modules.uielements": "1.0.0", 36 | "com.unity.modules.umbra": "1.0.0", 37 | "com.unity.modules.unityanalytics": "1.0.0", 38 | "com.unity.modules.unitywebrequest": "1.0.0", 39 | "com.unity.modules.unitywebrequestassetbundle": "1.0.0", 40 | "com.unity.modules.unitywebrequestaudio": "1.0.0", 41 | "com.unity.modules.unitywebrequesttexture": "1.0.0", 42 | "com.unity.modules.unitywebrequestwww": "1.0.0", 43 | "com.unity.modules.vehicles": "1.0.0", 44 | "com.unity.modules.video": "1.0.0", 45 | "com.unity.modules.vr": "1.0.0", 46 | "com.unity.modules.wind": "1.0.0", 47 | "com.unity.modules.xr": "1.0.0" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Packages/packages-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "com.unity.2d.sprite": { 4 | "version": "1.0.0", 5 | "depth": 0, 6 | "source": "builtin", 7 | "dependencies": {} 8 | }, 9 | "com.unity.2d.tilemap": { 10 | "version": "1.0.0", 11 | "depth": 0, 12 | "source": "builtin", 13 | "dependencies": {} 14 | }, 15 | "com.unity.burst": { 16 | "version": "1.6.5", 17 | "depth": 0, 18 | "source": "registry", 19 | "dependencies": { 20 | "com.unity.mathematics": "1.2.1" 21 | }, 22 | "url": "https://packages.unity.com" 23 | }, 24 | "com.unity.collab-proxy": { 25 | "version": "1.15.15", 26 | "depth": 0, 27 | "source": "registry", 28 | "dependencies": { 29 | "com.unity.services.core": "1.0.1" 30 | }, 31 | "url": "https://packages.unity.com" 32 | }, 33 | "com.unity.collections": { 34 | "version": "1.2.3-pre.1", 35 | "depth": 1, 36 | "source": "registry", 37 | "dependencies": { 38 | "com.unity.burst": "1.6.4", 39 | "com.unity.test-framework": "1.1.31" 40 | }, 41 | "url": "https://packages.unity.com" 42 | }, 43 | "com.unity.ext.nunit": { 44 | "version": "1.0.6", 45 | "depth": 0, 46 | "source": "registry", 47 | "dependencies": {}, 48 | "url": "https://packages.unity.com" 49 | }, 50 | "com.unity.ide.rider": { 51 | "version": "2.0.7", 52 | "depth": 0, 53 | "source": "registry", 54 | "dependencies": { 55 | "com.unity.test-framework": "1.1.1" 56 | }, 57 | "url": "https://packages.unity.com" 58 | }, 59 | "com.unity.ide.visualstudio": { 60 | "version": "2.0.14", 61 | "depth": 0, 62 | "source": "registry", 63 | "dependencies": { 64 | "com.unity.test-framework": "1.1.9" 65 | }, 66 | "url": "https://packages.unity.com" 67 | }, 68 | "com.unity.ide.vscode": { 69 | "version": "1.2.5", 70 | "depth": 0, 71 | "source": "registry", 72 | "dependencies": {}, 73 | "url": "https://packages.unity.com" 74 | }, 75 | "com.unity.jobs": { 76 | "version": "0.50.0-preview.8", 77 | "depth": 0, 78 | "source": "registry", 79 | "dependencies": { 80 | "com.unity.burst": "1.6.4", 81 | "com.unity.collections": "1.2.3-pre.1", 82 | "com.unity.mathematics": "1.2.1", 83 | "com.unity.nuget.mono-cecil": "1.10.1" 84 | }, 85 | "url": "https://packages.unity.com" 86 | }, 87 | "com.unity.mathematics": { 88 | "version": "1.2.6", 89 | "depth": 0, 90 | "source": "registry", 91 | "dependencies": {}, 92 | "url": "https://packages.unity.com" 93 | }, 94 | "com.unity.nuget.mono-cecil": { 95 | "version": "1.10.1", 96 | "depth": 1, 97 | "source": "registry", 98 | "dependencies": {}, 99 | "url": "https://packages.unity.com" 100 | }, 101 | "com.unity.services.core": { 102 | "version": "1.0.1", 103 | "depth": 1, 104 | "source": "registry", 105 | "dependencies": { 106 | "com.unity.modules.unitywebrequest": "1.0.0" 107 | }, 108 | "url": "https://packages.unity.com" 109 | }, 110 | "com.unity.test-framework": { 111 | "version": "1.1.31", 112 | "depth": 0, 113 | "source": "registry", 114 | "dependencies": { 115 | "com.unity.ext.nunit": "1.0.6", 116 | "com.unity.modules.imgui": "1.0.0", 117 | "com.unity.modules.jsonserialize": "1.0.0" 118 | }, 119 | "url": "https://packages.unity.com" 120 | }, 121 | "com.unity.textmeshpro": { 122 | "version": "3.0.6", 123 | "depth": 0, 124 | "source": "registry", 125 | "dependencies": { 126 | "com.unity.ugui": "1.0.0" 127 | }, 128 | "url": "https://packages.unity.com" 129 | }, 130 | "com.unity.timeline": { 131 | "version": "1.4.8", 132 | "depth": 0, 133 | "source": "registry", 134 | "dependencies": { 135 | "com.unity.modules.director": "1.0.0", 136 | "com.unity.modules.animation": "1.0.0", 137 | "com.unity.modules.audio": "1.0.0", 138 | "com.unity.modules.particlesystem": "1.0.0" 139 | }, 140 | "url": "https://packages.unity.com" 141 | }, 142 | "com.unity.ugui": { 143 | "version": "1.0.0", 144 | "depth": 0, 145 | "source": "builtin", 146 | "dependencies": { 147 | "com.unity.modules.ui": "1.0.0", 148 | "com.unity.modules.imgui": "1.0.0" 149 | } 150 | }, 151 | "com.unity.modules.ai": { 152 | "version": "1.0.0", 153 | "depth": 0, 154 | "source": "builtin", 155 | "dependencies": {} 156 | }, 157 | "com.unity.modules.androidjni": { 158 | "version": "1.0.0", 159 | "depth": 0, 160 | "source": "builtin", 161 | "dependencies": {} 162 | }, 163 | "com.unity.modules.animation": { 164 | "version": "1.0.0", 165 | "depth": 0, 166 | "source": "builtin", 167 | "dependencies": {} 168 | }, 169 | "com.unity.modules.assetbundle": { 170 | "version": "1.0.0", 171 | "depth": 0, 172 | "source": "builtin", 173 | "dependencies": {} 174 | }, 175 | "com.unity.modules.audio": { 176 | "version": "1.0.0", 177 | "depth": 0, 178 | "source": "builtin", 179 | "dependencies": {} 180 | }, 181 | "com.unity.modules.cloth": { 182 | "version": "1.0.0", 183 | "depth": 0, 184 | "source": "builtin", 185 | "dependencies": { 186 | "com.unity.modules.physics": "1.0.0" 187 | } 188 | }, 189 | "com.unity.modules.director": { 190 | "version": "1.0.0", 191 | "depth": 0, 192 | "source": "builtin", 193 | "dependencies": { 194 | "com.unity.modules.audio": "1.0.0", 195 | "com.unity.modules.animation": "1.0.0" 196 | } 197 | }, 198 | "com.unity.modules.imageconversion": { 199 | "version": "1.0.0", 200 | "depth": 0, 201 | "source": "builtin", 202 | "dependencies": {} 203 | }, 204 | "com.unity.modules.imgui": { 205 | "version": "1.0.0", 206 | "depth": 0, 207 | "source": "builtin", 208 | "dependencies": {} 209 | }, 210 | "com.unity.modules.jsonserialize": { 211 | "version": "1.0.0", 212 | "depth": 0, 213 | "source": "builtin", 214 | "dependencies": {} 215 | }, 216 | "com.unity.modules.particlesystem": { 217 | "version": "1.0.0", 218 | "depth": 0, 219 | "source": "builtin", 220 | "dependencies": {} 221 | }, 222 | "com.unity.modules.physics": { 223 | "version": "1.0.0", 224 | "depth": 0, 225 | "source": "builtin", 226 | "dependencies": {} 227 | }, 228 | "com.unity.modules.physics2d": { 229 | "version": "1.0.0", 230 | "depth": 0, 231 | "source": "builtin", 232 | "dependencies": {} 233 | }, 234 | "com.unity.modules.screencapture": { 235 | "version": "1.0.0", 236 | "depth": 0, 237 | "source": "builtin", 238 | "dependencies": { 239 | "com.unity.modules.imageconversion": "1.0.0" 240 | } 241 | }, 242 | "com.unity.modules.subsystems": { 243 | "version": "1.0.0", 244 | "depth": 1, 245 | "source": "builtin", 246 | "dependencies": { 247 | "com.unity.modules.jsonserialize": "1.0.0" 248 | } 249 | }, 250 | "com.unity.modules.terrain": { 251 | "version": "1.0.0", 252 | "depth": 0, 253 | "source": "builtin", 254 | "dependencies": {} 255 | }, 256 | "com.unity.modules.terrainphysics": { 257 | "version": "1.0.0", 258 | "depth": 0, 259 | "source": "builtin", 260 | "dependencies": { 261 | "com.unity.modules.physics": "1.0.0", 262 | "com.unity.modules.terrain": "1.0.0" 263 | } 264 | }, 265 | "com.unity.modules.tilemap": { 266 | "version": "1.0.0", 267 | "depth": 0, 268 | "source": "builtin", 269 | "dependencies": { 270 | "com.unity.modules.physics2d": "1.0.0" 271 | } 272 | }, 273 | "com.unity.modules.ui": { 274 | "version": "1.0.0", 275 | "depth": 0, 276 | "source": "builtin", 277 | "dependencies": {} 278 | }, 279 | "com.unity.modules.uielements": { 280 | "version": "1.0.0", 281 | "depth": 0, 282 | "source": "builtin", 283 | "dependencies": { 284 | "com.unity.modules.ui": "1.0.0", 285 | "com.unity.modules.imgui": "1.0.0", 286 | "com.unity.modules.jsonserialize": "1.0.0", 287 | "com.unity.modules.uielementsnative": "1.0.0" 288 | } 289 | }, 290 | "com.unity.modules.uielementsnative": { 291 | "version": "1.0.0", 292 | "depth": 1, 293 | "source": "builtin", 294 | "dependencies": { 295 | "com.unity.modules.ui": "1.0.0", 296 | "com.unity.modules.imgui": "1.0.0", 297 | "com.unity.modules.jsonserialize": "1.0.0" 298 | } 299 | }, 300 | "com.unity.modules.umbra": { 301 | "version": "1.0.0", 302 | "depth": 0, 303 | "source": "builtin", 304 | "dependencies": {} 305 | }, 306 | "com.unity.modules.unityanalytics": { 307 | "version": "1.0.0", 308 | "depth": 0, 309 | "source": "builtin", 310 | "dependencies": { 311 | "com.unity.modules.unitywebrequest": "1.0.0", 312 | "com.unity.modules.jsonserialize": "1.0.0" 313 | } 314 | }, 315 | "com.unity.modules.unitywebrequest": { 316 | "version": "1.0.0", 317 | "depth": 0, 318 | "source": "builtin", 319 | "dependencies": {} 320 | }, 321 | "com.unity.modules.unitywebrequestassetbundle": { 322 | "version": "1.0.0", 323 | "depth": 0, 324 | "source": "builtin", 325 | "dependencies": { 326 | "com.unity.modules.assetbundle": "1.0.0", 327 | "com.unity.modules.unitywebrequest": "1.0.0" 328 | } 329 | }, 330 | "com.unity.modules.unitywebrequestaudio": { 331 | "version": "1.0.0", 332 | "depth": 0, 333 | "source": "builtin", 334 | "dependencies": { 335 | "com.unity.modules.unitywebrequest": "1.0.0", 336 | "com.unity.modules.audio": "1.0.0" 337 | } 338 | }, 339 | "com.unity.modules.unitywebrequesttexture": { 340 | "version": "1.0.0", 341 | "depth": 0, 342 | "source": "builtin", 343 | "dependencies": { 344 | "com.unity.modules.unitywebrequest": "1.0.0", 345 | "com.unity.modules.imageconversion": "1.0.0" 346 | } 347 | }, 348 | "com.unity.modules.unitywebrequestwww": { 349 | "version": "1.0.0", 350 | "depth": 0, 351 | "source": "builtin", 352 | "dependencies": { 353 | "com.unity.modules.unitywebrequest": "1.0.0", 354 | "com.unity.modules.unitywebrequestassetbundle": "1.0.0", 355 | "com.unity.modules.unitywebrequestaudio": "1.0.0", 356 | "com.unity.modules.audio": "1.0.0", 357 | "com.unity.modules.assetbundle": "1.0.0", 358 | "com.unity.modules.imageconversion": "1.0.0" 359 | } 360 | }, 361 | "com.unity.modules.vehicles": { 362 | "version": "1.0.0", 363 | "depth": 0, 364 | "source": "builtin", 365 | "dependencies": { 366 | "com.unity.modules.physics": "1.0.0" 367 | } 368 | }, 369 | "com.unity.modules.video": { 370 | "version": "1.0.0", 371 | "depth": 0, 372 | "source": "builtin", 373 | "dependencies": { 374 | "com.unity.modules.audio": "1.0.0", 375 | "com.unity.modules.ui": "1.0.0", 376 | "com.unity.modules.unitywebrequest": "1.0.0" 377 | } 378 | }, 379 | "com.unity.modules.vr": { 380 | "version": "1.0.0", 381 | "depth": 0, 382 | "source": "builtin", 383 | "dependencies": { 384 | "com.unity.modules.jsonserialize": "1.0.0", 385 | "com.unity.modules.physics": "1.0.0", 386 | "com.unity.modules.xr": "1.0.0" 387 | } 388 | }, 389 | "com.unity.modules.wind": { 390 | "version": "1.0.0", 391 | "depth": 0, 392 | "source": "builtin", 393 | "dependencies": {} 394 | }, 395 | "com.unity.modules.xr": { 396 | "version": "1.0.0", 397 | "depth": 0, 398 | "source": "builtin", 399 | "dependencies": { 400 | "com.unity.modules.physics": "1.0.0", 401 | "com.unity.modules.jsonserialize": "1.0.0", 402 | "com.unity.modules.subsystems": "1.0.0" 403 | } 404 | } 405 | } 406 | } 407 | -------------------------------------------------------------------------------- /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/BurstAotSettings_StandaloneWindows.json: -------------------------------------------------------------------------------- 1 | { 2 | "MonoBehaviour": { 3 | "Version": 4, 4 | "EnableBurstCompilation": true, 5 | "EnableOptimisations": true, 6 | "EnableSafetyChecks": false, 7 | "EnableDebugInAllBuilds": false, 8 | "UsePlatformSDKLinker": false, 9 | "CpuMinTargetX32": 0, 10 | "CpuMaxTargetX32": 0, 11 | "CpuMinTargetX64": 0, 12 | "CpuMaxTargetX64": 0, 13 | "CpuTargetsX32": 6, 14 | "CpuTargetsX64": 72, 15 | "OptimizeFor": 0 16 | } 17 | } 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/CommonBurstAotSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "MonoBehaviour": { 3 | "Version": 4, 4 | "DisabledWarnings": "" 5 | } 6 | } 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/Scenes/SpriteBatcherJobifiedTest.unity 10 | guid: 1b5643918639bc942a7ba09890ca0f7c 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: 12 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_AlwaysIncludedShaders: 32 | - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} 33 | - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} 34 | m_PreloadedShaders: [] 35 | m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, 36 | type: 0} 37 | m_CustomRenderPipeline: {fileID: 0} 38 | m_TransparencySortMode: 0 39 | m_TransparencySortAxis: {x: 0, y: 0, z: 1} 40 | m_DefaultRenderingPath: 1 41 | m_DefaultMobileRenderingPath: 1 42 | m_TierSettings: [] 43 | m_LightmapStripping: 0 44 | m_FogStripping: 0 45 | m_InstancingStripping: 0 46 | m_LightmapKeepPlain: 1 47 | m_LightmapKeepDirCombined: 1 48 | m_LightmapKeepDynamicPlain: 1 49 | m_LightmapKeepDynamicDirCombined: 1 50 | m_LightmapKeepShadowMask: 1 51 | m_LightmapKeepSubtractive: 1 52 | m_FogKeepLinear: 1 53 | m_FogKeepExp: 1 54 | m_FogKeepExp2: 1 55 | m_AlbedoSwatchInfos: [] 56 | m_LightsUseLinearIntensity: 0 57 | m_LightsUseColorTemperature: 0 58 | -------------------------------------------------------------------------------- /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/PackageManagerSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!114 &1 4 | MonoBehaviour: 5 | m_ObjectHideFlags: 61 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: 13964, guid: 0000000000000000e000000000000000, type: 0} 13 | m_Name: 14 | m_EditorClassIdentifier: 15 | m_EnablePreviewPackages: 1 16 | m_EnablePackageDependencies: 1 17 | m_AdvancedSettingsExpanded: 1 18 | m_ScopedRegistriesSettingsExpanded: 1 19 | oneTimeWarningShown: 1 20 | m_Registries: 21 | - m_Id: main 22 | m_Name: 23 | m_Url: https://packages.unity.com 24 | m_Scopes: [] 25 | m_IsDefault: 1 26 | m_Capabilities: 7 27 | m_UserSelectedRegistryName: 28 | m_UserAddingNewScopedRegistry: 0 29 | m_RegistryInfoDraft: 30 | m_ErrorMessage: 31 | m_Original: 32 | m_Id: 33 | m_Name: 34 | m_Url: 35 | m_Scopes: [] 36 | m_IsDefault: 0 37 | m_Capabilities: 0 38 | m_Modified: 0 39 | m_Name: 40 | m_Url: 41 | m_Scopes: 42 | - 43 | m_SelectedScopeIndex: 0 44 | -------------------------------------------------------------------------------- /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: 1 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: 22 7 | productGUID: 5297c6f21c04e5241aabe0bce84ae799 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: SpriteBatcherTest 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 | mipStripping: 0 53 | numberOfMipsStripped: 0 54 | m_StackTraceTypes: 010000000100000001000000010000000100000001000000 55 | iosShowActivityIndicatorOnLoading: -1 56 | androidShowActivityIndicatorOnLoading: -1 57 | iosUseCustomAppBackgroundBehavior: 0 58 | iosAllowHTTPDownload: 1 59 | allowedAutorotateToPortrait: 1 60 | allowedAutorotateToPortraitUpsideDown: 1 61 | allowedAutorotateToLandscapeRight: 1 62 | allowedAutorotateToLandscapeLeft: 1 63 | useOSAutorotation: 1 64 | use32BitDisplayBuffer: 1 65 | preserveFramebufferAlpha: 0 66 | disableDepthAndStencilBuffers: 0 67 | androidStartInFullscreen: 1 68 | androidRenderOutsideSafeArea: 1 69 | androidUseSwappy: 0 70 | androidBlitType: 0 71 | androidResizableWindow: 0 72 | androidDefaultWindowWidth: 1920 73 | androidDefaultWindowHeight: 1080 74 | androidMinimumWindowWidth: 400 75 | androidMinimumWindowHeight: 300 76 | androidFullscreenMode: 1 77 | defaultIsNativeResolution: 1 78 | macRetinaSupport: 1 79 | runInBackground: 1 80 | captureSingleScreen: 0 81 | muteOtherAudioSources: 0 82 | Prepare IOS For Recording: 0 83 | Force IOS Speakers When Recording: 0 84 | deferSystemGesturesMode: 0 85 | hideHomeButton: 0 86 | submitAnalytics: 1 87 | usePlayerLog: 1 88 | bakeCollisionMeshes: 0 89 | forceSingleInstance: 0 90 | useFlipModelSwapchain: 1 91 | resizableWindow: 0 92 | useMacAppStoreValidation: 0 93 | macAppStoreCategory: public.app-category.games 94 | gpuSkinning: 0 95 | xboxPIXTextureCapture: 0 96 | xboxEnableAvatar: 0 97 | xboxEnableKinect: 0 98 | xboxEnableKinectAutoTracking: 0 99 | xboxEnableFitness: 0 100 | visibleInBackground: 1 101 | allowFullscreenSwitch: 1 102 | fullscreenMode: 1 103 | xboxSpeechDB: 0 104 | xboxEnableHeadOrientation: 0 105 | xboxEnableGuest: 0 106 | xboxEnablePIXSampling: 0 107 | metalFramebufferOnly: 0 108 | xboxOneResolution: 0 109 | xboxOneSResolution: 0 110 | xboxOneXResolution: 3 111 | xboxOneMonoLoggingLevel: 0 112 | xboxOneLoggingLevel: 1 113 | xboxOneDisableEsram: 0 114 | xboxOneEnableTypeOptimization: 0 115 | xboxOnePresentImmediateThreshold: 0 116 | switchQueueCommandMemory: 0 117 | switchQueueControlMemory: 16384 118 | switchQueueComputeMemory: 262144 119 | switchNVNShaderPoolsGranularity: 33554432 120 | switchNVNDefaultPoolsGranularity: 16777216 121 | switchNVNOtherPoolsGranularity: 16777216 122 | switchNVNMaxPublicTextureIDCount: 0 123 | switchNVNMaxPublicSamplerIDCount: 0 124 | stadiaPresentMode: 0 125 | stadiaTargetFramerate: 0 126 | vulkanNumSwapchainBuffers: 3 127 | vulkanEnableSetSRGBWrite: 0 128 | vulkanEnablePreTransform: 0 129 | vulkanEnableLateAcquireNextImage: 0 130 | vulkanEnableCommandBufferRecycling: 1 131 | m_SupportedAspectRatios: 132 | 4:3: 1 133 | 5:4: 1 134 | 16:10: 1 135 | 16:9: 1 136 | Others: 1 137 | bundleVersion: 0.1 138 | preloadedAssets: [] 139 | metroInputSource: 0 140 | wsaTransparentSwapchain: 0 141 | m_HolographicPauseOnTrackingLoss: 1 142 | xboxOneDisableKinectGpuReservation: 1 143 | xboxOneEnable7thCore: 1 144 | vrSettings: 145 | enable360StereoCapture: 0 146 | isWsaHolographicRemotingEnabled: 0 147 | enableFrameTimingStats: 0 148 | useHDRDisplay: 0 149 | D3DHDRBitDepth: 0 150 | m_ColorGamuts: 00000000 151 | targetPixelDensity: 30 152 | resolutionScalingMode: 0 153 | androidSupportedAspectRatio: 1 154 | androidMaxAspectRatio: 2.1 155 | applicationIdentifier: 156 | Standalone: com.Company.ProductName 157 | buildNumber: 158 | Standalone: 0 159 | iPhone: 0 160 | tvOS: 0 161 | overrideDefaultApplicationIdentifier: 1 162 | AndroidBundleVersionCode: 1 163 | AndroidMinSdkVersion: 19 164 | AndroidTargetSdkVersion: 0 165 | AndroidPreferredInstallLocation: 1 166 | aotOptions: 167 | stripEngineCode: 1 168 | iPhoneStrippingLevel: 0 169 | iPhoneScriptCallOptimization: 0 170 | ForceInternetPermission: 0 171 | ForceSDCardPermission: 0 172 | CreateWallpaper: 0 173 | APKExpansionFiles: 0 174 | keepLoadedShadersAlive: 0 175 | StripUnusedMeshComponents: 1 176 | VertexChannelCompressionMask: 4054 177 | iPhoneSdkVersion: 988 178 | iOSTargetOSVersionString: 11.0 179 | tvOSSdkVersion: 0 180 | tvOSRequireExtendedGameController: 0 181 | tvOSTargetOSVersionString: 11.0 182 | uIPrerenderedIcon: 0 183 | uIRequiresPersistentWiFi: 0 184 | uIRequiresFullScreen: 1 185 | uIStatusBarHidden: 1 186 | uIExitOnSuspend: 0 187 | uIStatusBarStyle: 0 188 | appleTVSplashScreen: {fileID: 0} 189 | appleTVSplashScreen2x: {fileID: 0} 190 | tvOSSmallIconLayers: [] 191 | tvOSSmallIconLayers2x: [] 192 | tvOSLargeIconLayers: [] 193 | tvOSLargeIconLayers2x: [] 194 | tvOSTopShelfImageLayers: [] 195 | tvOSTopShelfImageLayers2x: [] 196 | tvOSTopShelfImageWideLayers: [] 197 | tvOSTopShelfImageWideLayers2x: [] 198 | iOSLaunchScreenType: 0 199 | iOSLaunchScreenPortrait: {fileID: 0} 200 | iOSLaunchScreenLandscape: {fileID: 0} 201 | iOSLaunchScreenBackgroundColor: 202 | serializedVersion: 2 203 | rgba: 0 204 | iOSLaunchScreenFillPct: 100 205 | iOSLaunchScreenSize: 100 206 | iOSLaunchScreenCustomXibPath: 207 | iOSLaunchScreeniPadType: 0 208 | iOSLaunchScreeniPadImage: {fileID: 0} 209 | iOSLaunchScreeniPadBackgroundColor: 210 | serializedVersion: 2 211 | rgba: 0 212 | iOSLaunchScreeniPadFillPct: 100 213 | iOSLaunchScreeniPadSize: 100 214 | iOSLaunchScreeniPadCustomXibPath: 215 | iOSLaunchScreenCustomStoryboardPath: 216 | iOSLaunchScreeniPadCustomStoryboardPath: 217 | iOSDeviceRequirements: [] 218 | iOSURLSchemes: [] 219 | iOSBackgroundModes: 0 220 | iOSMetalForceHardShadows: 0 221 | metalEditorSupport: 1 222 | metalAPIValidation: 1 223 | iOSRenderExtraFrameOnPause: 0 224 | iosCopyPluginsCodeInsteadOfSymlink: 0 225 | appleDeveloperTeamID: 226 | iOSManualSigningProvisioningProfileID: 227 | tvOSManualSigningProvisioningProfileID: 228 | iOSManualSigningProvisioningProfileType: 0 229 | tvOSManualSigningProvisioningProfileType: 0 230 | appleEnableAutomaticSigning: 0 231 | iOSRequireARKit: 0 232 | iOSAutomaticallyDetectAndAddCapabilities: 1 233 | appleEnableProMotion: 0 234 | shaderPrecisionModel: 0 235 | clonedFromGUID: 5f34be1353de5cf4398729fda238591b 236 | templatePackageId: com.unity.template.2d@3.2.5 237 | templateDefaultScene: Assets/Scenes/SampleScene.unity 238 | useCustomMainManifest: 0 239 | useCustomLauncherManifest: 0 240 | useCustomMainGradleTemplate: 0 241 | useCustomLauncherGradleManifest: 0 242 | useCustomBaseGradleTemplate: 0 243 | useCustomGradlePropertiesTemplate: 0 244 | useCustomProguardFile: 0 245 | AndroidTargetArchitectures: 1 246 | AndroidTargetDevices: 0 247 | AndroidSplashScreenScale: 0 248 | androidSplashScreen: {fileID: 0} 249 | AndroidKeystoreName: 250 | AndroidKeyaliasName: 251 | AndroidBuildApkPerCpuArchitecture: 0 252 | AndroidTVCompatibility: 0 253 | AndroidIsGame: 1 254 | AndroidEnableTango: 0 255 | androidEnableBanner: 1 256 | androidUseLowAccuracyLocation: 0 257 | androidUseCustomKeystore: 0 258 | m_AndroidBanners: 259 | - width: 320 260 | height: 180 261 | banner: {fileID: 0} 262 | androidGamepadSupportLevel: 0 263 | chromeosInputEmulation: 1 264 | AndroidMinifyWithR8: 0 265 | AndroidMinifyRelease: 0 266 | AndroidMinifyDebug: 0 267 | AndroidValidateAppBundleSize: 1 268 | AndroidAppBundleSizeToValidate: 150 269 | m_BuildTargetIcons: [] 270 | m_BuildTargetPlatformIcons: [] 271 | m_BuildTargetBatching: [] 272 | m_BuildTargetGraphicsJobs: 273 | - m_BuildTarget: GameCoreScarlettSupport 274 | m_GraphicsJobs: 0 275 | - m_BuildTarget: Switch 276 | m_GraphicsJobs: 0 277 | - m_BuildTarget: iOSSupport 278 | m_GraphicsJobs: 0 279 | - m_BuildTarget: LuminSupport 280 | m_GraphicsJobs: 0 281 | - m_BuildTarget: MacStandaloneSupport 282 | m_GraphicsJobs: 0 283 | - m_BuildTarget: PS5Player 284 | m_GraphicsJobs: 0 285 | - m_BuildTarget: WebGLSupport 286 | m_GraphicsJobs: 0 287 | - m_BuildTarget: AppleTVSupport 288 | m_GraphicsJobs: 0 289 | - m_BuildTarget: GameCoreXboxOneSupport 290 | m_GraphicsJobs: 0 291 | - m_BuildTarget: CloudRendering 292 | m_GraphicsJobs: 0 293 | - m_BuildTarget: WindowsStandaloneSupport 294 | m_GraphicsJobs: 0 295 | - m_BuildTarget: PS4Player 296 | m_GraphicsJobs: 0 297 | - m_BuildTarget: MetroSupport 298 | m_GraphicsJobs: 0 299 | - m_BuildTarget: AndroidPlayer 300 | m_GraphicsJobs: 0 301 | - m_BuildTarget: BJMSupport 302 | m_GraphicsJobs: 0 303 | - m_BuildTarget: LinuxStandaloneSupport 304 | m_GraphicsJobs: 0 305 | - m_BuildTarget: XboxOnePlayer 306 | m_GraphicsJobs: 0 307 | m_BuildTargetGraphicsJobMode: 308 | - m_BuildTarget: PS4Player 309 | m_GraphicsJobMode: 0 310 | - m_BuildTarget: XboxOnePlayer 311 | m_GraphicsJobMode: 0 312 | m_BuildTargetGraphicsAPIs: 313 | - m_BuildTarget: AndroidPlayer 314 | m_APIs: 150000000b000000 315 | m_Automatic: 0 316 | - m_BuildTarget: iOSSupport 317 | m_APIs: 10000000 318 | m_Automatic: 1 319 | m_BuildTargetVRSettings: [] 320 | openGLRequireES31: 0 321 | openGLRequireES31AEP: 0 322 | openGLRequireES32: 0 323 | m_TemplateCustomTags: {} 324 | mobileMTRendering: 325 | Android: 1 326 | iPhone: 1 327 | tvOS: 1 328 | m_BuildTargetGroupLightmapEncodingQuality: [] 329 | m_BuildTargetGroupLightmapSettings: [] 330 | m_BuildTargetNormalMapEncoding: [] 331 | playModeTestRunnerEnabled: 0 332 | runPlayModeTestAsEditModeTest: 0 333 | actionOnDotNetUnhandledException: 1 334 | enableInternalProfiler: 0 335 | logObjCUncaughtExceptions: 1 336 | enableCrashReportAPI: 0 337 | cameraUsageDescription: 338 | locationUsageDescription: 339 | microphoneUsageDescription: 340 | bluetoothUsageDescription: 341 | switchNMETAOverride: 342 | switchNetLibKey: 343 | switchSocketMemoryPoolSize: 6144 344 | switchSocketAllocatorPoolSize: 128 345 | switchSocketConcurrencyLimit: 14 346 | switchScreenResolutionBehavior: 2 347 | switchUseCPUProfiler: 0 348 | switchUseGOLDLinker: 0 349 | switchApplicationID: 0x01004b9000490000 350 | switchNSODependencies: 351 | switchTitleNames_0: 352 | switchTitleNames_1: 353 | switchTitleNames_2: 354 | switchTitleNames_3: 355 | switchTitleNames_4: 356 | switchTitleNames_5: 357 | switchTitleNames_6: 358 | switchTitleNames_7: 359 | switchTitleNames_8: 360 | switchTitleNames_9: 361 | switchTitleNames_10: 362 | switchTitleNames_11: 363 | switchTitleNames_12: 364 | switchTitleNames_13: 365 | switchTitleNames_14: 366 | switchTitleNames_15: 367 | switchPublisherNames_0: 368 | switchPublisherNames_1: 369 | switchPublisherNames_2: 370 | switchPublisherNames_3: 371 | switchPublisherNames_4: 372 | switchPublisherNames_5: 373 | switchPublisherNames_6: 374 | switchPublisherNames_7: 375 | switchPublisherNames_8: 376 | switchPublisherNames_9: 377 | switchPublisherNames_10: 378 | switchPublisherNames_11: 379 | switchPublisherNames_12: 380 | switchPublisherNames_13: 381 | switchPublisherNames_14: 382 | switchPublisherNames_15: 383 | switchIcons_0: {fileID: 0} 384 | switchIcons_1: {fileID: 0} 385 | switchIcons_2: {fileID: 0} 386 | switchIcons_3: {fileID: 0} 387 | switchIcons_4: {fileID: 0} 388 | switchIcons_5: {fileID: 0} 389 | switchIcons_6: {fileID: 0} 390 | switchIcons_7: {fileID: 0} 391 | switchIcons_8: {fileID: 0} 392 | switchIcons_9: {fileID: 0} 393 | switchIcons_10: {fileID: 0} 394 | switchIcons_11: {fileID: 0} 395 | switchIcons_12: {fileID: 0} 396 | switchIcons_13: {fileID: 0} 397 | switchIcons_14: {fileID: 0} 398 | switchIcons_15: {fileID: 0} 399 | switchSmallIcons_0: {fileID: 0} 400 | switchSmallIcons_1: {fileID: 0} 401 | switchSmallIcons_2: {fileID: 0} 402 | switchSmallIcons_3: {fileID: 0} 403 | switchSmallIcons_4: {fileID: 0} 404 | switchSmallIcons_5: {fileID: 0} 405 | switchSmallIcons_6: {fileID: 0} 406 | switchSmallIcons_7: {fileID: 0} 407 | switchSmallIcons_8: {fileID: 0} 408 | switchSmallIcons_9: {fileID: 0} 409 | switchSmallIcons_10: {fileID: 0} 410 | switchSmallIcons_11: {fileID: 0} 411 | switchSmallIcons_12: {fileID: 0} 412 | switchSmallIcons_13: {fileID: 0} 413 | switchSmallIcons_14: {fileID: 0} 414 | switchSmallIcons_15: {fileID: 0} 415 | switchManualHTML: 416 | switchAccessibleURLs: 417 | switchLegalInformation: 418 | switchMainThreadStackSize: 1048576 419 | switchPresenceGroupId: 420 | switchLogoHandling: 0 421 | switchReleaseVersion: 0 422 | switchDisplayVersion: 1.0.0 423 | switchStartupUserAccount: 0 424 | switchTouchScreenUsage: 0 425 | switchSupportedLanguagesMask: 0 426 | switchLogoType: 0 427 | switchApplicationErrorCodeCategory: 428 | switchUserAccountSaveDataSize: 0 429 | switchUserAccountSaveDataJournalSize: 0 430 | switchApplicationAttribute: 0 431 | switchCardSpecSize: -1 432 | switchCardSpecClock: -1 433 | switchRatingsMask: 0 434 | switchRatingsInt_0: 0 435 | switchRatingsInt_1: 0 436 | switchRatingsInt_2: 0 437 | switchRatingsInt_3: 0 438 | switchRatingsInt_4: 0 439 | switchRatingsInt_5: 0 440 | switchRatingsInt_6: 0 441 | switchRatingsInt_7: 0 442 | switchRatingsInt_8: 0 443 | switchRatingsInt_9: 0 444 | switchRatingsInt_10: 0 445 | switchRatingsInt_11: 0 446 | switchRatingsInt_12: 0 447 | switchLocalCommunicationIds_0: 448 | switchLocalCommunicationIds_1: 449 | switchLocalCommunicationIds_2: 450 | switchLocalCommunicationIds_3: 451 | switchLocalCommunicationIds_4: 452 | switchLocalCommunicationIds_5: 453 | switchLocalCommunicationIds_6: 454 | switchLocalCommunicationIds_7: 455 | switchParentalControl: 0 456 | switchAllowsScreenshot: 1 457 | switchAllowsVideoCapturing: 1 458 | switchAllowsRuntimeAddOnContentInstall: 0 459 | switchDataLossConfirmation: 0 460 | switchUserAccountLockEnabled: 0 461 | switchSystemResourceMemory: 16777216 462 | switchSupportedNpadStyles: 22 463 | switchNativeFsCacheSize: 32 464 | switchIsHoldTypeHorizontal: 0 465 | switchSupportedNpadCount: 8 466 | switchSocketConfigEnabled: 0 467 | switchTcpInitialSendBufferSize: 32 468 | switchTcpInitialReceiveBufferSize: 64 469 | switchTcpAutoSendBufferSizeMax: 256 470 | switchTcpAutoReceiveBufferSizeMax: 256 471 | switchUdpSendBufferSize: 9 472 | switchUdpReceiveBufferSize: 42 473 | switchSocketBufferEfficiency: 4 474 | switchSocketInitializeEnabled: 1 475 | switchNetworkInterfaceManagerInitializeEnabled: 1 476 | switchPlayerConnectionEnabled: 1 477 | switchUseNewStyleFilepaths: 0 478 | switchUseMicroSleepForYield: 1 479 | switchEnableRamDiskSupport: 0 480 | switchMicroSleepForYieldTime: 25 481 | switchRamDiskSpaceSize: 12 482 | ps4NPAgeRating: 12 483 | ps4NPTitleSecret: 484 | ps4NPTrophyPackPath: 485 | ps4ParentalLevel: 11 486 | ps4ContentID: ED1633-NPXX51362_00-0000000000000000 487 | ps4Category: 0 488 | ps4MasterVersion: 01.00 489 | ps4AppVersion: 01.00 490 | ps4AppType: 0 491 | ps4ParamSfxPath: 492 | ps4VideoOutPixelFormat: 0 493 | ps4VideoOutInitialWidth: 1920 494 | ps4VideoOutBaseModeInitialWidth: 1920 495 | ps4VideoOutReprojectionRate: 60 496 | ps4PronunciationXMLPath: 497 | ps4PronunciationSIGPath: 498 | ps4BackgroundImagePath: 499 | ps4StartupImagePath: 500 | ps4StartupImagesFolder: 501 | ps4IconImagesFolder: 502 | ps4SaveDataImagePath: 503 | ps4SdkOverride: 504 | ps4BGMPath: 505 | ps4ShareFilePath: 506 | ps4ShareOverlayImagePath: 507 | ps4PrivacyGuardImagePath: 508 | ps4ExtraSceSysFile: 509 | ps4NPtitleDatPath: 510 | ps4RemotePlayKeyAssignment: -1 511 | ps4RemotePlayKeyMappingDir: 512 | ps4PlayTogetherPlayerCount: 0 513 | ps4EnterButtonAssignment: 1 514 | ps4ApplicationParam1: 0 515 | ps4ApplicationParam2: 0 516 | ps4ApplicationParam3: 0 517 | ps4ApplicationParam4: 0 518 | ps4DownloadDataSize: 0 519 | ps4GarlicHeapSize: 2048 520 | ps4ProGarlicHeapSize: 2560 521 | playerPrefsMaxSize: 32768 522 | ps4Passcode: frAQBc8Wsa1xVPfvJcrgRYwTiizs2trQ 523 | ps4pnSessions: 1 524 | ps4pnPresence: 1 525 | ps4pnFriends: 1 526 | ps4pnGameCustomData: 1 527 | playerPrefsSupport: 0 528 | enableApplicationExit: 0 529 | resetTempFolder: 1 530 | restrictedAudioUsageRights: 0 531 | ps4UseResolutionFallback: 0 532 | ps4ReprojectionSupport: 0 533 | ps4UseAudio3dBackend: 0 534 | ps4UseLowGarlicFragmentationMode: 1 535 | ps4SocialScreenEnabled: 0 536 | ps4ScriptOptimizationLevel: 0 537 | ps4Audio3dVirtualSpeakerCount: 14 538 | ps4attribCpuUsage: 0 539 | ps4PatchPkgPath: 540 | ps4PatchLatestPkgPath: 541 | ps4PatchChangeinfoPath: 542 | ps4PatchDayOne: 0 543 | ps4attribUserManagement: 0 544 | ps4attribMoveSupport: 0 545 | ps4attrib3DSupport: 0 546 | ps4attribShareSupport: 0 547 | ps4attribExclusiveVR: 0 548 | ps4disableAutoHideSplash: 0 549 | ps4videoRecordingFeaturesUsed: 0 550 | ps4contentSearchFeaturesUsed: 0 551 | ps4CompatibilityPS5: 0 552 | ps4AllowPS5Detection: 0 553 | ps4GPU800MHz: 1 554 | ps4attribEyeToEyeDistanceSettingVR: 0 555 | ps4IncludedModules: [] 556 | ps4attribVROutputEnabled: 0 557 | monoEnv: 558 | splashScreenBackgroundSourceLandscape: {fileID: 0} 559 | splashScreenBackgroundSourcePortrait: {fileID: 0} 560 | blurSplashScreenBackground: 1 561 | spritePackerPolicy: 562 | webGLMemorySize: 16 563 | webGLExceptionSupport: 1 564 | webGLNameFilesAsHashes: 0 565 | webGLDataCaching: 1 566 | webGLDebugSymbols: 0 567 | webGLEmscriptenArgs: 568 | webGLModulesDirectory: 569 | webGLTemplate: APPLICATION:Default 570 | webGLAnalyzeBuildSize: 0 571 | webGLUseEmbeddedResources: 0 572 | webGLCompressionFormat: 1 573 | webGLWasmArithmeticExceptions: 0 574 | webGLLinkerTarget: 1 575 | webGLThreadsSupport: 0 576 | webGLDecompressionFallback: 0 577 | scriptingDefineSymbols: {} 578 | additionalCompilerArguments: {} 579 | platformArchitecture: {} 580 | scriptingBackend: 581 | Standalone: 1 582 | il2cppCompilerConfiguration: {} 583 | managedStrippingLevel: {} 584 | incrementalIl2cppBuild: {} 585 | suppressCommonWarnings: 1 586 | allowUnsafeCode: 0 587 | useDeterministicCompilation: 1 588 | useReferenceAssemblies: 1 589 | enableRoslynAnalyzers: 1 590 | additionalIl2CppArgs: 591 | scriptingRuntimeVersion: 1 592 | gcIncremental: 0 593 | assemblyVersionValidation: 1 594 | gcWBarrierValidation: 0 595 | apiCompatibilityLevelPerPlatform: 596 | Standalone: 3 597 | m_RenderingPath: 1 598 | m_MobileRenderingPath: 1 599 | metroPackageName: Template_2D 600 | metroPackageVersion: 601 | metroCertificatePath: 602 | metroCertificatePassword: 603 | metroCertificateSubject: 604 | metroCertificateIssuer: 605 | metroCertificateNotAfter: 0000000000000000 606 | metroApplicationDescription: Template_2D 607 | wsaImages: {} 608 | metroTileShortName: 609 | metroTileShowName: 0 610 | metroMediumTileShowName: 0 611 | metroLargeTileShowName: 0 612 | metroWideTileShowName: 0 613 | metroSupportStreamingInstall: 0 614 | metroLastRequiredScene: 0 615 | metroDefaultTileSize: 1 616 | metroTileForegroundText: 2 617 | metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0} 618 | metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, 619 | a: 1} 620 | metroSplashScreenUseBackgroundColor: 0 621 | platformCapabilities: {} 622 | metroTargetDeviceFamilies: {} 623 | metroFTAName: 624 | metroFTAFileTypes: [] 625 | metroProtocolName: 626 | vcxProjDefaultLanguage: 627 | XboxOneProductId: 628 | XboxOneUpdateKey: 629 | XboxOneSandboxId: 630 | XboxOneContentId: 631 | XboxOneTitleId: 632 | XboxOneSCId: 633 | XboxOneGameOsOverridePath: 634 | XboxOnePackagingOverridePath: 635 | XboxOneAppManifestOverridePath: 636 | XboxOneVersion: 1.0.0.0 637 | XboxOnePackageEncryption: 0 638 | XboxOnePackageUpdateGranularity: 2 639 | XboxOneDescription: 640 | XboxOneLanguage: 641 | - enus 642 | XboxOneCapability: [] 643 | XboxOneGameRating: {} 644 | XboxOneIsContentPackage: 0 645 | XboxOneEnhancedXboxCompatibilityMode: 0 646 | XboxOneEnableGPUVariability: 1 647 | XboxOneSockets: {} 648 | XboxOneSplashScreen: {fileID: 0} 649 | XboxOneAllowedProductIds: [] 650 | XboxOnePersistentLocalStorageSize: 0 651 | XboxOneXTitleMemory: 8 652 | XboxOneOverrideIdentityName: 653 | XboxOneOverrideIdentityPublisher: 654 | vrEditorSettings: {} 655 | cloudServicesEnabled: 656 | UNet: 1 657 | luminIcon: 658 | m_Name: 659 | m_ModelFolderPath: 660 | m_PortalFolderPath: 661 | luminCert: 662 | m_CertPath: 663 | m_SignPackage: 1 664 | luminIsChannelApp: 0 665 | luminVersion: 666 | m_VersionCode: 1 667 | m_VersionName: 668 | apiCompatibilityLevel: 6 669 | activeInputHandler: 0 670 | cloudProjectId: 671 | framebufferDepthMemorylessMode: 0 672 | qualitySettingsNames: [] 673 | projectName: 674 | organizationId: 675 | cloudEnabled: 0 676 | legacyClampBlendShapeWeights: 0 677 | virtualTexturingSupportEnabled: 0 678 | -------------------------------------------------------------------------------- /ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 2020.3.33f1 2 | m_EditorVersionWithRevision: 2020.3.33f1 (915a7af8b0d5) 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: 0 8 | m_QualitySettings: 9 | - serializedVersion: 2 10 | name: Medium 11 | pixelLightCount: 1 12 | shadows: 0 13 | shadowResolution: 0 14 | shadowProjection: 1 15 | shadowCascades: 1 16 | shadowDistance: 20 17 | shadowNearPlaneOffset: 3 18 | shadowCascade2Split: 0.33333334 19 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 20 | shadowmaskMode: 0 21 | skinWeights: 2 22 | textureQuality: 0 23 | anisotropicTextures: 0 24 | antiAliasing: 0 25 | softParticles: 0 26 | softVegetation: 0 27 | realtimeReflectionProbes: 0 28 | billboardsFaceCameraPosition: 0 29 | vSyncCount: 0 30 | lodBias: 0.7 31 | maximumLODLevel: 0 32 | streamingMipmapsActive: 0 33 | streamingMipmapsAddAllCameras: 1 34 | streamingMipmapsMemoryBudget: 512 35 | streamingMipmapsRenderersPerFrame: 512 36 | streamingMipmapsMaxLevelReduction: 2 37 | streamingMipmapsMaxFileIORequests: 1024 38 | particleRaycastBudget: 64 39 | asyncUploadTimeSlice: 2 40 | asyncUploadBufferSize: 16 41 | asyncUploadPersistentBuffer: 1 42 | resolutionScalingFixedDPIFactor: 1 43 | excludedTargetPlatforms: [] 44 | m_PerPlatformDefaultQuality: 45 | Android: 0 46 | Nintendo 3DS: 0 47 | Nintendo Switch: 0 48 | PS4: 0 49 | PSM: 0 50 | PSP2: 0 51 | Stadia: 0 52 | Standalone: 0 53 | Tizen: 0 54 | WebGL: 0 55 | WiiU: 0 56 | Windows Store Apps: 0 57 | XboxOne: 0 58 | iPhone: 0 59 | tvOS: 0 60 | -------------------------------------------------------------------------------- /ProjectSettings/SceneTemplateSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "templatePinStates": [], 3 | "dependencyTypeInfos": [ 4 | { 5 | "userAdded": false, 6 | "type": "UnityEngine.AnimationClip", 7 | "ignore": false, 8 | "defaultInstantiationMode": 0, 9 | "supportsModification": true 10 | }, 11 | { 12 | "userAdded": false, 13 | "type": "UnityEditor.Animations.AnimatorController", 14 | "ignore": false, 15 | "defaultInstantiationMode": 0, 16 | "supportsModification": true 17 | }, 18 | { 19 | "userAdded": false, 20 | "type": "UnityEngine.AnimatorOverrideController", 21 | "ignore": false, 22 | "defaultInstantiationMode": 0, 23 | "supportsModification": true 24 | }, 25 | { 26 | "userAdded": false, 27 | "type": "UnityEditor.Audio.AudioMixerController", 28 | "ignore": false, 29 | "defaultInstantiationMode": 0, 30 | "supportsModification": true 31 | }, 32 | { 33 | "userAdded": false, 34 | "type": "UnityEngine.ComputeShader", 35 | "ignore": true, 36 | "defaultInstantiationMode": 1, 37 | "supportsModification": true 38 | }, 39 | { 40 | "userAdded": false, 41 | "type": "UnityEngine.Cubemap", 42 | "ignore": false, 43 | "defaultInstantiationMode": 0, 44 | "supportsModification": true 45 | }, 46 | { 47 | "userAdded": false, 48 | "type": "UnityEngine.GameObject", 49 | "ignore": false, 50 | "defaultInstantiationMode": 0, 51 | "supportsModification": true 52 | }, 53 | { 54 | "userAdded": false, 55 | "type": "UnityEditor.LightingDataAsset", 56 | "ignore": false, 57 | "defaultInstantiationMode": 0, 58 | "supportsModification": false 59 | }, 60 | { 61 | "userAdded": false, 62 | "type": "UnityEngine.LightingSettings", 63 | "ignore": false, 64 | "defaultInstantiationMode": 0, 65 | "supportsModification": true 66 | }, 67 | { 68 | "userAdded": false, 69 | "type": "UnityEngine.Material", 70 | "ignore": false, 71 | "defaultInstantiationMode": 0, 72 | "supportsModification": true 73 | }, 74 | { 75 | "userAdded": false, 76 | "type": "UnityEditor.MonoScript", 77 | "ignore": true, 78 | "defaultInstantiationMode": 1, 79 | "supportsModification": true 80 | }, 81 | { 82 | "userAdded": false, 83 | "type": "UnityEngine.PhysicMaterial", 84 | "ignore": false, 85 | "defaultInstantiationMode": 0, 86 | "supportsModification": true 87 | }, 88 | { 89 | "userAdded": false, 90 | "type": "UnityEngine.PhysicsMaterial2D", 91 | "ignore": false, 92 | "defaultInstantiationMode": 0, 93 | "supportsModification": true 94 | }, 95 | { 96 | "userAdded": false, 97 | "type": "UnityEngine.Rendering.PostProcessing.PostProcessProfile", 98 | "ignore": false, 99 | "defaultInstantiationMode": 0, 100 | "supportsModification": true 101 | }, 102 | { 103 | "userAdded": false, 104 | "type": "UnityEngine.Rendering.PostProcessing.PostProcessResources", 105 | "ignore": false, 106 | "defaultInstantiationMode": 0, 107 | "supportsModification": true 108 | }, 109 | { 110 | "userAdded": false, 111 | "type": "UnityEngine.Rendering.VolumeProfile", 112 | "ignore": false, 113 | "defaultInstantiationMode": 0, 114 | "supportsModification": true 115 | }, 116 | { 117 | "userAdded": false, 118 | "type": "UnityEditor.SceneAsset", 119 | "ignore": false, 120 | "defaultInstantiationMode": 0, 121 | "supportsModification": false 122 | }, 123 | { 124 | "userAdded": false, 125 | "type": "UnityEngine.Shader", 126 | "ignore": true, 127 | "defaultInstantiationMode": 1, 128 | "supportsModification": true 129 | }, 130 | { 131 | "userAdded": false, 132 | "type": "UnityEngine.ShaderVariantCollection", 133 | "ignore": true, 134 | "defaultInstantiationMode": 1, 135 | "supportsModification": true 136 | }, 137 | { 138 | "userAdded": false, 139 | "type": "UnityEngine.Texture", 140 | "ignore": false, 141 | "defaultInstantiationMode": 0, 142 | "supportsModification": true 143 | }, 144 | { 145 | "userAdded": false, 146 | "type": "UnityEngine.Texture2D", 147 | "ignore": false, 148 | "defaultInstantiationMode": 0, 149 | "supportsModification": true 150 | }, 151 | { 152 | "userAdded": false, 153 | "type": "UnityEngine.Timeline.TimelineAsset", 154 | "ignore": false, 155 | "defaultInstantiationMode": 0, 156 | "supportsModification": true 157 | } 158 | ], 159 | "defaultDependencyTypeInfo": { 160 | "userAdded": false, 161 | "type": "", 162 | "ignore": false, 163 | "defaultInstantiationMode": 1, 164 | "supportsModification": true 165 | }, 166 | "newSceneOverride": 0 167 | } -------------------------------------------------------------------------------- /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/VersionControlSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!890905787 &1 4 | VersionControlSettings: 5 | m_ObjectHideFlags: 0 6 | m_Mode: Visible Meta Files 7 | m_CollabEditorSettings: 8 | inProgressEnabled: 1 9 | -------------------------------------------------------------------------------- /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 | # Unity_SpriteBatcherTest 2 | A simple test to batch multiple sprites in a dynamic mesh 3 | 4 | Update: added a new sprite batcher that utilizes Jobs system and Burst compiler. It's ~10x more performant. 5 | -------------------------------------------------------------------------------- /UserSettings/EditorUserSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!162 &1 4 | EditorUserSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 4 7 | m_ConfigSettings: 8 | RecentlyUsedScenePath-0: 9 | value: 22424703114646680e0b0227036c6c00041e0c2f0e293233252c0f19ede23d3eebe232dde2292b722c0ce6281d 10 | flags: 0 11 | vcSharedLogLevel: 12 | value: 0d5e400f0650 13 | flags: 0 14 | m_VCAutomaticAdd: 1 15 | m_VCDebugCom: 0 16 | m_VCDebugCmd: 0 17 | m_VCDebugOut: 0 18 | m_SemanticMergeMode: 2 19 | m_VCShowFailedCheckout: 1 20 | m_VCOverwriteFailedCheckoutAssets: 1 21 | m_VCProjectOverlayIcons: 1 22 | m_VCHierarchyOverlayIcons: 1 23 | m_VCOtherOverlayIcons: 1 24 | m_VCAllowAsyncUpdate: 0 25 | --------------------------------------------------------------------------------