├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── CHANGELOG.md ├── CHANGELOG.md.meta ├── Docs.meta ├── Docs ├── AddPackage.png ├── AddPackage.png.meta ├── AutoBinding.png ├── AutoBinding.png.meta ├── ButtonPressBinding.png ├── ButtonPressBinding.png.meta ├── FigmaPrototype.png ├── FigmaPrototype.png.meta ├── SelectPage.png ├── SelectPage.png.meta ├── UnityFigmaBridgeBanner.png └── UnityFigmaBridgeBanner.png.meta ├── LICENSE ├── LICENSE.meta ├── README.md ├── README.md.meta ├── UnityFigmaBridge.meta ├── UnityFigmaBridge ├── Assets.meta ├── Assets │ ├── TransitionFadeToBlack.controller │ ├── TransitionFadeToBlack.controller.meta │ ├── TransitionFadeToBlack.prefab │ ├── TransitionFadeToBlack.prefab.meta │ ├── TransitionFadeToBlackAnimateIn.anim │ ├── TransitionFadeToBlackAnimateIn.anim.meta │ ├── TransitionFadeToBlackAnimateOut.anim │ ├── TransitionFadeToBlackAnimateOut.anim.meta │ ├── TransitionFadeToBlackHidden.anim │ ├── TransitionFadeToBlackHidden.anim.meta │ ├── google-fonts.json │ └── google-fonts.json.meta ├── BindFigmaButtonPress.cs ├── BindFigmaButtonPress.cs.meta ├── Editor.meta ├── Editor │ ├── Components.meta │ ├── Components │ │ ├── ComponentManager.cs │ │ └── ComponentManager.cs.meta │ ├── FigmaApi.meta │ ├── FigmaApi │ │ ├── FigmaApiData.cs │ │ ├── FigmaApiData.cs.meta │ │ ├── FigmaApiUtils.cs │ │ ├── FigmaApiUtils.cs.meta │ │ ├── FigmaDataUtils.cs │ │ └── FigmaDataUtils.cs.meta │ ├── FigmaImportProcessData.cs │ ├── FigmaImportProcessData.cs.meta │ ├── Fonts.meta │ ├── Fonts │ │ ├── FontManager.cs │ │ ├── FontManager.cs.meta │ │ ├── GoogleFontLibraryManager.cs │ │ ├── GoogleFontLibraryManager.cs.meta │ │ ├── TextMeshProFontUtils.cs │ │ └── TextMeshProFontUtils.cs.meta │ ├── Nodes.meta │ ├── Nodes │ │ ├── EffectManager.cs │ │ ├── EffectManager.cs.meta │ │ ├── FigmaAssetGenerator.cs │ │ ├── FigmaAssetGenerator.cs.meta │ │ ├── FigmaLayoutManager.cs │ │ ├── FigmaLayoutManager.cs.meta │ │ ├── FigmaNodeManager.cs │ │ ├── FigmaNodeManager.cs.meta │ │ ├── NodeTransformManager.cs │ │ └── NodeTransformManager.cs.meta │ ├── PrototypeFlow.meta │ ├── PrototypeFlow │ │ ├── BehaviourBindingManager.cs │ │ ├── BehaviourBindingManager.cs.meta │ │ ├── PrototypeFlowManager.cs │ │ ├── PrototypeFlowManager.cs.meta │ │ ├── ScreenNameCodeGenerator.cs │ │ └── ScreenNameCodeGenerator.cs.meta │ ├── Settings.meta │ ├── Settings │ │ ├── UnityFigmaBridgeSettings.cs │ │ ├── UnityFigmaBridgeSettings.cs.meta │ │ ├── UnityFigmaBridgeSettingsEditor.cs │ │ ├── UnityFigmaBridgeSettingsEditor.cs.meta │ │ ├── UnityFigmaBridgeSettingsProvider.cs │ │ └── UnityFigmaBridgeSettingsProvider.cs.meta │ ├── UnityComponentEditors.meta │ ├── UnityComponentEditors │ │ ├── FigmaImageEditor.cs │ │ └── FigmaImageEditor.cs.meta │ ├── UnityFigmaBridgeEditor.asmdef │ ├── UnityFigmaBridgeEditor.asmdef.meta │ ├── UnityFigmaBridgeImporter.cs │ ├── UnityFigmaBridgeImporter.cs.meta │ ├── Utils.meta │ └── Utils │ │ ├── EditorInputDialog.cs │ │ ├── EditorInputDialog.cs.meta │ │ ├── FigmaPaths.cs │ │ ├── FigmaPaths.cs.meta │ │ ├── MathUtils.cs │ │ ├── MathUtils.cs.meta │ │ ├── UnityUiUtils.cs │ │ ├── UnityUiUtils.cs.meta │ │ ├── UnityWebRequestAwaiter.cs │ │ └── UnityWebRequestAwaiter.cs.meta ├── Runtime.meta ├── Runtime │ ├── Resources.meta │ ├── Resources │ │ ├── Shaders.meta │ │ └── Shaders │ │ │ ├── FigmaImageShader.shader │ │ │ ├── FigmaImageShader.shader.meta │ │ │ ├── FigmaTextMeshPro.shader │ │ │ └── FigmaTextMeshPro.shader.meta │ ├── UI.meta │ └── UI │ │ ├── FigmaComponentNodeMarker.cs │ │ ├── FigmaComponentNodeMarker.cs.meta │ │ ├── FigmaImage.cs │ │ ├── FigmaImage.cs.meta │ │ ├── FigmaNodeObject.cs │ │ ├── FigmaNodeObject.cs.meta │ │ ├── FigmaPrototypeFlowButton.cs │ │ ├── FigmaPrototypeFlowButton.cs.meta │ │ ├── FigmaScreenUtils.cs │ │ ├── FigmaScreenUtils.cs.meta │ │ ├── PrototypeFlowController.cs │ │ ├── PrototypeFlowController.cs.meta │ │ ├── SafeArea.cs │ │ ├── SafeArea.cs.meta │ │ ├── TransitionEffect.cs │ │ ├── TransitionEffect.cs.meta │ │ ├── TransitionEffectAnimationDriven.cs │ │ └── TransitionEffectAnimationDriven.cs.meta ├── UnityFigmaBridgeRuntime.asmdef └── UnityFigmaBridgeRuntime.asmdef.meta ├── package.json └── package.json.meta /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[BUG]" 5 | labels: bug, enhancement 6 | assignees: simonoliver 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots and example Figma File** 24 | If applicable, add screenshots and/or a link to an example Figma file to help explain your problem. 25 | 26 | ** Version** 27 | - Unity Version: [e.g. Unity 2021.3.11] 28 | - Platform [e.g. Windows 11] 29 | - Rendering Pipeline [e.g Built-in render pipepline or URP 12.1.10] 30 | 31 | **Additional context** 32 | Add any other context about the problem here. 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "[FEATURE REQUEST]" 5 | labels: enhancement 6 | assignees: simonoliver 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log: 2 | 3 | ## 1.0.8 4 | 5 | Better support for Linear Color Space (@naoya-maeda). Please note that from this release 6 | all imported textures will have sRGB set to true. The FigmaImage component 7 | now supports sRGB textures in both gamma and linear color spaces/ 8 | 9 | ## 1.0.7 10 | 11 | - Enhancement - Added support for "Fit" Image mode (@laura-copop) 12 | - Enhancement - Added support for flipped nodes (@laura-copop) 13 | - Bug fix - JSON Deserialisation no longer throws errors for missing items (@laura-copop) 14 | - Bug fix - Correctly uses project colorspace (@laura-copop) 15 | - Bug fix - Non-visible fills no longer default to visible (@laura-copop) 16 | - Bug fix - Server side images now batch where required to prevent Figma API errors 17 | 18 | ## 1.0.6 19 | 20 | - Enhancement - Added page sync selection (thanks @SatoruUeda) 21 | - Enhancement - Implemented correct alignment for auto-layout 22 | - Enhancement - Use Server-side rendering for boolean shapes 23 | - Bug Fix - Fix for crash import for deeply nested components 24 | - Change - Auto layout components are disabled by default 25 | - Bug fix - Masked objects no longer render the masks themselves 26 | 27 | ## 1.0.5 28 | 29 | Small release adding a few new Figma features and bugs. Thanks @SatoruUeda for the contributions and for all the reports. 30 | 31 | - Enhancement -Added support for "Fill" Image mode 32 | - Enhancement -Added text auto sizing 33 | - Enhancement -Added image fill opacity support 34 | - Enhancement -Added layer opacity support 35 | - Bug fix - Fixed issues with components being overwritten 36 | - Bug fix - Numerous other small bugfixes -------------------------------------------------------------------------------- /CHANGELOG.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3ecb569643c7488aa9225a239385adaa 3 | timeCreated: 1687965599 -------------------------------------------------------------------------------- /Docs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8f34ac6b2529cb84dad0090116c61844 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Docs/AddPackage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simonoliver/UnityFigmaBridge/dbd12bff29e8bc84e2682bb19495899711651455/Docs/AddPackage.png -------------------------------------------------------------------------------- /Docs/AddPackage.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f8e9e96ae66fea64d9d893dee86c1bc3 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 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 | vTOnly: 0 27 | ignoreMasterTextureLimit: 0 28 | grayScaleToAlpha: 0 29 | generateCubemap: 6 30 | cubemapConvolution: 0 31 | seamlessCubemap: 0 32 | textureFormat: 1 33 | maxTextureSize: 2048 34 | textureSettings: 35 | serializedVersion: 2 36 | filterMode: 1 37 | aniso: 1 38 | mipBias: 0 39 | wrapU: 1 40 | wrapV: 1 41 | wrapW: 1 42 | nPOTScale: 0 43 | lightmap: 0 44 | compressionQuality: 50 45 | spriteMode: 1 46 | spriteExtrude: 1 47 | spriteMeshType: 1 48 | alignment: 0 49 | spritePivot: {x: 0.5, y: 0.5} 50 | spritePixelsToUnits: 100 51 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 52 | spriteGenerateFallbackPhysicsShape: 1 53 | alphaUsage: 1 54 | alphaIsTransparency: 1 55 | spriteTessellationDetail: -1 56 | textureType: 8 57 | textureShape: 1 58 | singleChannelComponent: 0 59 | flipbookRows: 1 60 | flipbookColumns: 1 61 | maxTextureSizeSet: 0 62 | compressionQualitySet: 0 63 | textureFormatSet: 0 64 | ignorePngGamma: 0 65 | applyGammaDecoding: 0 66 | cookieLightType: 0 67 | platformSettings: 68 | - serializedVersion: 3 69 | buildTarget: DefaultTexturePlatform 70 | maxTextureSize: 2048 71 | resizeAlgorithm: 0 72 | textureFormat: -1 73 | textureCompression: 1 74 | compressionQuality: 50 75 | crunchedCompression: 0 76 | allowsAlphaSplitting: 0 77 | overridden: 0 78 | androidETC2FallbackOverride: 0 79 | forceMaximumCompressionQuality_BC6H_BC7: 0 80 | - serializedVersion: 3 81 | buildTarget: Standalone 82 | maxTextureSize: 2048 83 | resizeAlgorithm: 0 84 | textureFormat: -1 85 | textureCompression: 1 86 | compressionQuality: 50 87 | crunchedCompression: 0 88 | allowsAlphaSplitting: 0 89 | overridden: 0 90 | androidETC2FallbackOverride: 0 91 | forceMaximumCompressionQuality_BC6H_BC7: 0 92 | - serializedVersion: 3 93 | buildTarget: Server 94 | maxTextureSize: 2048 95 | resizeAlgorithm: 0 96 | textureFormat: -1 97 | textureCompression: 1 98 | compressionQuality: 50 99 | crunchedCompression: 0 100 | allowsAlphaSplitting: 0 101 | overridden: 0 102 | androidETC2FallbackOverride: 0 103 | forceMaximumCompressionQuality_BC6H_BC7: 0 104 | - serializedVersion: 3 105 | buildTarget: Android 106 | maxTextureSize: 2048 107 | resizeAlgorithm: 0 108 | textureFormat: -1 109 | textureCompression: 1 110 | compressionQuality: 50 111 | crunchedCompression: 0 112 | allowsAlphaSplitting: 0 113 | overridden: 0 114 | androidETC2FallbackOverride: 0 115 | forceMaximumCompressionQuality_BC6H_BC7: 0 116 | - serializedVersion: 3 117 | buildTarget: iPhone 118 | maxTextureSize: 2048 119 | resizeAlgorithm: 0 120 | textureFormat: -1 121 | textureCompression: 1 122 | compressionQuality: 50 123 | crunchedCompression: 0 124 | allowsAlphaSplitting: 0 125 | overridden: 0 126 | androidETC2FallbackOverride: 0 127 | forceMaximumCompressionQuality_BC6H_BC7: 0 128 | - serializedVersion: 3 129 | buildTarget: WebGL 130 | maxTextureSize: 2048 131 | resizeAlgorithm: 0 132 | textureFormat: -1 133 | textureCompression: 1 134 | compressionQuality: 50 135 | crunchedCompression: 0 136 | allowsAlphaSplitting: 0 137 | overridden: 0 138 | androidETC2FallbackOverride: 0 139 | forceMaximumCompressionQuality_BC6H_BC7: 0 140 | spriteSheet: 141 | serializedVersion: 2 142 | sprites: [] 143 | outline: [] 144 | physicsShape: [] 145 | bones: [] 146 | spriteID: 5e97eb03825dee720800000000000000 147 | internalID: 0 148 | vertices: [] 149 | indices: 150 | edges: [] 151 | weights: [] 152 | secondaryTextures: [] 153 | nameFileIdTable: {} 154 | spritePackingTag: 155 | pSDRemoveMatte: 0 156 | pSDShowRemoveMatteOption: 0 157 | userData: 158 | assetBundleName: 159 | assetBundleVariant: 160 | -------------------------------------------------------------------------------- /Docs/AutoBinding.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simonoliver/UnityFigmaBridge/dbd12bff29e8bc84e2682bb19495899711651455/Docs/AutoBinding.png -------------------------------------------------------------------------------- /Docs/AutoBinding.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 77805c1094cb5c94ea2946fe059dee5e 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 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 | vTOnly: 0 27 | ignoreMasterTextureLimit: 0 28 | grayScaleToAlpha: 0 29 | generateCubemap: 6 30 | cubemapConvolution: 0 31 | seamlessCubemap: 0 32 | textureFormat: 1 33 | maxTextureSize: 2048 34 | textureSettings: 35 | serializedVersion: 2 36 | filterMode: 1 37 | aniso: 1 38 | mipBias: 0 39 | wrapU: 1 40 | wrapV: 1 41 | wrapW: 1 42 | nPOTScale: 0 43 | lightmap: 0 44 | compressionQuality: 50 45 | spriteMode: 1 46 | spriteExtrude: 1 47 | spriteMeshType: 1 48 | alignment: 0 49 | spritePivot: {x: 0.5, y: 0.5} 50 | spritePixelsToUnits: 100 51 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 52 | spriteGenerateFallbackPhysicsShape: 1 53 | alphaUsage: 1 54 | alphaIsTransparency: 1 55 | spriteTessellationDetail: -1 56 | textureType: 8 57 | textureShape: 1 58 | singleChannelComponent: 0 59 | flipbookRows: 1 60 | flipbookColumns: 1 61 | maxTextureSizeSet: 0 62 | compressionQualitySet: 0 63 | textureFormatSet: 0 64 | ignorePngGamma: 0 65 | applyGammaDecoding: 0 66 | cookieLightType: 0 67 | platformSettings: 68 | - serializedVersion: 3 69 | buildTarget: DefaultTexturePlatform 70 | maxTextureSize: 2048 71 | resizeAlgorithm: 0 72 | textureFormat: -1 73 | textureCompression: 1 74 | compressionQuality: 50 75 | crunchedCompression: 0 76 | allowsAlphaSplitting: 0 77 | overridden: 0 78 | androidETC2FallbackOverride: 0 79 | forceMaximumCompressionQuality_BC6H_BC7: 0 80 | - serializedVersion: 3 81 | buildTarget: Standalone 82 | maxTextureSize: 2048 83 | resizeAlgorithm: 0 84 | textureFormat: -1 85 | textureCompression: 1 86 | compressionQuality: 50 87 | crunchedCompression: 0 88 | allowsAlphaSplitting: 0 89 | overridden: 0 90 | androidETC2FallbackOverride: 0 91 | forceMaximumCompressionQuality_BC6H_BC7: 0 92 | - serializedVersion: 3 93 | buildTarget: Server 94 | maxTextureSize: 2048 95 | resizeAlgorithm: 0 96 | textureFormat: -1 97 | textureCompression: 1 98 | compressionQuality: 50 99 | crunchedCompression: 0 100 | allowsAlphaSplitting: 0 101 | overridden: 0 102 | androidETC2FallbackOverride: 0 103 | forceMaximumCompressionQuality_BC6H_BC7: 0 104 | - serializedVersion: 3 105 | buildTarget: Android 106 | maxTextureSize: 2048 107 | resizeAlgorithm: 0 108 | textureFormat: -1 109 | textureCompression: 1 110 | compressionQuality: 50 111 | crunchedCompression: 0 112 | allowsAlphaSplitting: 0 113 | overridden: 0 114 | androidETC2FallbackOverride: 0 115 | forceMaximumCompressionQuality_BC6H_BC7: 0 116 | - serializedVersion: 3 117 | buildTarget: iPhone 118 | maxTextureSize: 2048 119 | resizeAlgorithm: 0 120 | textureFormat: -1 121 | textureCompression: 1 122 | compressionQuality: 50 123 | crunchedCompression: 0 124 | allowsAlphaSplitting: 0 125 | overridden: 0 126 | androidETC2FallbackOverride: 0 127 | forceMaximumCompressionQuality_BC6H_BC7: 0 128 | - serializedVersion: 3 129 | buildTarget: WebGL 130 | maxTextureSize: 2048 131 | resizeAlgorithm: 0 132 | textureFormat: -1 133 | textureCompression: 1 134 | compressionQuality: 50 135 | crunchedCompression: 0 136 | allowsAlphaSplitting: 0 137 | overridden: 0 138 | androidETC2FallbackOverride: 0 139 | forceMaximumCompressionQuality_BC6H_BC7: 0 140 | spriteSheet: 141 | serializedVersion: 2 142 | sprites: [] 143 | outline: [] 144 | physicsShape: [] 145 | bones: [] 146 | spriteID: 5e97eb03825dee720800000000000000 147 | internalID: 0 148 | vertices: [] 149 | indices: 150 | edges: [] 151 | weights: [] 152 | secondaryTextures: [] 153 | nameFileIdTable: {} 154 | spritePackingTag: 155 | pSDRemoveMatte: 0 156 | pSDShowRemoveMatteOption: 0 157 | userData: 158 | assetBundleName: 159 | assetBundleVariant: 160 | -------------------------------------------------------------------------------- /Docs/ButtonPressBinding.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simonoliver/UnityFigmaBridge/dbd12bff29e8bc84e2682bb19495899711651455/Docs/ButtonPressBinding.png -------------------------------------------------------------------------------- /Docs/ButtonPressBinding.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c243d291cf454a5408947addb652ca9f 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 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 | vTOnly: 0 27 | ignoreMasterTextureLimit: 0 28 | grayScaleToAlpha: 0 29 | generateCubemap: 6 30 | cubemapConvolution: 0 31 | seamlessCubemap: 0 32 | textureFormat: 1 33 | maxTextureSize: 2048 34 | textureSettings: 35 | serializedVersion: 2 36 | filterMode: 1 37 | aniso: 1 38 | mipBias: 0 39 | wrapU: 1 40 | wrapV: 1 41 | wrapW: 1 42 | nPOTScale: 0 43 | lightmap: 0 44 | compressionQuality: 50 45 | spriteMode: 1 46 | spriteExtrude: 1 47 | spriteMeshType: 1 48 | alignment: 0 49 | spritePivot: {x: 0.5, y: 0.5} 50 | spritePixelsToUnits: 100 51 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 52 | spriteGenerateFallbackPhysicsShape: 1 53 | alphaUsage: 1 54 | alphaIsTransparency: 1 55 | spriteTessellationDetail: -1 56 | textureType: 8 57 | textureShape: 1 58 | singleChannelComponent: 0 59 | flipbookRows: 1 60 | flipbookColumns: 1 61 | maxTextureSizeSet: 0 62 | compressionQualitySet: 0 63 | textureFormatSet: 0 64 | ignorePngGamma: 0 65 | applyGammaDecoding: 0 66 | cookieLightType: 0 67 | platformSettings: 68 | - serializedVersion: 3 69 | buildTarget: DefaultTexturePlatform 70 | maxTextureSize: 2048 71 | resizeAlgorithm: 0 72 | textureFormat: -1 73 | textureCompression: 1 74 | compressionQuality: 50 75 | crunchedCompression: 0 76 | allowsAlphaSplitting: 0 77 | overridden: 0 78 | androidETC2FallbackOverride: 0 79 | forceMaximumCompressionQuality_BC6H_BC7: 0 80 | - serializedVersion: 3 81 | buildTarget: Standalone 82 | maxTextureSize: 2048 83 | resizeAlgorithm: 0 84 | textureFormat: -1 85 | textureCompression: 1 86 | compressionQuality: 50 87 | crunchedCompression: 0 88 | allowsAlphaSplitting: 0 89 | overridden: 0 90 | androidETC2FallbackOverride: 0 91 | forceMaximumCompressionQuality_BC6H_BC7: 0 92 | - serializedVersion: 3 93 | buildTarget: Server 94 | maxTextureSize: 2048 95 | resizeAlgorithm: 0 96 | textureFormat: -1 97 | textureCompression: 1 98 | compressionQuality: 50 99 | crunchedCompression: 0 100 | allowsAlphaSplitting: 0 101 | overridden: 0 102 | androidETC2FallbackOverride: 0 103 | forceMaximumCompressionQuality_BC6H_BC7: 0 104 | - serializedVersion: 3 105 | buildTarget: Android 106 | maxTextureSize: 2048 107 | resizeAlgorithm: 0 108 | textureFormat: -1 109 | textureCompression: 1 110 | compressionQuality: 50 111 | crunchedCompression: 0 112 | allowsAlphaSplitting: 0 113 | overridden: 0 114 | androidETC2FallbackOverride: 0 115 | forceMaximumCompressionQuality_BC6H_BC7: 0 116 | - serializedVersion: 3 117 | buildTarget: iPhone 118 | maxTextureSize: 2048 119 | resizeAlgorithm: 0 120 | textureFormat: -1 121 | textureCompression: 1 122 | compressionQuality: 50 123 | crunchedCompression: 0 124 | allowsAlphaSplitting: 0 125 | overridden: 0 126 | androidETC2FallbackOverride: 0 127 | forceMaximumCompressionQuality_BC6H_BC7: 0 128 | - serializedVersion: 3 129 | buildTarget: WebGL 130 | maxTextureSize: 2048 131 | resizeAlgorithm: 0 132 | textureFormat: -1 133 | textureCompression: 1 134 | compressionQuality: 50 135 | crunchedCompression: 0 136 | allowsAlphaSplitting: 0 137 | overridden: 0 138 | androidETC2FallbackOverride: 0 139 | forceMaximumCompressionQuality_BC6H_BC7: 0 140 | spriteSheet: 141 | serializedVersion: 2 142 | sprites: [] 143 | outline: [] 144 | physicsShape: [] 145 | bones: [] 146 | spriteID: 5e97eb03825dee720800000000000000 147 | internalID: 0 148 | vertices: [] 149 | indices: 150 | edges: [] 151 | weights: [] 152 | secondaryTextures: [] 153 | nameFileIdTable: {} 154 | spritePackingTag: 155 | pSDRemoveMatte: 0 156 | pSDShowRemoveMatteOption: 0 157 | userData: 158 | assetBundleName: 159 | assetBundleVariant: 160 | -------------------------------------------------------------------------------- /Docs/FigmaPrototype.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simonoliver/UnityFigmaBridge/dbd12bff29e8bc84e2682bb19495899711651455/Docs/FigmaPrototype.png -------------------------------------------------------------------------------- /Docs/FigmaPrototype.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 469cf20810ad72742989761bb4e0f045 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 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 | vTOnly: 0 27 | ignoreMasterTextureLimit: 0 28 | grayScaleToAlpha: 0 29 | generateCubemap: 6 30 | cubemapConvolution: 0 31 | seamlessCubemap: 0 32 | textureFormat: 1 33 | maxTextureSize: 2048 34 | textureSettings: 35 | serializedVersion: 2 36 | filterMode: 1 37 | aniso: 1 38 | mipBias: 0 39 | wrapU: 1 40 | wrapV: 1 41 | wrapW: 1 42 | nPOTScale: 0 43 | lightmap: 0 44 | compressionQuality: 50 45 | spriteMode: 1 46 | spriteExtrude: 1 47 | spriteMeshType: 1 48 | alignment: 0 49 | spritePivot: {x: 0.5, y: 0.5} 50 | spritePixelsToUnits: 100 51 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 52 | spriteGenerateFallbackPhysicsShape: 1 53 | alphaUsage: 1 54 | alphaIsTransparency: 1 55 | spriteTessellationDetail: -1 56 | textureType: 8 57 | textureShape: 1 58 | singleChannelComponent: 0 59 | flipbookRows: 1 60 | flipbookColumns: 1 61 | maxTextureSizeSet: 0 62 | compressionQualitySet: 0 63 | textureFormatSet: 0 64 | ignorePngGamma: 0 65 | applyGammaDecoding: 0 66 | cookieLightType: 0 67 | platformSettings: 68 | - serializedVersion: 3 69 | buildTarget: DefaultTexturePlatform 70 | maxTextureSize: 2048 71 | resizeAlgorithm: 0 72 | textureFormat: -1 73 | textureCompression: 1 74 | compressionQuality: 50 75 | crunchedCompression: 0 76 | allowsAlphaSplitting: 0 77 | overridden: 0 78 | androidETC2FallbackOverride: 0 79 | forceMaximumCompressionQuality_BC6H_BC7: 0 80 | - serializedVersion: 3 81 | buildTarget: Standalone 82 | maxTextureSize: 2048 83 | resizeAlgorithm: 0 84 | textureFormat: -1 85 | textureCompression: 1 86 | compressionQuality: 50 87 | crunchedCompression: 0 88 | allowsAlphaSplitting: 0 89 | overridden: 0 90 | androidETC2FallbackOverride: 0 91 | forceMaximumCompressionQuality_BC6H_BC7: 0 92 | - serializedVersion: 3 93 | buildTarget: Server 94 | maxTextureSize: 2048 95 | resizeAlgorithm: 0 96 | textureFormat: -1 97 | textureCompression: 1 98 | compressionQuality: 50 99 | crunchedCompression: 0 100 | allowsAlphaSplitting: 0 101 | overridden: 0 102 | androidETC2FallbackOverride: 0 103 | forceMaximumCompressionQuality_BC6H_BC7: 0 104 | - serializedVersion: 3 105 | buildTarget: Android 106 | maxTextureSize: 2048 107 | resizeAlgorithm: 0 108 | textureFormat: -1 109 | textureCompression: 1 110 | compressionQuality: 50 111 | crunchedCompression: 0 112 | allowsAlphaSplitting: 0 113 | overridden: 0 114 | androidETC2FallbackOverride: 0 115 | forceMaximumCompressionQuality_BC6H_BC7: 0 116 | - serializedVersion: 3 117 | buildTarget: iPhone 118 | maxTextureSize: 2048 119 | resizeAlgorithm: 0 120 | textureFormat: -1 121 | textureCompression: 1 122 | compressionQuality: 50 123 | crunchedCompression: 0 124 | allowsAlphaSplitting: 0 125 | overridden: 0 126 | androidETC2FallbackOverride: 0 127 | forceMaximumCompressionQuality_BC6H_BC7: 0 128 | - serializedVersion: 3 129 | buildTarget: WebGL 130 | maxTextureSize: 2048 131 | resizeAlgorithm: 0 132 | textureFormat: -1 133 | textureCompression: 1 134 | compressionQuality: 50 135 | crunchedCompression: 0 136 | allowsAlphaSplitting: 0 137 | overridden: 0 138 | androidETC2FallbackOverride: 0 139 | forceMaximumCompressionQuality_BC6H_BC7: 0 140 | spriteSheet: 141 | serializedVersion: 2 142 | sprites: [] 143 | outline: [] 144 | physicsShape: [] 145 | bones: [] 146 | spriteID: 5e97eb03825dee720800000000000000 147 | internalID: 0 148 | vertices: [] 149 | indices: 150 | edges: [] 151 | weights: [] 152 | secondaryTextures: [] 153 | nameFileIdTable: {} 154 | spritePackingTag: 155 | pSDRemoveMatte: 0 156 | pSDShowRemoveMatteOption: 0 157 | userData: 158 | assetBundleName: 159 | assetBundleVariant: 160 | -------------------------------------------------------------------------------- /Docs/SelectPage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simonoliver/UnityFigmaBridge/dbd12bff29e8bc84e2682bb19495899711651455/Docs/SelectPage.png -------------------------------------------------------------------------------- /Docs/SelectPage.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 46bdfb723f275c241a5ee6e8b7189610 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 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 | vTOnly: 0 27 | ignoreMasterTextureLimit: 0 28 | grayScaleToAlpha: 0 29 | generateCubemap: 6 30 | cubemapConvolution: 0 31 | seamlessCubemap: 0 32 | textureFormat: 1 33 | maxTextureSize: 2048 34 | textureSettings: 35 | serializedVersion: 2 36 | filterMode: 1 37 | aniso: 1 38 | mipBias: 0 39 | wrapU: 1 40 | wrapV: 1 41 | wrapW: 1 42 | nPOTScale: 0 43 | lightmap: 0 44 | compressionQuality: 50 45 | spriteMode: 1 46 | spriteExtrude: 1 47 | spriteMeshType: 1 48 | alignment: 0 49 | spritePivot: {x: 0.5, y: 0.5} 50 | spritePixelsToUnits: 100 51 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 52 | spriteGenerateFallbackPhysicsShape: 1 53 | alphaUsage: 1 54 | alphaIsTransparency: 1 55 | spriteTessellationDetail: -1 56 | textureType: 8 57 | textureShape: 1 58 | singleChannelComponent: 0 59 | flipbookRows: 1 60 | flipbookColumns: 1 61 | maxTextureSizeSet: 0 62 | compressionQualitySet: 0 63 | textureFormatSet: 0 64 | ignorePngGamma: 0 65 | applyGammaDecoding: 0 66 | cookieLightType: 0 67 | platformSettings: 68 | - serializedVersion: 3 69 | buildTarget: DefaultTexturePlatform 70 | maxTextureSize: 2048 71 | resizeAlgorithm: 0 72 | textureFormat: -1 73 | textureCompression: 1 74 | compressionQuality: 50 75 | crunchedCompression: 0 76 | allowsAlphaSplitting: 0 77 | overridden: 0 78 | androidETC2FallbackOverride: 0 79 | forceMaximumCompressionQuality_BC6H_BC7: 0 80 | - serializedVersion: 3 81 | buildTarget: Standalone 82 | maxTextureSize: 2048 83 | resizeAlgorithm: 0 84 | textureFormat: -1 85 | textureCompression: 1 86 | compressionQuality: 50 87 | crunchedCompression: 0 88 | allowsAlphaSplitting: 0 89 | overridden: 0 90 | androidETC2FallbackOverride: 0 91 | forceMaximumCompressionQuality_BC6H_BC7: 0 92 | - serializedVersion: 3 93 | buildTarget: Server 94 | maxTextureSize: 2048 95 | resizeAlgorithm: 0 96 | textureFormat: -1 97 | textureCompression: 1 98 | compressionQuality: 50 99 | crunchedCompression: 0 100 | allowsAlphaSplitting: 0 101 | overridden: 0 102 | androidETC2FallbackOverride: 0 103 | forceMaximumCompressionQuality_BC6H_BC7: 0 104 | - serializedVersion: 3 105 | buildTarget: Android 106 | maxTextureSize: 2048 107 | resizeAlgorithm: 0 108 | textureFormat: -1 109 | textureCompression: 1 110 | compressionQuality: 50 111 | crunchedCompression: 0 112 | allowsAlphaSplitting: 0 113 | overridden: 0 114 | androidETC2FallbackOverride: 0 115 | forceMaximumCompressionQuality_BC6H_BC7: 0 116 | - serializedVersion: 3 117 | buildTarget: iPhone 118 | maxTextureSize: 2048 119 | resizeAlgorithm: 0 120 | textureFormat: -1 121 | textureCompression: 1 122 | compressionQuality: 50 123 | crunchedCompression: 0 124 | allowsAlphaSplitting: 0 125 | overridden: 0 126 | androidETC2FallbackOverride: 0 127 | forceMaximumCompressionQuality_BC6H_BC7: 0 128 | - serializedVersion: 3 129 | buildTarget: Nintendo Switch 130 | maxTextureSize: 2048 131 | resizeAlgorithm: 0 132 | textureFormat: -1 133 | textureCompression: 1 134 | compressionQuality: 50 135 | crunchedCompression: 0 136 | allowsAlphaSplitting: 0 137 | overridden: 0 138 | androidETC2FallbackOverride: 0 139 | forceMaximumCompressionQuality_BC6H_BC7: 0 140 | - serializedVersion: 3 141 | buildTarget: WebGL 142 | maxTextureSize: 2048 143 | resizeAlgorithm: 0 144 | textureFormat: -1 145 | textureCompression: 1 146 | compressionQuality: 50 147 | crunchedCompression: 0 148 | allowsAlphaSplitting: 0 149 | overridden: 0 150 | androidETC2FallbackOverride: 0 151 | forceMaximumCompressionQuality_BC6H_BC7: 0 152 | - serializedVersion: 3 153 | buildTarget: Windows Store Apps 154 | maxTextureSize: 2048 155 | resizeAlgorithm: 0 156 | textureFormat: -1 157 | textureCompression: 1 158 | compressionQuality: 50 159 | crunchedCompression: 0 160 | allowsAlphaSplitting: 0 161 | overridden: 0 162 | androidETC2FallbackOverride: 0 163 | forceMaximumCompressionQuality_BC6H_BC7: 0 164 | spriteSheet: 165 | serializedVersion: 2 166 | sprites: [] 167 | outline: [] 168 | physicsShape: [] 169 | bones: [] 170 | spriteID: 5e97eb03825dee720800000000000000 171 | internalID: 0 172 | vertices: [] 173 | indices: 174 | edges: [] 175 | weights: [] 176 | secondaryTextures: [] 177 | nameFileIdTable: {} 178 | spritePackingTag: 179 | pSDRemoveMatte: 0 180 | pSDShowRemoveMatteOption: 0 181 | userData: 182 | assetBundleName: 183 | assetBundleVariant: 184 | -------------------------------------------------------------------------------- /Docs/UnityFigmaBridgeBanner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simonoliver/UnityFigmaBridge/dbd12bff29e8bc84e2682bb19495899711651455/Docs/UnityFigmaBridgeBanner.png -------------------------------------------------------------------------------- /Docs/UnityFigmaBridgeBanner.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d3838b3e2e16a3648bdd738efeff6bd8 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 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 | vTOnly: 0 27 | ignoreMasterTextureLimit: 0 28 | grayScaleToAlpha: 0 29 | generateCubemap: 6 30 | cubemapConvolution: 0 31 | seamlessCubemap: 0 32 | textureFormat: 1 33 | maxTextureSize: 2048 34 | textureSettings: 35 | serializedVersion: 2 36 | filterMode: 1 37 | aniso: 1 38 | mipBias: 0 39 | wrapU: 1 40 | wrapV: 1 41 | wrapW: 1 42 | nPOTScale: 0 43 | lightmap: 0 44 | compressionQuality: 50 45 | spriteMode: 1 46 | spriteExtrude: 1 47 | spriteMeshType: 1 48 | alignment: 0 49 | spritePivot: {x: 0.5, y: 0.5} 50 | spritePixelsToUnits: 100 51 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 52 | spriteGenerateFallbackPhysicsShape: 1 53 | alphaUsage: 1 54 | alphaIsTransparency: 1 55 | spriteTessellationDetail: -1 56 | textureType: 8 57 | textureShape: 1 58 | singleChannelComponent: 0 59 | flipbookRows: 1 60 | flipbookColumns: 1 61 | maxTextureSizeSet: 0 62 | compressionQualitySet: 0 63 | textureFormatSet: 0 64 | ignorePngGamma: 0 65 | applyGammaDecoding: 0 66 | cookieLightType: 0 67 | platformSettings: 68 | - serializedVersion: 3 69 | buildTarget: DefaultTexturePlatform 70 | maxTextureSize: 2048 71 | resizeAlgorithm: 0 72 | textureFormat: -1 73 | textureCompression: 1 74 | compressionQuality: 50 75 | crunchedCompression: 0 76 | allowsAlphaSplitting: 0 77 | overridden: 0 78 | androidETC2FallbackOverride: 0 79 | forceMaximumCompressionQuality_BC6H_BC7: 0 80 | - serializedVersion: 3 81 | buildTarget: Standalone 82 | maxTextureSize: 2048 83 | resizeAlgorithm: 0 84 | textureFormat: -1 85 | textureCompression: 1 86 | compressionQuality: 50 87 | crunchedCompression: 0 88 | allowsAlphaSplitting: 0 89 | overridden: 0 90 | androidETC2FallbackOverride: 0 91 | forceMaximumCompressionQuality_BC6H_BC7: 0 92 | - serializedVersion: 3 93 | buildTarget: Server 94 | maxTextureSize: 2048 95 | resizeAlgorithm: 0 96 | textureFormat: -1 97 | textureCompression: 1 98 | compressionQuality: 50 99 | crunchedCompression: 0 100 | allowsAlphaSplitting: 0 101 | overridden: 0 102 | androidETC2FallbackOverride: 0 103 | forceMaximumCompressionQuality_BC6H_BC7: 0 104 | - serializedVersion: 3 105 | buildTarget: Android 106 | maxTextureSize: 2048 107 | resizeAlgorithm: 0 108 | textureFormat: -1 109 | textureCompression: 1 110 | compressionQuality: 50 111 | crunchedCompression: 0 112 | allowsAlphaSplitting: 0 113 | overridden: 0 114 | androidETC2FallbackOverride: 0 115 | forceMaximumCompressionQuality_BC6H_BC7: 0 116 | - serializedVersion: 3 117 | buildTarget: iPhone 118 | maxTextureSize: 2048 119 | resizeAlgorithm: 0 120 | textureFormat: -1 121 | textureCompression: 1 122 | compressionQuality: 50 123 | crunchedCompression: 0 124 | allowsAlphaSplitting: 0 125 | overridden: 0 126 | androidETC2FallbackOverride: 0 127 | forceMaximumCompressionQuality_BC6H_BC7: 0 128 | - serializedVersion: 3 129 | buildTarget: WebGL 130 | maxTextureSize: 2048 131 | resizeAlgorithm: 0 132 | textureFormat: -1 133 | textureCompression: 1 134 | compressionQuality: 50 135 | crunchedCompression: 0 136 | allowsAlphaSplitting: 0 137 | overridden: 0 138 | androidETC2FallbackOverride: 0 139 | forceMaximumCompressionQuality_BC6H_BC7: 0 140 | spriteSheet: 141 | serializedVersion: 2 142 | sprites: [] 143 | outline: [] 144 | physicsShape: [] 145 | bones: [] 146 | spriteID: 5e97eb03825dee720800000000000000 147 | internalID: 0 148 | vertices: [] 149 | indices: 150 | edges: [] 151 | weights: [] 152 | secondaryTextures: [] 153 | nameFileIdTable: {} 154 | spritePackingTag: 155 | pSDRemoveMatte: 0 156 | pSDShowRemoveMatteOption: 0 157 | userData: 158 | assetBundleName: 159 | assetBundleVariant: 160 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Simon Oliver 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 | -------------------------------------------------------------------------------- /LICENSE.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: de28dad4e4dd34046ba477f3f473dbc0 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 34de62a4722bb844f8e7db3e77d62fe3 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /UnityFigmaBridge.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ba078c56a2c82934785cb726cb537ec2 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /UnityFigmaBridge/Assets.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: baca153d871220647af24a31958461c5 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /UnityFigmaBridge/Assets/TransitionFadeToBlack.controller: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1107 &-5379317927783227556 4 | AnimatorStateMachine: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 1 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: Base Layer 11 | m_ChildStates: 12 | - serializedVersion: 1 13 | m_State: {fileID: 4393240818782801404} 14 | m_Position: {x: 460, y: 10, z: 0} 15 | - serializedVersion: 1 16 | m_State: {fileID: 8478415071470378186} 17 | m_Position: {x: 340, y: 90, z: 0} 18 | - serializedVersion: 1 19 | m_State: {fileID: 4080833062758361933} 20 | m_Position: {x: 140, y: 270, z: 0} 21 | m_ChildStateMachines: [] 22 | m_AnyStateTransitions: 23 | - {fileID: 5231872260233416048} 24 | - {fileID: -3600459057478334624} 25 | m_EntryTransitions: [] 26 | m_StateMachineTransitions: {} 27 | m_StateMachineBehaviours: [] 28 | m_AnyStatePosition: {x: 50, y: 20, z: 0} 29 | m_EntryPosition: {x: -80, y: 210, z: 0} 30 | m_ExitPosition: {x: 800, y: 120, z: 0} 31 | m_ParentStateMachinePosition: {x: 800, y: 20, z: 0} 32 | m_DefaultState: {fileID: 4080833062758361933} 33 | --- !u!1101 &-3600459057478334624 34 | AnimatorStateTransition: 35 | m_ObjectHideFlags: 1 36 | m_CorrespondingSourceObject: {fileID: 0} 37 | m_PrefabInstance: {fileID: 0} 38 | m_PrefabAsset: {fileID: 0} 39 | m_Name: 40 | m_Conditions: 41 | - m_ConditionMode: 1 42 | m_ConditionEvent: TransitionOut 43 | m_EventTreshold: 0 44 | m_DstStateMachine: {fileID: 0} 45 | m_DstState: {fileID: 4393240818782801404} 46 | m_Solo: 0 47 | m_Mute: 0 48 | m_IsExit: 0 49 | serializedVersion: 3 50 | m_TransitionDuration: 0 51 | m_TransitionOffset: 0 52 | m_ExitTime: 0.75 53 | m_HasExitTime: 0 54 | m_HasFixedDuration: 1 55 | m_InterruptionSource: 0 56 | m_OrderedInterruption: 1 57 | m_CanTransitionToSelf: 1 58 | --- !u!91 &9100000 59 | AnimatorController: 60 | m_ObjectHideFlags: 0 61 | m_CorrespondingSourceObject: {fileID: 0} 62 | m_PrefabInstance: {fileID: 0} 63 | m_PrefabAsset: {fileID: 0} 64 | m_Name: TransitionFadeToBlack 65 | serializedVersion: 5 66 | m_AnimatorParameters: 67 | - m_Name: TransitionOut 68 | m_Type: 9 69 | m_DefaultFloat: 0 70 | m_DefaultInt: 0 71 | m_DefaultBool: 0 72 | m_Controller: {fileID: 0} 73 | - m_Name: TransitionIn 74 | m_Type: 9 75 | m_DefaultFloat: 0 76 | m_DefaultInt: 0 77 | m_DefaultBool: 0 78 | m_Controller: {fileID: 0} 79 | - m_Name: Hidden 80 | m_Type: 9 81 | m_DefaultFloat: 0 82 | m_DefaultInt: 0 83 | m_DefaultBool: 0 84 | m_Controller: {fileID: 0} 85 | m_AnimatorLayers: 86 | - serializedVersion: 5 87 | m_Name: Base Layer 88 | m_StateMachine: {fileID: -5379317927783227556} 89 | m_Mask: {fileID: 0} 90 | m_Motions: [] 91 | m_Behaviours: [] 92 | m_BlendingMode: 0 93 | m_SyncedLayerIndex: -1 94 | m_DefaultWeight: 0 95 | m_IKPass: 0 96 | m_SyncedLayerAffectsTiming: 0 97 | m_Controller: {fileID: 9100000} 98 | --- !u!1102 &4080833062758361933 99 | AnimatorState: 100 | serializedVersion: 6 101 | m_ObjectHideFlags: 1 102 | m_CorrespondingSourceObject: {fileID: 0} 103 | m_PrefabInstance: {fileID: 0} 104 | m_PrefabAsset: {fileID: 0} 105 | m_Name: TransitionFadeToBlackHidden 106 | m_Speed: 1 107 | m_CycleOffset: 0 108 | m_Transitions: [] 109 | m_StateMachineBehaviours: [] 110 | m_Position: {x: 50, y: 50, z: 0} 111 | m_IKOnFeet: 0 112 | m_WriteDefaultValues: 1 113 | m_Mirror: 0 114 | m_SpeedParameterActive: 0 115 | m_MirrorParameterActive: 0 116 | m_CycleOffsetParameterActive: 0 117 | m_TimeParameterActive: 0 118 | m_Motion: {fileID: 7400000, guid: 1d643a3737685a748a53bead1faee7e1, type: 2} 119 | m_Tag: 120 | m_SpeedParameter: 121 | m_MirrorParameter: 122 | m_CycleOffsetParameter: 123 | m_TimeParameter: 124 | --- !u!1102 &4393240818782801404 125 | AnimatorState: 126 | serializedVersion: 6 127 | m_ObjectHideFlags: 1 128 | m_CorrespondingSourceObject: {fileID: 0} 129 | m_PrefabInstance: {fileID: 0} 130 | m_PrefabAsset: {fileID: 0} 131 | m_Name: TransitionOut 132 | m_Speed: 1 133 | m_CycleOffset: 0 134 | m_Transitions: [] 135 | m_StateMachineBehaviours: [] 136 | m_Position: {x: 50, y: 50, z: 0} 137 | m_IKOnFeet: 0 138 | m_WriteDefaultValues: 1 139 | m_Mirror: 0 140 | m_SpeedParameterActive: 0 141 | m_MirrorParameterActive: 0 142 | m_CycleOffsetParameterActive: 0 143 | m_TimeParameterActive: 0 144 | m_Motion: {fileID: 7400000, guid: 17af76cbf2e401c448bc1fddebe42999, type: 2} 145 | m_Tag: 146 | m_SpeedParameter: 147 | m_MirrorParameter: 148 | m_CycleOffsetParameter: 149 | m_TimeParameter: 150 | --- !u!1101 &5231872260233416048 151 | AnimatorStateTransition: 152 | m_ObjectHideFlags: 1 153 | m_CorrespondingSourceObject: {fileID: 0} 154 | m_PrefabInstance: {fileID: 0} 155 | m_PrefabAsset: {fileID: 0} 156 | m_Name: 157 | m_Conditions: 158 | - m_ConditionMode: 1 159 | m_ConditionEvent: TransitionIn 160 | m_EventTreshold: 0 161 | m_DstStateMachine: {fileID: 0} 162 | m_DstState: {fileID: 8478415071470378186} 163 | m_Solo: 0 164 | m_Mute: 0 165 | m_IsExit: 0 166 | serializedVersion: 3 167 | m_TransitionDuration: 0 168 | m_TransitionOffset: 0 169 | m_ExitTime: 0.75 170 | m_HasExitTime: 0 171 | m_HasFixedDuration: 1 172 | m_InterruptionSource: 0 173 | m_OrderedInterruption: 1 174 | m_CanTransitionToSelf: 1 175 | --- !u!1102 &8478415071470378186 176 | AnimatorState: 177 | serializedVersion: 6 178 | m_ObjectHideFlags: 1 179 | m_CorrespondingSourceObject: {fileID: 0} 180 | m_PrefabInstance: {fileID: 0} 181 | m_PrefabAsset: {fileID: 0} 182 | m_Name: TransitionIn 183 | m_Speed: 1 184 | m_CycleOffset: 0 185 | m_Transitions: [] 186 | m_StateMachineBehaviours: [] 187 | m_Position: {x: 50, y: 50, z: 0} 188 | m_IKOnFeet: 0 189 | m_WriteDefaultValues: 1 190 | m_Mirror: 0 191 | m_SpeedParameterActive: 0 192 | m_MirrorParameterActive: 0 193 | m_CycleOffsetParameterActive: 0 194 | m_TimeParameterActive: 0 195 | m_Motion: {fileID: 7400000, guid: c46e22b038090b44297365191ed45f6e, type: 2} 196 | m_Tag: 197 | m_SpeedParameter: 198 | m_MirrorParameter: 199 | m_CycleOffsetParameter: 200 | m_TimeParameter: 201 | -------------------------------------------------------------------------------- /UnityFigmaBridge/Assets/TransitionFadeToBlack.controller.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2e6cbc62b872ba740898c1c46e2a9384 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 9100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /UnityFigmaBridge/Assets/TransitionFadeToBlack.prefab: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1 &6892956003890051085 4 | GameObject: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | serializedVersion: 6 10 | m_Component: 11 | - component: {fileID: 6892956003890051086} 12 | - component: {fileID: 6892956003890051087} 13 | - component: {fileID: 6892956003890051084} 14 | - component: {fileID: 6892956003890051073} 15 | - component: {fileID: 6892956003890051072} 16 | m_Layer: 0 17 | m_Name: TransitionFadeToBlack 18 | m_TagString: Untagged 19 | m_Icon: {fileID: 0} 20 | m_NavMeshLayer: 0 21 | m_StaticEditorFlags: 0 22 | m_IsActive: 1 23 | --- !u!224 &6892956003890051086 24 | RectTransform: 25 | m_ObjectHideFlags: 0 26 | m_CorrespondingSourceObject: {fileID: 0} 27 | m_PrefabInstance: {fileID: 0} 28 | m_PrefabAsset: {fileID: 0} 29 | m_GameObject: {fileID: 6892956003890051085} 30 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 31 | m_LocalPosition: {x: 0, y: 0, z: 0} 32 | m_LocalScale: {x: 1, y: 1, z: 1} 33 | m_ConstrainProportionsScale: 0 34 | m_Children: [] 35 | m_Father: {fileID: 0} 36 | m_RootOrder: 0 37 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 38 | m_AnchorMin: {x: 0, y: 0} 39 | m_AnchorMax: {x: 1, y: 1} 40 | m_AnchoredPosition: {x: 0, y: 0} 41 | m_SizeDelta: {x: 0, y: 0} 42 | m_Pivot: {x: 0.5, y: 0.5} 43 | --- !u!222 &6892956003890051087 44 | CanvasRenderer: 45 | m_ObjectHideFlags: 0 46 | m_CorrespondingSourceObject: {fileID: 0} 47 | m_PrefabInstance: {fileID: 0} 48 | m_PrefabAsset: {fileID: 0} 49 | m_GameObject: {fileID: 6892956003890051085} 50 | m_CullTransparentMesh: 1 51 | --- !u!114 &6892956003890051084 52 | MonoBehaviour: 53 | m_ObjectHideFlags: 0 54 | m_CorrespondingSourceObject: {fileID: 0} 55 | m_PrefabInstance: {fileID: 0} 56 | m_PrefabAsset: {fileID: 0} 57 | m_GameObject: {fileID: 6892956003890051085} 58 | m_Enabled: 0 59 | m_EditorHideFlags: 0 60 | m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 61 | m_Name: 62 | m_EditorClassIdentifier: 63 | m_Material: {fileID: 0} 64 | m_Color: {r: 0, g: 0, b: 0, a: 1} 65 | m_RaycastTarget: 1 66 | m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} 67 | m_Maskable: 1 68 | m_OnCullStateChanged: 69 | m_PersistentCalls: 70 | m_Calls: [] 71 | m_Sprite: {fileID: 0} 72 | m_Type: 0 73 | m_PreserveAspect: 0 74 | m_FillCenter: 1 75 | m_FillMethod: 4 76 | m_FillAmount: 1 77 | m_FillClockwise: 1 78 | m_FillOrigin: 0 79 | m_UseSpriteMesh: 0 80 | m_PixelsPerUnitMultiplier: 1 81 | --- !u!95 &6892956003890051073 82 | Animator: 83 | serializedVersion: 4 84 | m_ObjectHideFlags: 0 85 | m_CorrespondingSourceObject: {fileID: 0} 86 | m_PrefabInstance: {fileID: 0} 87 | m_PrefabAsset: {fileID: 0} 88 | m_GameObject: {fileID: 6892956003890051085} 89 | m_Enabled: 1 90 | m_Avatar: {fileID: 0} 91 | m_Controller: {fileID: 9100000, guid: 2e6cbc62b872ba740898c1c46e2a9384, type: 2} 92 | m_CullingMode: 0 93 | m_UpdateMode: 0 94 | m_ApplyRootMotion: 0 95 | m_LinearVelocityBlending: 0 96 | m_StabilizeFeet: 0 97 | m_WarningMessage: 98 | m_HasTransformHierarchy: 1 99 | m_AllowConstantClipSamplingOptimization: 1 100 | m_KeepAnimatorControllerStateOnDisable: 0 101 | --- !u!114 &6892956003890051072 102 | MonoBehaviour: 103 | m_ObjectHideFlags: 0 104 | m_CorrespondingSourceObject: {fileID: 0} 105 | m_PrefabInstance: {fileID: 0} 106 | m_PrefabAsset: {fileID: 0} 107 | m_GameObject: {fileID: 6892956003890051085} 108 | m_Enabled: 1 109 | m_EditorHideFlags: 0 110 | m_Script: {fileID: 11500000, guid: 52bf4d995684410cb5acc4e8f1e00ba8, type: 3} 111 | m_Name: 112 | m_EditorClassIdentifier: 113 | m_TransitionEffectAnimator: {fileID: 6892956003890051073} 114 | -------------------------------------------------------------------------------- /UnityFigmaBridge/Assets/TransitionFadeToBlack.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d7963c2a080cd9942831d2d3823dfb97 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /UnityFigmaBridge/Assets/TransitionFadeToBlackAnimateIn.anim: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!74 &7400000 4 | AnimationClip: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_Name: TransitionFadeToBlackAnimateIn 10 | serializedVersion: 6 11 | m_Legacy: 0 12 | m_Compressed: 0 13 | m_UseHighQualityCurve: 1 14 | m_RotationCurves: [] 15 | m_CompressedRotationCurves: [] 16 | m_EulerCurves: [] 17 | m_PositionCurves: [] 18 | m_ScaleCurves: [] 19 | m_FloatCurves: 20 | - curve: 21 | serializedVersion: 2 22 | m_Curve: 23 | - serializedVersion: 3 24 | time: 0 25 | value: 1 26 | inSlope: 0 27 | outSlope: 0 28 | tangentMode: 136 29 | weightedMode: 0 30 | inWeight: 0.33333334 31 | outWeight: 0.33333334 32 | - serializedVersion: 3 33 | time: 0.25 34 | value: 0 35 | inSlope: 0 36 | outSlope: 0 37 | tangentMode: 136 38 | weightedMode: 0 39 | inWeight: 0.33333334 40 | outWeight: 0.33333334 41 | m_PreInfinity: 2 42 | m_PostInfinity: 2 43 | m_RotationOrder: 4 44 | attribute: m_Color.a 45 | path: 46 | classID: 114 47 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 48 | - curve: 49 | serializedVersion: 2 50 | m_Curve: 51 | - serializedVersion: 3 52 | time: 0 53 | value: 1 54 | inSlope: Infinity 55 | outSlope: Infinity 56 | tangentMode: 103 57 | weightedMode: 0 58 | inWeight: 0 59 | outWeight: 0 60 | - serializedVersion: 3 61 | time: 0.25 62 | value: 1 63 | inSlope: Infinity 64 | outSlope: Infinity 65 | tangentMode: 103 66 | weightedMode: 0 67 | inWeight: 0 68 | outWeight: 0 69 | m_PreInfinity: 2 70 | m_PostInfinity: 2 71 | m_RotationOrder: 4 72 | attribute: m_Enabled 73 | path: 74 | classID: 114 75 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 76 | m_PPtrCurves: [] 77 | m_SampleRate: 60 78 | m_WrapMode: 0 79 | m_Bounds: 80 | m_Center: {x: 0, y: 0, z: 0} 81 | m_Extent: {x: 0, y: 0, z: 0} 82 | m_ClipBindingConstant: 83 | genericBindings: 84 | - serializedVersion: 2 85 | path: 0 86 | attribute: 304273561 87 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 88 | typeID: 114 89 | customType: 0 90 | isPPtrCurve: 0 91 | - serializedVersion: 2 92 | path: 0 93 | attribute: 3305885265 94 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 95 | typeID: 114 96 | customType: 24 97 | isPPtrCurve: 0 98 | pptrCurveMapping: [] 99 | m_AnimationClipSettings: 100 | serializedVersion: 2 101 | m_AdditiveReferencePoseClip: {fileID: 0} 102 | m_AdditiveReferencePoseTime: 0 103 | m_StartTime: 0 104 | m_StopTime: 0.25 105 | m_OrientationOffsetY: 0 106 | m_Level: 0 107 | m_CycleOffset: 0 108 | m_HasAdditiveReferencePose: 0 109 | m_LoopTime: 0 110 | m_LoopBlend: 0 111 | m_LoopBlendOrientation: 0 112 | m_LoopBlendPositionY: 0 113 | m_LoopBlendPositionXZ: 0 114 | m_KeepOriginalOrientation: 0 115 | m_KeepOriginalPositionY: 1 116 | m_KeepOriginalPositionXZ: 0 117 | m_HeightFromFeet: 0 118 | m_Mirror: 0 119 | m_EditorCurves: 120 | - curve: 121 | serializedVersion: 2 122 | m_Curve: 123 | - serializedVersion: 3 124 | time: 0 125 | value: 1 126 | inSlope: 0 127 | outSlope: 0 128 | tangentMode: 136 129 | weightedMode: 0 130 | inWeight: 0.33333334 131 | outWeight: 0.33333334 132 | - serializedVersion: 3 133 | time: 0.25 134 | value: 0 135 | inSlope: 0 136 | outSlope: 0 137 | tangentMode: 136 138 | weightedMode: 0 139 | inWeight: 0.33333334 140 | outWeight: 0.33333334 141 | m_PreInfinity: 2 142 | m_PostInfinity: 2 143 | m_RotationOrder: 4 144 | attribute: m_Color.a 145 | path: 146 | classID: 114 147 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 148 | - curve: 149 | serializedVersion: 2 150 | m_Curve: 151 | - serializedVersion: 3 152 | time: 0 153 | value: 1 154 | inSlope: Infinity 155 | outSlope: Infinity 156 | tangentMode: 103 157 | weightedMode: 0 158 | inWeight: 0 159 | outWeight: 0 160 | - serializedVersion: 3 161 | time: 0.25 162 | value: 1 163 | inSlope: Infinity 164 | outSlope: Infinity 165 | tangentMode: 103 166 | weightedMode: 0 167 | inWeight: 0 168 | outWeight: 0 169 | m_PreInfinity: 2 170 | m_PostInfinity: 2 171 | m_RotationOrder: 4 172 | attribute: m_Enabled 173 | path: 174 | classID: 114 175 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 176 | m_EulerEditorCurves: [] 177 | m_HasGenericRootTransform: 0 178 | m_HasMotionFloatCurves: 0 179 | m_Events: 180 | - time: 0.25 181 | functionName: TransitionInComplete 182 | data: 183 | objectReferenceParameter: {fileID: 0} 184 | floatParameter: 0 185 | intParameter: 0 186 | messageOptions: 0 187 | -------------------------------------------------------------------------------- /UnityFigmaBridge/Assets/TransitionFadeToBlackAnimateIn.anim.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c46e22b038090b44297365191ed45f6e 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 7400000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /UnityFigmaBridge/Assets/TransitionFadeToBlackAnimateOut.anim: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!74 &7400000 4 | AnimationClip: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_Name: TransitionFadeToBlackAnimateOut 10 | serializedVersion: 6 11 | m_Legacy: 0 12 | m_Compressed: 0 13 | m_UseHighQualityCurve: 1 14 | m_RotationCurves: [] 15 | m_CompressedRotationCurves: [] 16 | m_EulerCurves: [] 17 | m_PositionCurves: [] 18 | m_ScaleCurves: [] 19 | m_FloatCurves: 20 | - curve: 21 | serializedVersion: 2 22 | m_Curve: 23 | - serializedVersion: 3 24 | time: 0 25 | value: 0 26 | inSlope: 0 27 | outSlope: 0 28 | tangentMode: 136 29 | weightedMode: 0 30 | inWeight: 0.33333334 31 | outWeight: 0.33333334 32 | - serializedVersion: 3 33 | time: 0.25 34 | value: 1 35 | inSlope: 0 36 | outSlope: 0 37 | tangentMode: 136 38 | weightedMode: 0 39 | inWeight: 0.33333334 40 | outWeight: 0.33333334 41 | m_PreInfinity: 2 42 | m_PostInfinity: 2 43 | m_RotationOrder: 4 44 | attribute: m_Color.a 45 | path: 46 | classID: 114 47 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 48 | - curve: 49 | serializedVersion: 2 50 | m_Curve: 51 | - serializedVersion: 3 52 | time: 0 53 | value: 1 54 | inSlope: Infinity 55 | outSlope: Infinity 56 | tangentMode: 103 57 | weightedMode: 0 58 | inWeight: 0 59 | outWeight: 0 60 | m_PreInfinity: 2 61 | m_PostInfinity: 2 62 | m_RotationOrder: 4 63 | attribute: m_Enabled 64 | path: 65 | classID: 114 66 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 67 | m_PPtrCurves: [] 68 | m_SampleRate: 60 69 | m_WrapMode: 0 70 | m_Bounds: 71 | m_Center: {x: 0, y: 0, z: 0} 72 | m_Extent: {x: 0, y: 0, z: 0} 73 | m_ClipBindingConstant: 74 | genericBindings: 75 | - serializedVersion: 2 76 | path: 0 77 | attribute: 304273561 78 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 79 | typeID: 114 80 | customType: 0 81 | isPPtrCurve: 0 82 | - serializedVersion: 2 83 | path: 0 84 | attribute: 3305885265 85 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 86 | typeID: 114 87 | customType: 24 88 | isPPtrCurve: 0 89 | pptrCurveMapping: [] 90 | m_AnimationClipSettings: 91 | serializedVersion: 2 92 | m_AdditiveReferencePoseClip: {fileID: 0} 93 | m_AdditiveReferencePoseTime: 0 94 | m_StartTime: 0 95 | m_StopTime: 0.25 96 | m_OrientationOffsetY: 0 97 | m_Level: 0 98 | m_CycleOffset: 0 99 | m_HasAdditiveReferencePose: 0 100 | m_LoopTime: 0 101 | m_LoopBlend: 0 102 | m_LoopBlendOrientation: 0 103 | m_LoopBlendPositionY: 0 104 | m_LoopBlendPositionXZ: 0 105 | m_KeepOriginalOrientation: 0 106 | m_KeepOriginalPositionY: 1 107 | m_KeepOriginalPositionXZ: 0 108 | m_HeightFromFeet: 0 109 | m_Mirror: 0 110 | m_EditorCurves: 111 | - curve: 112 | serializedVersion: 2 113 | m_Curve: 114 | - serializedVersion: 3 115 | time: 0 116 | value: 0 117 | inSlope: 0 118 | outSlope: 0 119 | tangentMode: 136 120 | weightedMode: 0 121 | inWeight: 0.33333334 122 | outWeight: 0.33333334 123 | - serializedVersion: 3 124 | time: 0.25 125 | value: 1 126 | inSlope: 0 127 | outSlope: 0 128 | tangentMode: 136 129 | weightedMode: 0 130 | inWeight: 0.33333334 131 | outWeight: 0.33333334 132 | m_PreInfinity: 2 133 | m_PostInfinity: 2 134 | m_RotationOrder: 4 135 | attribute: m_Color.a 136 | path: 137 | classID: 114 138 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 139 | - curve: 140 | serializedVersion: 2 141 | m_Curve: 142 | - serializedVersion: 3 143 | time: 0 144 | value: 1 145 | inSlope: Infinity 146 | outSlope: Infinity 147 | tangentMode: 103 148 | weightedMode: 0 149 | inWeight: 0 150 | outWeight: 0 151 | m_PreInfinity: 2 152 | m_PostInfinity: 2 153 | m_RotationOrder: 4 154 | attribute: m_Enabled 155 | path: 156 | classID: 114 157 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 158 | m_EulerEditorCurves: [] 159 | m_HasGenericRootTransform: 0 160 | m_HasMotionFloatCurves: 0 161 | m_Events: 162 | - time: 0.25 163 | functionName: TransitionOutComplete 164 | data: 165 | objectReferenceParameter: {fileID: 0} 166 | floatParameter: 0 167 | intParameter: 0 168 | messageOptions: 0 169 | -------------------------------------------------------------------------------- /UnityFigmaBridge/Assets/TransitionFadeToBlackAnimateOut.anim.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 17af76cbf2e401c448bc1fddebe42999 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 7400000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /UnityFigmaBridge/Assets/TransitionFadeToBlackHidden.anim: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!74 &7400000 4 | AnimationClip: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_Name: TransitionFadeToBlackHidden 10 | serializedVersion: 6 11 | m_Legacy: 0 12 | m_Compressed: 0 13 | m_UseHighQualityCurve: 1 14 | m_RotationCurves: [] 15 | m_CompressedRotationCurves: [] 16 | m_EulerCurves: [] 17 | m_PositionCurves: [] 18 | m_ScaleCurves: [] 19 | m_FloatCurves: 20 | - curve: 21 | serializedVersion: 2 22 | m_Curve: 23 | - serializedVersion: 3 24 | time: 0 25 | value: 0 26 | inSlope: 0 27 | outSlope: 0 28 | tangentMode: 136 29 | weightedMode: 0 30 | inWeight: 0.33333334 31 | outWeight: 0.33333334 32 | m_PreInfinity: 2 33 | m_PostInfinity: 2 34 | m_RotationOrder: 4 35 | attribute: m_Color.r 36 | path: 37 | classID: 114 38 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 39 | - curve: 40 | serializedVersion: 2 41 | m_Curve: 42 | - serializedVersion: 3 43 | time: 0 44 | value: 0 45 | inSlope: 0 46 | outSlope: 0 47 | tangentMode: 136 48 | weightedMode: 0 49 | inWeight: 0.33333334 50 | outWeight: 0.33333334 51 | m_PreInfinity: 2 52 | m_PostInfinity: 2 53 | m_RotationOrder: 4 54 | attribute: m_Color.g 55 | path: 56 | classID: 114 57 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 58 | - curve: 59 | serializedVersion: 2 60 | m_Curve: 61 | - serializedVersion: 3 62 | time: 0 63 | value: 0 64 | inSlope: 0 65 | outSlope: 0 66 | tangentMode: 136 67 | weightedMode: 0 68 | inWeight: 0.33333334 69 | outWeight: 0.33333334 70 | m_PreInfinity: 2 71 | m_PostInfinity: 2 72 | m_RotationOrder: 4 73 | attribute: m_Color.b 74 | path: 75 | classID: 114 76 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 77 | - curve: 78 | serializedVersion: 2 79 | m_Curve: 80 | - serializedVersion: 3 81 | time: 0 82 | value: 1 83 | inSlope: 0 84 | outSlope: 0 85 | tangentMode: 136 86 | weightedMode: 0 87 | inWeight: 0.33333334 88 | outWeight: 0.33333334 89 | m_PreInfinity: 2 90 | m_PostInfinity: 2 91 | m_RotationOrder: 4 92 | attribute: m_Color.a 93 | path: 94 | classID: 114 95 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 96 | - curve: 97 | serializedVersion: 2 98 | m_Curve: 99 | - serializedVersion: 3 100 | time: 0 101 | value: 0 102 | inSlope: Infinity 103 | outSlope: Infinity 104 | tangentMode: 103 105 | weightedMode: 0 106 | inWeight: 0 107 | outWeight: 0 108 | m_PreInfinity: 2 109 | m_PostInfinity: 2 110 | m_RotationOrder: 4 111 | attribute: m_Enabled 112 | path: 113 | classID: 114 114 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 115 | m_PPtrCurves: [] 116 | m_SampleRate: 60 117 | m_WrapMode: 0 118 | m_Bounds: 119 | m_Center: {x: 0, y: 0, z: 0} 120 | m_Extent: {x: 0, y: 0, z: 0} 121 | m_ClipBindingConstant: 122 | genericBindings: 123 | - serializedVersion: 2 124 | path: 0 125 | attribute: 3305885265 126 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 127 | typeID: 114 128 | customType: 24 129 | isPPtrCurve: 0 130 | - serializedVersion: 2 131 | path: 0 132 | attribute: 2526845255 133 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 134 | typeID: 114 135 | customType: 0 136 | isPPtrCurve: 0 137 | - serializedVersion: 2 138 | path: 0 139 | attribute: 4215373228 140 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 141 | typeID: 114 142 | customType: 0 143 | isPPtrCurve: 0 144 | - serializedVersion: 2 145 | path: 0 146 | attribute: 2334886179 147 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 148 | typeID: 114 149 | customType: 0 150 | isPPtrCurve: 0 151 | - serializedVersion: 2 152 | path: 0 153 | attribute: 304273561 154 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 155 | typeID: 114 156 | customType: 0 157 | isPPtrCurve: 0 158 | pptrCurveMapping: [] 159 | m_AnimationClipSettings: 160 | serializedVersion: 2 161 | m_AdditiveReferencePoseClip: {fileID: 0} 162 | m_AdditiveReferencePoseTime: 0 163 | m_StartTime: 0 164 | m_StopTime: 0 165 | m_OrientationOffsetY: 0 166 | m_Level: 0 167 | m_CycleOffset: 0 168 | m_HasAdditiveReferencePose: 0 169 | m_LoopTime: 0 170 | m_LoopBlend: 0 171 | m_LoopBlendOrientation: 0 172 | m_LoopBlendPositionY: 0 173 | m_LoopBlendPositionXZ: 0 174 | m_KeepOriginalOrientation: 0 175 | m_KeepOriginalPositionY: 1 176 | m_KeepOriginalPositionXZ: 0 177 | m_HeightFromFeet: 0 178 | m_Mirror: 0 179 | m_EditorCurves: 180 | - curve: 181 | serializedVersion: 2 182 | m_Curve: 183 | - serializedVersion: 3 184 | time: 0 185 | value: 0 186 | inSlope: 0 187 | outSlope: 0 188 | tangentMode: 136 189 | weightedMode: 0 190 | inWeight: 0.33333334 191 | outWeight: 0.33333334 192 | m_PreInfinity: 2 193 | m_PostInfinity: 2 194 | m_RotationOrder: 4 195 | attribute: m_Color.r 196 | path: 197 | classID: 114 198 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 199 | - curve: 200 | serializedVersion: 2 201 | m_Curve: 202 | - serializedVersion: 3 203 | time: 0 204 | value: 0 205 | inSlope: 0 206 | outSlope: 0 207 | tangentMode: 136 208 | weightedMode: 0 209 | inWeight: 0.33333334 210 | outWeight: 0.33333334 211 | m_PreInfinity: 2 212 | m_PostInfinity: 2 213 | m_RotationOrder: 4 214 | attribute: m_Color.g 215 | path: 216 | classID: 114 217 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 218 | - curve: 219 | serializedVersion: 2 220 | m_Curve: 221 | - serializedVersion: 3 222 | time: 0 223 | value: 0 224 | inSlope: 0 225 | outSlope: 0 226 | tangentMode: 136 227 | weightedMode: 0 228 | inWeight: 0.33333334 229 | outWeight: 0.33333334 230 | m_PreInfinity: 2 231 | m_PostInfinity: 2 232 | m_RotationOrder: 4 233 | attribute: m_Color.b 234 | path: 235 | classID: 114 236 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 237 | - curve: 238 | serializedVersion: 2 239 | m_Curve: 240 | - serializedVersion: 3 241 | time: 0 242 | value: 1 243 | inSlope: 0 244 | outSlope: 0 245 | tangentMode: 136 246 | weightedMode: 0 247 | inWeight: 0.33333334 248 | outWeight: 0.33333334 249 | m_PreInfinity: 2 250 | m_PostInfinity: 2 251 | m_RotationOrder: 4 252 | attribute: m_Color.a 253 | path: 254 | classID: 114 255 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 256 | - curve: 257 | serializedVersion: 2 258 | m_Curve: 259 | - serializedVersion: 3 260 | time: 0 261 | value: 0 262 | inSlope: Infinity 263 | outSlope: Infinity 264 | tangentMode: 103 265 | weightedMode: 0 266 | inWeight: 0 267 | outWeight: 0 268 | m_PreInfinity: 2 269 | m_PostInfinity: 2 270 | m_RotationOrder: 4 271 | attribute: m_Enabled 272 | path: 273 | classID: 114 274 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 275 | m_EulerEditorCurves: [] 276 | m_HasGenericRootTransform: 0 277 | m_HasMotionFloatCurves: 0 278 | m_Events: [] 279 | -------------------------------------------------------------------------------- /UnityFigmaBridge/Assets/TransitionFadeToBlackHidden.anim.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1d643a3737685a748a53bead1faee7e1 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 7400000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /UnityFigmaBridge/Assets/google-fonts.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 039fb5d884ee21a4580def42af13594a 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /UnityFigmaBridge/BindFigmaButtonPress.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace UnityFigmaBridge 4 | { 5 | /// 6 | /// Allows a method to be bound to a specific named Figma button 7 | /// 8 | [AttributeUsage(AttributeTargets.Method)] 9 | public class BindFigmaButtonPress : Attribute 10 | { 11 | 12 | public string TargetButtonName; 13 | 14 | public BindFigmaButtonPress(string buttonName) 15 | { 16 | TargetButtonName = buttonName; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /UnityFigmaBridge/BindFigmaButtonPress.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4e46822ff93d452ebfebc6d48ecb474a 3 | timeCreated: 1667494536 -------------------------------------------------------------------------------- /UnityFigmaBridge/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5d895f49a561bdd46ab03a2a3365f78e 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /UnityFigmaBridge/Editor/Components.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: de037911648940ccb54f41e9a6ce2269 3 | timeCreated: 1675088702 -------------------------------------------------------------------------------- /UnityFigmaBridge/Editor/Components/ComponentManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 955fb3906177447e4b6969ee1600ebbb 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityFigmaBridge/Editor/FigmaApi.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6225b33197c94ec1bdd4b95afbb41bb8 3 | timeCreated: 1675087638 -------------------------------------------------------------------------------- /UnityFigmaBridge/Editor/FigmaApi/FigmaApiData.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d0d057b054f174bf4a33060efa805477 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityFigmaBridge/Editor/FigmaApi/FigmaApiUtils.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 31ac86380e3d46eb8df30246ff80a344 3 | timeCreated: 1667483125 -------------------------------------------------------------------------------- /UnityFigmaBridge/Editor/FigmaApi/FigmaDataUtils.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 316a67c72ac984192a756ba2dbc68b28 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityFigmaBridge/Editor/FigmaImportProcessData.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using UnityEngine; 4 | using UnityFigmaBridge.Editor.FigmaApi; 5 | using UnityFigmaBridge.Editor.Fonts; 6 | using UnityFigmaBridge.Editor.Settings; 7 | using UnityFigmaBridge.Runtime.UI; 8 | 9 | namespace UnityFigmaBridge.Editor 10 | { 11 | /// 12 | /// Wrapper for all data regarding current import process 13 | /// 14 | public class FigmaImportProcessData 15 | { 16 | /// 17 | /// The current importer settings 18 | /// 19 | public UnityFigmaBridgeSettings Settings; 20 | /// 21 | /// The source FIGMA file 22 | /// 23 | public FigmaFile SourceFile; 24 | 25 | /// 26 | /// Details of components used and created for this file 27 | /// 28 | public FigmaBridgeComponentData ComponentData; 29 | 30 | /// 31 | /// Mapping of document fonts to TextMeshPro fonts and material variants 32 | /// 33 | public FigmaFontMap FontMap; 34 | 35 | /// 36 | /// Nodes that should be used for server-side rendering substitution 37 | /// 38 | public List ServerRenderNodes = new List(); 39 | 40 | /// 41 | /// this is set when the figma unity UI document is generated 42 | /// 43 | public PrototypeFlowController PrototypeFlowController; 44 | 45 | /// 46 | /// Generated page prefabs 47 | /// 48 | public List PagePrefabs = new(); 49 | 50 | /// 51 | /// Generated screens 52 | /// 53 | public List ScreenPrefabs = new List(); 54 | 55 | /// 56 | /// Count of flowScreen prefabs created with a specific name (to prevent name collision) 57 | /// 58 | public Dictionary ScreenPrefabNameCounter = new(); 59 | 60 | /// 61 | /// Count of page prefab created with a specific name (to prevent name collision) 62 | /// 63 | public Dictionary PagePrefabNameCounter = new(); 64 | 65 | /// 66 | /// List of all prototype flow starting points 67 | /// 68 | public List PrototypeFlowStartPoints = new(); 69 | 70 | /// 71 | /// List of all page nodes to import 72 | /// 73 | public List SelectedPagesForImport = new(); 74 | 75 | /// 76 | /// Allow faster lookup of nodes by ID 77 | /// 78 | public Dictionary NodeLookupDictionary = new(); 79 | } 80 | 81 | /// 82 | /// Contains data of components and matching prefabs (in addition to missing prefab definitions) 83 | /// 84 | public class FigmaBridgeComponentData 85 | { 86 | /// 87 | /// Count of component names 88 | /// 89 | private Dictionary ComponentNameCount = new(); 90 | 91 | /// 92 | /// List of all missing component definitions on the file 93 | /// 94 | public List MissingComponentDefinitionsList=new(); 95 | 96 | /// 97 | /// Mapping of NodeIDs to components 98 | /// 99 | public Dictionary ComponentInstances = new(); 100 | 101 | /// 102 | /// Node definitions for externally referenced components 103 | /// 104 | public FigmaFileNodes ExternalComponentDefinitions; 105 | 106 | /// 107 | /// Get count of prefabs created with a specific component name (to prevent name collision) 108 | /// 109 | /// 110 | /// 111 | public int GetComponentNameCount(string componentName) 112 | { 113 | // Check for existing use of name 114 | return ComponentNameCount.ContainsKey(componentName) 115 | ? ComponentNameCount[componentName] 116 | : 0; 117 | } 118 | 119 | /// 120 | /// Increment count of components of a specific name found 121 | /// 122 | /// 123 | /// 124 | public void IncrementComponentNameCount(string componentName,int amount) 125 | { 126 | ComponentNameCount[componentName] = GetComponentNameCount(componentName) + amount; 127 | } 128 | 129 | /// 130 | /// Register a component prefab 131 | /// 132 | /// 133 | /// 134 | public void RegisterComponentPrefab(string nodeId, GameObject componentPrefab) 135 | { 136 | if (!ComponentInstances.ContainsKey(nodeId)) 137 | ComponentInstances[nodeId] = new ComponentMappingEntry 138 | { 139 | ComponentId = nodeId, 140 | ComponentPrefab = componentPrefab 141 | }; 142 | } 143 | 144 | public List AllComponentPrefabs => (from prefabPair in ComponentInstances where prefabPair.Value.ComponentPrefab != null select prefabPair.Value.ComponentPrefab).ToList(); 145 | 146 | /// 147 | /// Returns the created component prefab for a given component node id 148 | /// 149 | /// 150 | /// 151 | public GameObject GetComponentPrefab(string componentId) 152 | { 153 | return ComponentInstances.ContainsKey(componentId) ? ComponentInstances[componentId].ComponentPrefab : null; 154 | } 155 | } 156 | 157 | 158 | /// 159 | /// Individual entry for component mapping 160 | /// 161 | public class ComponentMappingEntry 162 | { 163 | public string ComponentId; 164 | public GameObject ComponentPrefab; 165 | } 166 | } -------------------------------------------------------------------------------- /UnityFigmaBridge/Editor/FigmaImportProcessData.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b01d95fc51584d80844f4e9cb32dc32c 3 | timeCreated: 1675160946 -------------------------------------------------------------------------------- /UnityFigmaBridge/Editor/Fonts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2d62acceb3950fe4295e887c51de9aea 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /UnityFigmaBridge/Editor/Fonts/FontManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Threading.Tasks; 4 | using TMPro; 5 | using UnityEditor; 6 | using UnityEngine; 7 | using UnityEngine.Rendering; 8 | using UnityFigmaBridge.Editor.FigmaApi; 9 | using UnityFigmaBridge.Editor.Utils; 10 | using Color = UnityEngine.Color; 11 | using MathUtils = UnityFigmaBridge.Editor.Utils.MathUtils; 12 | 13 | namespace UnityFigmaBridge.Editor.Fonts 14 | { 15 | 16 | public class FigmaFontMapEntry 17 | { 18 | public string FontFamily; 19 | public int FontWeight; 20 | public TMP_FontAsset FontAsset; 21 | public List FontmaterialVariations = new List(); 22 | } 23 | 24 | 25 | /// 26 | /// Class to map text effects (outline and shadow) to material presets 27 | /// 28 | public class FontMaterialVariation 29 | { 30 | public bool OutlineEnabled; 31 | public Color OutlineColor; 32 | public float OutlineThickness; 33 | 34 | public bool ShadowEnabled; 35 | public Color ShadowColor; 36 | public Vector2 ShadowDistance; 37 | 38 | public Material MaterialPreset; 39 | 40 | } 41 | 42 | 43 | public class FigmaFontMap 44 | { 45 | public List FontMapEntries = new List(); 46 | 47 | public FigmaFontMapEntry GetFontMapping(string fontFamily, int fontWeight) 48 | { 49 | return FontMapEntries.FirstOrDefault(fontMapEntry => fontMapEntry.FontFamily == fontFamily && fontMapEntry.FontWeight == fontWeight); 50 | } 51 | } 52 | 53 | /// 54 | /// Functionality to manage fonts, retrive and generate font assets 55 | /// 56 | public static class FontManager 57 | { 58 | /// 59 | /// Generates a map of fonts found int the document and font to map to 60 | /// 61 | /// 62 | /// 63 | /// 64 | public static async Task GenerateFontMapForDocument(FigmaFile figmaFile, bool enableGoogleFontsDownload) 65 | { 66 | FigmaFontMap fontMap = new FigmaFontMap(); 67 | var textNodes = new List(); 68 | FigmaDataUtils.FindAllNodesOfType(figmaFile.document,NodeType.TEXT, textNodes, 0); 69 | 70 | var allProjectFontAssets = AssetDatabase.FindAssets($"t:TMP_FontAsset").Select(guid => AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(guid))).ToList(); 71 | 72 | // Cycle through each node, to see if we have a match for each 73 | foreach (var textNode in textNodes) 74 | { 75 | var fontFamily = textNode.style.fontFamily; 76 | var fontWeight = textNode.style.fontWeight; 77 | var fontMapEntry = fontMap.GetFontMapping(fontFamily, fontWeight); 78 | if (fontMapEntry != null) continue; 79 | 80 | var newFontMapEntry = new FigmaFontMapEntry 81 | { 82 | FontFamily = fontFamily, 83 | FontWeight = fontWeight 84 | }; 85 | fontMap.FontMapEntries.Add(newFontMapEntry); 86 | if (GoogleFontLibraryManager.CheckFontExistsLocally(fontFamily, fontWeight)) 87 | { 88 | newFontMapEntry.FontAsset = GoogleFontLibraryManager.GetFontAsset(fontFamily, fontWeight); 89 | } 90 | else if (enableGoogleFontsDownload && GoogleFontLibraryManager.CheckFontAvailableForDownload(fontFamily, fontWeight)) 91 | { 92 | var downloadTask = GoogleFontLibraryManager.ImportFont(fontFamily, fontWeight); 93 | await downloadTask; 94 | if (downloadTask.Result) 95 | { 96 | // Success 97 | newFontMapEntry.FontAsset=GoogleFontLibraryManager.GetFontAsset(fontFamily, fontWeight); 98 | } 99 | } 100 | 101 | if (newFontMapEntry.FontAsset == null) 102 | newFontMapEntry.FontAsset = GetClosestFont(allProjectFontAssets,fontFamily,fontWeight); 103 | 104 | 105 | // TODO - We might want to handle generation of material variations here too 106 | } 107 | 108 | return fontMap; 109 | } 110 | 111 | 112 | 113 | static string StripFontDetailsFromName(TMP_FontAsset fontAsset) 114 | { 115 | // By default fonts are added with a hyphen to denote weight variations, so strip everything from hyphen 116 | var fontName = fontAsset.name.ToLower(); 117 | var hyphenPoint = fontName.IndexOf('-'); 118 | if (hyphenPoint > -1) fontName = fontName.Substring(0, hyphenPoint); 119 | // Remove any extra keywords 120 | var stripWords = new string[] 121 | { 122 | "sdf", 123 | "regular", 124 | "bold", 125 | "italic", 126 | " " 127 | }; 128 | foreach (var stripWord in stripWords) 129 | { 130 | fontName= fontName.Replace(stripWord, ""); 131 | } 132 | return fontName; 133 | } 134 | 135 | private static TMP_FontAsset GetClosestFont(List projectFonts,string fontFamily,int fontWeight) 136 | { 137 | var lowestMatchScore = 10000000; 138 | TMP_FontAsset closestMatch = null; 139 | 140 | // Make lower case and strip spaces 141 | var inputNameLower = fontFamily.ToLower().Replace(" ", "");; 142 | 143 | // Use Levenshtein distance to calculate best match from available strings 144 | foreach (var font in projectFonts) 145 | { 146 | var strippedFontName = StripFontDetailsFromName(font); 147 | 148 | var newScore = MathUtils.LeventshteinStringDistance(inputNameLower, strippedFontName); 149 | //Debug.Log($"Checking font name {strippedFontName} vs {inputNameLower} score {newScore}"); 150 | if (newScore < lowestMatchScore) 151 | { 152 | closestMatch = font; 153 | lowestMatchScore = newScore; 154 | } 155 | } 156 | return closestMatch; 157 | } 158 | 159 | public static Material GetEffectMaterialPreset(FigmaFontMapEntry fontMapEntry, bool shadow, Color shadowColor, 160 | Vector2 shadowDistance, bool outline, 161 | Color outlineColor, float outlineThickness) 162 | { 163 | // Do we have a matching material? 164 | var materialPresets = fontMapEntry.FontmaterialVariations.Count; 165 | 166 | 167 | foreach (var materialPreset in fontMapEntry.FontmaterialVariations) 168 | { 169 | bool isMatch = true; 170 | if (materialPreset.ShadowEnabled != shadow) isMatch = false; 171 | if (shadow && materialPreset.ShadowColor!=shadowColor) isMatch = false; 172 | if (shadow && materialPreset.ShadowDistance!=shadowDistance) isMatch = false; 173 | 174 | if (materialPreset.OutlineEnabled != outline) isMatch = false; 175 | if (outline && materialPreset.OutlineColor != outlineColor) isMatch = false; 176 | if (outline && materialPreset.OutlineThickness != outlineThickness) isMatch = false; 177 | 178 | if (isMatch) return materialPreset.MaterialPreset; 179 | } 180 | // No match, create new preset 181 | var newMaterialPreset = new Material(fontMapEntry.FontAsset.material); 182 | // We use a modified shader that handles distance from edge better 183 | newMaterialPreset.shader = Shader.Find("Figma/TextMeshPro"); 184 | 185 | var materialName = $"{fontMapEntry.FontAsset.name}_variant_{materialPresets}"; 186 | newMaterialPreset.name = materialName; 187 | 188 | newMaterialPreset.SetKeyword(new LocalKeyword(newMaterialPreset.shader,"UNDERLAY_ON"),shadow); 189 | 190 | if (shadow) 191 | { 192 | newMaterialPreset.SetFloat("_UnderlayOffsetX",0); 193 | newMaterialPreset.SetFloat("_UnderlayOffsetY",-0.6f); 194 | newMaterialPreset.SetColor("_UnderlayColor",shadowColor); 195 | } 196 | 197 | newMaterialPreset.SetKeyword(new LocalKeyword(newMaterialPreset.shader,"OUTLINE_ON"),outline); 198 | 199 | if (outline) 200 | { 201 | // For now we'll just use a fixed value as this is proportional to font size not a fixed value 202 | // Note we are using a modified shader to ensure outline is outside 203 | 204 | newMaterialPreset.SetFloat("_OutlineWidth",outlineThickness); 205 | newMaterialPreset.SetColor("_OutlineColor",outlineColor); 206 | } 207 | 208 | AssetDatabase.CreateAsset(newMaterialPreset, $"{FigmaPaths.FigmaFontMaterialPresetsFolder}/{materialName}.mat"); 209 | 210 | fontMapEntry.FontmaterialVariations.Add(new FontMaterialVariation 211 | { 212 | ShadowEnabled=shadow, 213 | ShadowColor = shadowColor, 214 | ShadowDistance = shadowDistance, 215 | OutlineEnabled = outline, 216 | OutlineColor = outlineColor, 217 | OutlineThickness = outlineThickness, 218 | MaterialPreset = newMaterialPreset 219 | }); 220 | return newMaterialPreset; 221 | } 222 | 223 | } 224 | } 225 | -------------------------------------------------------------------------------- /UnityFigmaBridge/Editor/Fonts/FontManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 60c36597ea73c429db25ffabfaee8e58 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityFigmaBridge/Editor/Fonts/GoogleFontLibraryManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Newtonsoft.Json; 7 | using TMPro; 8 | using UnityEditor; 9 | using UnityEngine; 10 | using UnityEngine.Networking; 11 | using UnityFigmaBridge.Editor.Utils; 12 | 13 | namespace UnityFigmaBridge.Editor.Fonts 14 | { 15 | 16 | // Using font list from https://github.com/jonathantneal/google-fonts-complete 17 | 18 | [Serializable] 19 | public class GoogleFontUrlList 20 | { 21 | public string eot; 22 | public string svg; 23 | public string ttf; 24 | public string woff; 25 | public string woff2; 26 | } 27 | 28 | [Serializable] 29 | public class GoogleFontVariant 30 | { 31 | public GoogleFontUrlList url; 32 | } 33 | 34 | [Serializable] 35 | public class GoogleFontVariantList 36 | { 37 | public Dictionary normal; 38 | } 39 | 40 | [Serializable] 41 | public class GoogleFontDefinition 42 | { 43 | public string category; 44 | public string lastModified; 45 | public string[] subsets; 46 | public GoogleFontVariantList variants; 47 | } 48 | 49 | 50 | public static class GoogleFontLibraryManager 51 | { 52 | private static Dictionary s_FontDefinitions; 53 | 54 | public static void LoadFontData() 55 | { 56 | // If already loaded, ignore 57 | if (s_FontDefinitions != null) return; 58 | var fontDataFile = AssetDatabase.LoadAssetAtPath("Packages/com.simonoliver.unityfigma/UnityFigmaBridge/Assets/google-fonts.json", typeof(TextAsset)) as TextAsset; 59 | Debug.Log($"Font data loaded {fontDataFile.text.Length}"); 60 | s_FontDefinitions = JsonConvert.DeserializeObject>(fontDataFile.text); 61 | Debug.Log($"Fonts found {s_FontDefinitions.Count}"); 62 | } 63 | 64 | /// 65 | /// Path to a TTF font downloaded from Google Fonts 66 | /// 67 | /// 68 | /// 69 | /// 70 | public static string PathToTtfFont(string fontName, int fontWeight) 71 | { 72 | return $"{FigmaPaths.FigmaFontsFolder}/{CombinedFontName(fontName,fontWeight)}.ttf"; 73 | } 74 | 75 | /// 76 | /// Path to a Text Mesh Pro font generated from a Google Font 77 | /// 78 | /// 79 | /// 80 | /// 81 | public static string PathToTmpFont(string fontName, int fontWeight) 82 | { 83 | return $"{FigmaPaths.FigmaFontsFolder}/{CombinedFontName(fontName,fontWeight)}_SDF.asset"; 84 | } 85 | 86 | /// 87 | /// Check to see if a matching font exists 88 | /// 89 | /// 90 | /// 91 | /// 92 | public static bool CheckFontExistsLocally(string fontName, int fontWeight) 93 | { 94 | return File.Exists(PathToTmpFont(fontName, fontWeight)); 95 | } 96 | 97 | 98 | public static TMP_FontAsset GetFontAsset(string fontName, int fontWeight) 99 | { 100 | return AssetDatabase.LoadAssetAtPath(PathToTmpFont(fontName, fontWeight)); 101 | } 102 | 103 | public static string CombinedFontName(string fontName, int fontWeight) 104 | { 105 | return $"{fontName}_{fontWeight}"; 106 | } 107 | 108 | public static async Task ImportFont(string fontName, int fontWeight) 109 | { 110 | // Ensure font data loaded 111 | LoadFontData(); 112 | var fontDownloadUrl = GetFontUrl(fontName,fontWeight); 113 | if (string.IsNullOrEmpty(fontDownloadUrl)) 114 | { 115 | Debug.Log("Cant download font as not found"); 116 | return false; 117 | } 118 | 119 | Debug.Log($"Downloading font {fontName} at url {fontDownloadUrl}"); 120 | 121 | 122 | var webRequest = UnityWebRequest.Get(fontDownloadUrl); 123 | await webRequest.SendWebRequest(); 124 | 125 | if (!(webRequest.result is UnityWebRequest.Result.Success)) 126 | { 127 | Debug.LogWarning($"Error downloading font {webRequest.error}"); 128 | return false; 129 | } 130 | 131 | Debug.Log($"Received font file - size {webRequest.downloadHandler.data.Length}"); 132 | 133 | 134 | var fontFilePath = PathToTtfFont(fontName, fontWeight); 135 | File.WriteAllBytes(fontFilePath,webRequest.downloadHandler.data); 136 | 137 | AssetDatabase.ImportAsset(fontFilePath); 138 | AssetDatabase.Refresh(); 139 | 140 | var ttfFontAsset = AssetDatabase.LoadAssetAtPath(fontFilePath); 141 | if (ttfFontAsset == null) 142 | { 143 | Debug.LogError("Problem loading downloaded font"); 144 | return false; 145 | } 146 | 147 | // Generate font 148 | // Some info here 149 | // https://forum.unity.com/threads/generate-font-asset-via-script.1057043/ 150 | // And reference from TMPro_FontAssetCreatorWindow 151 | 152 | var tmpFontAsset=TMP_FontAsset.CreateFontAsset(ttfFontAsset); 153 | var tmpFilePath = PathToTmpFont(fontName, fontWeight); 154 | 155 | AssetDatabase.CreateAsset(tmpFontAsset, tmpFilePath); 156 | 157 | tmpFontAsset.material.name = $"{CombinedFontName(fontName, fontWeight)} Atlas Material"; 158 | tmpFontAsset.atlasTexture.name = $"{CombinedFontName(fontName, fontWeight)} Atlas"; 159 | 160 | AssetDatabase.AddObjectToAsset(tmpFontAsset.material, tmpFontAsset); 161 | AssetDatabase.AddObjectToAsset(tmpFontAsset.atlasTexture, tmpFontAsset); 162 | 163 | EditorUtility.SetDirty(tmpFontAsset); 164 | 165 | AssetDatabase.SaveAssets(); 166 | 167 | // Add basic characters 168 | TextMeshProFontUtils.AddBasicCharacterSetToFont(tmpFontAsset); 169 | 170 | EditorUtility.SetDirty(tmpFontAsset); 171 | AssetDatabase.SaveAssets(); 172 | 173 | return true; 174 | } 175 | 176 | 177 | private static string GetFontUrl(string fontName, int fontWeight) 178 | { 179 | LoadFontData(); 180 | var fontDefinition = GetFontDefinition(fontName); 181 | if (fontDefinition == null) 182 | { 183 | Debug.LogWarning($"No matching font {fontName}"); 184 | return string.Empty; 185 | } 186 | 187 | if (fontDefinition.variants == null) 188 | { 189 | Debug.LogWarning($"No variant data for font {fontName}"); 190 | return string.Empty; 191 | } 192 | if (fontDefinition.variants.normal == null) return string.Empty; 193 | if (!fontDefinition.variants.normal.ContainsKey(fontWeight.ToString())) 194 | { 195 | Debug.LogWarning($"No matching weight {fontWeight} for font {fontName}"); 196 | return string.Empty; 197 | } 198 | var variant = fontDefinition.variants.normal[fontWeight.ToString()]; 199 | return variant.url.ttf; 200 | } 201 | 202 | 203 | 204 | private static GoogleFontDefinition GetFontDefinition(string fontName) 205 | { 206 | LoadFontData(); 207 | // get case insensitive match 208 | return (from fontKeyPair in s_FontDefinitions where string.Equals(fontKeyPair.Key, fontName, StringComparison.CurrentCultureIgnoreCase) select fontKeyPair.Value).FirstOrDefault(); 209 | } 210 | 211 | /// 212 | /// Checks through our table of google fonts to see if we have a match 213 | /// 214 | /// 215 | /// 216 | /// 217 | public static bool CheckFontAvailableForDownload(string fontFamily, int fontWeight) 218 | { 219 | LoadFontData(); 220 | return !string.IsNullOrEmpty(GetFontUrl(fontFamily, fontWeight)); 221 | } 222 | } 223 | } 224 | -------------------------------------------------------------------------------- /UnityFigmaBridge/Editor/Fonts/GoogleFontLibraryManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e991ac18e6fbf0b41ad009321e314fe9 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityFigmaBridge/Editor/Fonts/TextMeshProFontUtils.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using TMPro; 3 | using UnityEngine; 4 | 5 | namespace UnityFigmaBridge.Editor.Fonts 6 | { 7 | // Character set code adapted from TMPRo_FontAssetCreatorWindow 8 | // //https://forum.unity.com/threads/tmp-1-4-1-creating-static-font-assets-via-editor-script.719471/ 9 | 10 | public static class TextMeshProFontUtils 11 | { 12 | public static void AddBasicCharacterSetToFont(TMP_FontAsset tmpFontAsset) 13 | { 14 | var characterSequence = "32 - 126, 160, 8203, 8230, 9633"; 15 | var characterSet = ParseNumberSequence(characterSequence); 16 | tmpFontAsset.TryAddCharacters(characterSet, out var cantAddChars); 17 | } 18 | 19 | /// 20 | /// Method which returns the character corresponding to a decimal value. 21 | /// 22 | /// 23 | /// 24 | static uint[] ParseNumberSequence(string sequence) 25 | { 26 | List unicodeList = new List(); 27 | string[] sequences = sequence.Split(','); 28 | 29 | foreach (string seq in sequences) 30 | { 31 | string[] s1 = seq.Split('-'); 32 | 33 | if (s1.Length == 1) 34 | try 35 | { 36 | unicodeList.Add(uint.Parse(s1[0])); 37 | } 38 | catch 39 | { 40 | Debug.Log("No characters selected or invalid format."); 41 | } 42 | else 43 | { 44 | for (uint j = uint.Parse(s1[0]); j < uint.Parse(s1[1]) + 1; j++) 45 | { 46 | unicodeList.Add(j); 47 | } 48 | } 49 | } 50 | 51 | return unicodeList.ToArray(); 52 | } 53 | 54 | 55 | private static uint[] GetCharacterSet(string charSequence) 56 | { 57 | // Get list of characters that need to be packed and rendered to the atlas texture. 58 | 59 | var char_List = new List(); 60 | 61 | for (int i = 0; i < charSequence.Length; i++) 62 | { 63 | uint unicode = charSequence[i]; 64 | 65 | // Handle surrogate pairs 66 | if (i < charSequence.Length - 1 && char.IsHighSurrogate((char)unicode) && 67 | char.IsLowSurrogate(charSequence[i + 1])) 68 | { 69 | unicode = (uint)char.ConvertToUtf32(charSequence[i], charSequence[i + 1]); 70 | i += 1; 71 | } 72 | 73 | // Check to make sure we don't include duplicates 74 | if (char_List.FindIndex(item => item == unicode) == -1) 75 | char_List.Add(unicode); 76 | } 77 | 78 | return char_List.ToArray(); 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /UnityFigmaBridge/Editor/Fonts/TextMeshProFontUtils.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 934994f2a3444c00a9acbc3d98cbd3b8 3 | timeCreated: 1674731699 -------------------------------------------------------------------------------- /UnityFigmaBridge/Editor/Nodes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b8efe3450b5343089c941c22c999c078 3 | timeCreated: 1675093762 -------------------------------------------------------------------------------- /UnityFigmaBridge/Editor/Nodes/EffectManager.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.UI; 3 | using UnityFigmaBridge.Editor.FigmaApi; 4 | 5 | namespace UnityFigmaBridge.Editor.Nodes 6 | { 7 | /// 8 | /// Applies effects to nodes where required. 9 | /// 10 | public static class EffectManager 11 | { 12 | 13 | 14 | /// 15 | /// Apply all effects to a given node 16 | /// 17 | /// 18 | /// 19 | /// 20 | public static void ApplyAllFigmaEffectsToUnityNode(GameObject nodeGameObject,Node node, 21 | FigmaImportProcessData figmaImportProcessData) 22 | { 23 | foreach (var effect in node.effects) ApplyEffectToUnityNode(nodeGameObject,node,effect,figmaImportProcessData); 24 | 25 | } 26 | 27 | 28 | /// 29 | /// Applies an individual effect gto a unity node 30 | /// 31 | /// 32 | /// 33 | /// 34 | /// 35 | private static void ApplyEffectToUnityNode(GameObject nodeGameObject,Node node,Effect effect, FigmaImportProcessData figmaImportProcessData) 36 | { 37 | switch (effect.type) 38 | { 39 | case Effect.EffectType.DROP_SHADOW: 40 | switch (node.type) 41 | { 42 | case NodeType.TEXT: 43 | // TMPro doesnt support shadows, this will be done via material preset 44 | break; 45 | case NodeType.DOCUMENT: 46 | case NodeType.CANVAS: 47 | case NodeType.FRAME: 48 | case NodeType.GROUP: 49 | case NodeType.VECTOR: 50 | case NodeType.BOOLEAN_OPERATION: 51 | case NodeType.STAR: 52 | case NodeType.LINE: 53 | case NodeType.ELLIPSE: 54 | case NodeType.REGULAR_POLYGON: 55 | case NodeType.RECTANGLE: 56 | case NodeType.SLICE: 57 | case NodeType.COMPONENT: 58 | case NodeType.COMPONENT_SET: 59 | case NodeType.INSTANCE: 60 | case NodeType.STICKY: 61 | case NodeType.SHAPE_WITH_TEXT: 62 | case NodeType.CONNECTOR: 63 | default: 64 | var shadow = nodeGameObject.AddComponent(); 65 | shadow.effectDistance = new Vector2(effect.offset.x, -effect.offset.y); 66 | shadow.effectColor = FigmaDataUtils.ToUnityColor(effect.color); 67 | // TODO - Apply blur radius (will need better shadow implementation) 68 | break; 69 | } 70 | 71 | break; 72 | case Effect.EffectType.INNER_SHADOW: 73 | case Effect.EffectType.LAYER_BLUR: 74 | case Effect.EffectType.BACKGROUND_BLUR: 75 | // Unsupported 76 | break; 77 | } 78 | } 79 | 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /UnityFigmaBridge/Editor/Nodes/EffectManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1b26d45db75cc47e18b1339d8495acbb 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityFigmaBridge/Editor/Nodes/FigmaAssetGenerator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: eeac310f909c40f998ca63fce2186016 3 | timeCreated: 1615991240 -------------------------------------------------------------------------------- /UnityFigmaBridge/Editor/Nodes/FigmaLayoutManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | using UnityEngine.UI; 4 | using UnityFigmaBridge.Editor.FigmaApi; 5 | using UnityFigmaBridge.Editor.Utils; 6 | 7 | namespace UnityFigmaBridge.Editor.Nodes 8 | { 9 | /// 10 | /// Manages layout functionality for Figma nodes 11 | /// 12 | public static class FigmaLayoutManager 13 | { 14 | /// 15 | /// Applies layout properties for a given node to a gameObject, using Vertical/Horizontal layout groups 16 | /// 17 | /// 18 | /// 19 | /// 20 | /// Generated scroll content object (if generated) 21 | public static void ApplyLayoutPropertiesForNode( GameObject nodeGameObject,Node node, 22 | FigmaImportProcessData figmaImportProcessData,out GameObject scrollContentGameObject) 23 | { 24 | 25 | // Depending on whether scrolling is applied, we may want to add layout to this object or to the content 26 | // holder 27 | 28 | var targetLayoutObject = nodeGameObject; 29 | scrollContentGameObject = null; 30 | 31 | // Check scrolling requirements 32 | var implementScrolling = node.type == NodeType.FRAME && node.overflowDirection != Node.OverflowDirection.NONE; 33 | if (implementScrolling) 34 | { 35 | // This Frame implements scrolling, so we need to add in appropriate functionality 36 | 37 | // Add in a rect mask to implement clipping 38 | if (node.clipsContent) UnityUiUtils.GetOrAddComponent(nodeGameObject); 39 | 40 | // Create the content clip and parent to this object 41 | scrollContentGameObject = new GameObject($"{node.name}_ScrollContent", typeof(RectTransform)); 42 | var scrollContentRectTransform = scrollContentGameObject.transform as RectTransform; 43 | scrollContentRectTransform.pivot = new Vector2(0, 1); 44 | scrollContentRectTransform.anchorMin = scrollContentRectTransform.anchorMax =new Vector2(0,1); 45 | scrollContentRectTransform.anchoredPosition=Vector2.zero; 46 | scrollContentRectTransform.SetParent(nodeGameObject.transform, false); 47 | 48 | var scrollRectComponent = UnityUiUtils.GetOrAddComponent(nodeGameObject); 49 | scrollRectComponent.content = scrollContentGameObject.transform as RectTransform; 50 | scrollRectComponent.horizontal = 51 | node.overflowDirection is Node.OverflowDirection.HORIZONTAL_SCROLLING 52 | or Node.OverflowDirection.HORIZONTAL_AND_VERTICAL_SCROLLING; 53 | 54 | scrollRectComponent.vertical = 55 | node.overflowDirection is Node.OverflowDirection.VERTICAL_SCROLLING 56 | or Node.OverflowDirection.HORIZONTAL_AND_VERTICAL_SCROLLING; 57 | 58 | 59 | // If using layout, we need to use content size fitter to ensure proper sizing for child components 60 | if (node.layoutMode != Node.LayoutMode.NONE) 61 | { 62 | var contentSizeFitter = UnityUiUtils.GetOrAddComponent(scrollContentGameObject); 63 | contentSizeFitter.horizontalFit = ContentSizeFitter.FitMode.PreferredSize; 64 | contentSizeFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize; 65 | } 66 | 67 | // Apply layout to this content clip 68 | targetLayoutObject = scrollContentGameObject; 69 | } 70 | 71 | 72 | // Ignore if layout mode is NONE or layout disabled 73 | if (node.layoutMode == Node.LayoutMode.NONE || !figmaImportProcessData.Settings.EnableAutoLayout) return; 74 | 75 | // Remove an existing layout group if it exists 76 | var existingLayoutGroup = targetLayoutObject.GetComponent(); 77 | if (existingLayoutGroup!=null) UnityEngine.Object.DestroyImmediate(existingLayoutGroup); 78 | 79 | HorizontalOrVerticalLayoutGroup layoutGroup = null; 80 | 81 | switch (node.layoutMode) 82 | { 83 | case Node.LayoutMode.VERTICAL: 84 | layoutGroup= UnityUiUtils.GetOrAddComponent(targetLayoutObject); 85 | layoutGroup.childForceExpandWidth= layoutGroup.childForceExpandHeight = false; 86 | // Setup alignment according to Figma layout. Primary is Vertical 87 | switch (node.primaryAxisAlignItems) 88 | { 89 | // Upper Alignment 90 | case Node.PrimaryAxisAlignItems.MIN: 91 | layoutGroup.childAlignment = node.counterAxisAlignItems switch 92 | { 93 | Node.CounterAxisAlignItems.MIN => TextAnchor.UpperLeft, 94 | Node.CounterAxisAlignItems.CENTER => TextAnchor.UpperCenter, 95 | Node.CounterAxisAlignItems.MAX => TextAnchor.UpperRight, 96 | _ => layoutGroup.childAlignment 97 | }; 98 | break; 99 | // Center alignment 100 | case Node.PrimaryAxisAlignItems.CENTER: 101 | layoutGroup.childAlignment = node.counterAxisAlignItems switch 102 | { 103 | Node.CounterAxisAlignItems.MIN => TextAnchor.MiddleLeft, 104 | Node.CounterAxisAlignItems.CENTER => TextAnchor.MiddleCenter, 105 | Node.CounterAxisAlignItems.MAX => TextAnchor.MiddleRight, 106 | _ => layoutGroup.childAlignment 107 | }; 108 | break; 109 | // Lower alignment 110 | case Node.PrimaryAxisAlignItems.MAX: 111 | layoutGroup.childAlignment = node.counterAxisAlignItems switch 112 | { 113 | Node.CounterAxisAlignItems.MIN => TextAnchor.LowerLeft, 114 | Node.CounterAxisAlignItems.CENTER => TextAnchor.LowerCenter, 115 | Node.CounterAxisAlignItems.MAX => TextAnchor.LowerRight, 116 | _ => layoutGroup.childAlignment 117 | }; 118 | break; 119 | default: 120 | throw new ArgumentOutOfRangeException(); 121 | } 122 | 123 | break; 124 | case Node.LayoutMode.HORIZONTAL: 125 | layoutGroup= UnityUiUtils.GetOrAddComponent(targetLayoutObject); 126 | layoutGroup.childForceExpandWidth= layoutGroup.childForceExpandHeight = false; 127 | // Setup alignment according to Figma layout. Primary is Horizontal 128 | layoutGroup.childAlignment = node.primaryAxisAlignItems switch 129 | { 130 | // Left Alignment 131 | Node.PrimaryAxisAlignItems.MIN => node.counterAxisAlignItems switch 132 | { 133 | Node.CounterAxisAlignItems.MIN => TextAnchor.UpperLeft, 134 | Node.CounterAxisAlignItems.CENTER => TextAnchor.MiddleLeft, 135 | Node.CounterAxisAlignItems.MAX => TextAnchor.LowerLeft, 136 | _ => layoutGroup.childAlignment 137 | }, 138 | // Center alignment 139 | Node.PrimaryAxisAlignItems.CENTER => node.counterAxisAlignItems switch 140 | { 141 | Node.CounterAxisAlignItems.MIN => TextAnchor.UpperCenter, 142 | Node.CounterAxisAlignItems.CENTER => TextAnchor.MiddleCenter, 143 | Node.CounterAxisAlignItems.MAX => TextAnchor.LowerCenter, 144 | _ => layoutGroup.childAlignment 145 | }, 146 | // Right alignment 147 | Node.PrimaryAxisAlignItems.MAX => node.counterAxisAlignItems switch 148 | { 149 | Node.CounterAxisAlignItems.MIN => TextAnchor.UpperRight, 150 | Node.CounterAxisAlignItems.CENTER => TextAnchor.MiddleRight, 151 | Node.CounterAxisAlignItems.MAX => TextAnchor.LowerRight, 152 | _ => layoutGroup.childAlignment 153 | }, 154 | _ => throw new ArgumentOutOfRangeException() 155 | }; 156 | break; 157 | } 158 | 159 | layoutGroup.childControlHeight = true; 160 | layoutGroup.childControlWidth = true; 161 | layoutGroup.childForceExpandHeight = false; 162 | layoutGroup.childForceExpandWidth = false; 163 | layoutGroup.childAlignment = TextAnchor.MiddleCenter; 164 | 165 | layoutGroup.padding = new RectOffset(Mathf.RoundToInt(node.paddingLeft), Mathf.RoundToInt(node.paddingRight), 166 | Mathf.RoundToInt(node.paddingTop), Mathf.RoundToInt(node.paddingBottom)); 167 | layoutGroup.spacing = node.itemSpacing; 168 | } 169 | } 170 | } -------------------------------------------------------------------------------- /UnityFigmaBridge/Editor/Nodes/FigmaLayoutManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ed74f063df4c424ab147e0537a4cf324 3 | timeCreated: 1677677962 -------------------------------------------------------------------------------- /UnityFigmaBridge/Editor/Nodes/FigmaNodeManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fee9c7ef29da4974a7bd3fcb1907aa8c 3 | timeCreated: 1674646925 -------------------------------------------------------------------------------- /UnityFigmaBridge/Editor/Nodes/NodeTransformManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b68e897ab11c40b69a11d6a4290d584d 3 | timeCreated: 1675101457 -------------------------------------------------------------------------------- /UnityFigmaBridge/Editor/PrototypeFlow.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f48d86fe544648498fc954d20c1ba4d9 3 | timeCreated: 1675099003 -------------------------------------------------------------------------------- /UnityFigmaBridge/Editor/PrototypeFlow/BehaviourBindingManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using UnityEditor; 6 | using UnityEditor.Events; 7 | using UnityEngine; 8 | using UnityEngine.Events; 9 | using UnityEngine.UI; 10 | using UnityFigmaBridge.Runtime.UI; 11 | 12 | namespace UnityFigmaBridge.Editor.PrototypeFlow 13 | { 14 | public static class BehaviourBindingManager 15 | { 16 | 17 | 18 | private const int MAX_SEARCH_DEPTH_FOR_TRANSFORMS = 3; 19 | 20 | /// 21 | /// Attempts to find a suitable mono behaviour to bind 22 | /// 23 | /// 24 | /// 25 | private static void BindBehaviourToNode(GameObject gameObject, FigmaImportProcessData importProcessData) 26 | { 27 | // Add in any special behaviours driven by name or other rules. If special case, dont add any more behaviours 28 | bool specialCaseNode=AddSpecialBehavioursToNode(gameObject,importProcessData); 29 | if (specialCaseNode) return; 30 | 31 | var bindingNameSpace = importProcessData.Settings.ScreenBindingNamespace; 32 | var className = $"{gameObject.name}"; 33 | 34 | // We'll want to search all assemblies 35 | var matchingType = GetTypeByName(bindingNameSpace,className); 36 | if (matchingType == null) 37 | { 38 | // No matching type found 39 | return; 40 | } 41 | //Debug.Log($"Matching type found {className}"); 42 | 43 | if (!matchingType.IsSubclassOf(typeof(MonoBehaviour))) 44 | { 45 | // Type found but is not a MonoBehaviour, cannot attach"); 46 | return; 47 | } 48 | // Make sure it doesnt already have this component attached (this can happen for nested components) 49 | var attachedBehaviour = gameObject.GetComponent(matchingType); 50 | if (attachedBehaviour==null) attachedBehaviour=gameObject.AddComponent(matchingType); 51 | 52 | // Find all fields for this class, and if inherit from component, look to assign 53 | BindFieldsForComponent(gameObject, attachedBehaviour); 54 | 55 | } 56 | 57 | private static bool AddSpecialBehavioursToNode(GameObject gameObject, FigmaImportProcessData importProcessData) 58 | { 59 | if (gameObject.name.ToUpper() == "SAFEAREA") 60 | { 61 | // Add in a safe area component for correct resizing 62 | if (gameObject.GetComponent() == null) 63 | { 64 | gameObject.AddComponent(); 65 | // Also move pivot to top left, to make offset calc a bit easier 66 | //FigmaDocumentUtils.SetPivot(gameObject.transform as RectTransform, new Vector2(0,1)); 67 | return true; 68 | } 69 | } 70 | 71 | return false; 72 | } 73 | 74 | public static void BindFieldsForComponent(GameObject gameObject, Component component) 75 | { 76 | var componentType = component.GetType(); 77 | 78 | // Then check private fields 79 | FieldInfo[] privateSerializedFields=componentType.GetFields( 80 | BindingFlags.NonPublic | 81 | BindingFlags.Instance); 82 | List allSerializedComponentFields = privateSerializedFields.Where(field => field.GetCustomAttribute(typeof(SerializeField)) != null).ToList(); 83 | 84 | // And add all public fields 85 | allSerializedComponentFields.AddRange(componentType.GetFields()); 86 | 87 | foreach (var field in allSerializedComponentFields) 88 | { 89 | var fieldType = field.FieldType; 90 | // See if there is a child transform with matching name (case insensitive) 91 | var matchingTransform = GetChildTransformByName(gameObject.transform, field.Name, true,MAX_SEARCH_DEPTH_FOR_TRANSFORMS); 92 | if (matchingTransform) 93 | { 94 | if (fieldType == typeof(GameObject)) 95 | { 96 | field.SetValue(component,matchingTransform.gameObject); 97 | } 98 | else if (fieldType.IsSubclassOf(typeof(Component))) 99 | { 100 | // Try and find a matching component 101 | var matchingComponent = matchingTransform.gameObject.GetComponent(fieldType); 102 | if (matchingComponent) 103 | { 104 | // Found matching component - set 105 | field.SetValue(component,matchingComponent); 106 | } 107 | } 108 | } 109 | } 110 | 111 | // Bind methods! 112 | var methods = componentType.GetMethods().Where(m=>m.GetCustomAttributes(typeof(BindFigmaButtonPress), false).Length > 0) 113 | .ToArray(); 114 | 115 | foreach (var method in methods) 116 | { 117 | var buttonPressMethodAttribute = (BindFigmaButtonPress) method.GetCustomAttribute(typeof(BindFigmaButtonPress)); 118 | //Debug.Log($"Attempting to bind method {method.Name} to button {buttonPressMethodAttribute.TargetButtonName}"); 119 | var targetButtonTransform=GetChildTransformByName(gameObject.transform, buttonPressMethodAttribute.TargetButtonName, true,MAX_SEARCH_DEPTH_FOR_TRANSFORMS); 120 | if (targetButtonTransform != null) 121 | { 122 | // Found matching transform, try and get button 123 | var targetButton = targetButtonTransform.GetComponent