WebGL Demo Here - created with a 1-Click Import from this Figma file.
Example Unity Project Here - showing what gets generated by the tool
Easily bring your Figma Documents, Components, Assets and Prototypes to Unity! This package makes it super simple to connect a Figma document to your Unity project and import all of your assets as native Unity UI.
It's great for game jamming, quick prototyping and easily bringing your Figma designs into Unity. Tested on Unity 2021.3.X (other versions untested as yet)
Warning This is a very early release, so there's a lot that is missing, and probably a lot of bugs - feel free to send over any PRs or drop me a message on 🐤Twitter or 🐘Mastodon.
- Supports recreation of core Figma alements as native Unity objects
- Recreate Figma prototype flows to easily build Unity prototyps
- SDF renderer for core Figma shapes (Ellipse, Rectangle, Star)
- Recreates Figma components as prefabs and links accordingly (including nested components)
- Responsive layout and support for device safe areas
- Automatically generates required font assets (including downloading missing fonts from Google Fonts)
- Binds Unity MonoBehaviours and fields to Figma objects
- Server side rendering of vector shapes
- Open the Package Manager window (Window → Package Manager) and and then select the Add Package icon in the top left of the window to add a git package.
- Enter
https://github.com/simonoliver/UnityFigmaBridge.git
- Open Project Settings (Edit → Project Settings) and click "Create" to create a new settings asset
- Paste in the URL of your Figma Document (eg
https://www.figma.com/file/..../...
) - Get a (https://www.figma.com/developers/api#authentication)[Figma Personal Access Token from your user profile page], under Settings → Account → Personal Access Tokens
- If you don't already have TextMeshPro in your project, import TMP Essentials (Use Window → Text Mesh Pro → Import TMP Essential Resources)
By default, the importer will recreate the prototype flow found in the Figma File (as defined in the prototype tab). You can disable this by turning off "Build Prototype Flow" which will just generate Figma assets.
If *Build Prototype Flow" is selected, it will create required assets (Canvas, ProtoTypeController, EventSystem) and instantiate the default screen in the active scene. Hit play to start the prototype flow and buttons will transition to the specified screen as per the Figma document. Currently there is a dew
- Click Figma Bridge → Sync Document
- Enter your Personal Access Token (this will be stored in your Player Prefs for future use)
- It will ask if you want to use the current scene to generate prototype flow - Click yes
Node Type | Unity Mapping |
---|---|
Frames | Any frame placed on the root of a page is considered a "screen" and turned into prefab, stored in the Screens Folder |
Image fills | These are downloaded as PNGs and imported as sprites and stored in the ImageFills folder with the name of Figma ID |
Components | Theses are created as prefabs, and stored in the Components Folder |
Component Instances | The matching component prefab is instantiated, and any modified properties are applied |
Pages | Prefabs of each complete page are stored in the Pages folder |
Vectors | Rendered on the server as a PNG (see Server Rendering nelow) |
With the goal of trying to make it 1-click sync, if the font doesnt exist in your project it will try and download a matching TTF font from Google Fonts (from Jonathan Neal's google-fonts-complete project) and generate a new TextMesh Pro Font to match.
There are fallbacks to matching fonts if this can't be done
- Do you already have a matching downloaded Google Font in your project?
- If not, is it available to download on Google Fonts (and do you have this enabled)?
- If not, try and find the best match in your project (tries to find matching fonts by name, then best weight match)
To apply shadow and stroke settings, the importer will generate material presets as required.
As a result of the way that TextMeshPro handles outlines, the package will apply a custom shader (Fima/TextMeshPro) which uses "outside" positioning for strokes (the default in Figma), rather than "center" which TMPro usually uses (in future we'll support all three positions)
- If an object is marked for export, then it will render it as an image, download it as a PNG and place it in the path matching the object name. This can include file paths - for example you could name a node "Textures/Icon/GameIcon" and it will write the PNG file to "Assets/Textures/Icon/GameIcon.png"
When the document is loaded, it will look for nodes that should be rendered on the server. Rendering is done at a scale set in the settings file (Server Render Image Scale, defaults to 3). Currently these are when any of the following are true:
- An object is a vector shape
- Object is a frame only containing vector shape children nodes
- An object's name contains "render"
If you are seeing a lot of server rendering, check your Figma doc to see how you might be able to optimise (for example making sure all vectors are in a component so only rendered once)
Screens will behave according to constraints setup in the constraints panel, with the exception of "Scale" constraint. You can use the "SafeArea" component to automatically adjust the safe area for devices that use them (eg iPhone), as mentioned in Binding Behaviours
As syncing with Figma replaces existing components and screens, the package makes it easy to automatically add behaviours at sync time, to prevent you having to manually add them each time you sync.
Monobehaviours can be automatically bound to components and screens, and methods bound to button clicks. The importer uses reflection to do the following:
- If a MonoBehaviour exists that matches the name (case insensitive) of the object, it will be attached. Eg if I have a frame called "PlayScreen" and a MonoBehaviour called "PlayScreen", then that MonoBehaviour will be added automatically at sync time.
- If the attached MonoBehaviour has any serializable fields (public of using SerializeField attribute), they importer will try and find matching object names within a depth of 2 (currently hardcoded) and look for a matching component. For example, I could add ```public TextMeshPro_UGUI Title`'' and if there is a text object called Title then it will be assigned to that field.
- If you add the
[[BindFigmaButtonPress("PlayButton")]]
attribute to a method, then it will add an onClick listener to a button with that name (searching within a depth of 2)
Some special case components are automatically added:
- If an object's name contains "Button" or has an activate prototype link then it will add a Button component
- If an object's name is "SafeArea" then it will add a safe area component (useful for phones and other devices with non rectangular screens)
If a Button is added, it will look for a child node called "selected". If this is found, it will use this for rollover state.
The FigmaScreenController can have a TransitionEffect which implements transitions in and out animations. By default a template fade to black effect is created but can be replaced and assigned.
These should be imported automatically when the package is added
- TextMeshPro 2.0.1
- JSON.Net 2.01
If you need to change your personal access token, use Figma Bridge → Set Personal Access Token
- Uses Iniqo Quilez' 2D SDF Functions, krzy-s UnityWebRequestAwaiter and Jonathan Neal's google-fonts-complete list. Big thanks for making those available online!
- User defined locations for saving assets
- Image tweaks (Exposure, Contrast)
- Blur on shadows
- Ellipse sweep angles and fill ratio
- Most effects (Inner shadow, Layer Blur, Background Blue)
- Multiple fills on a single object
- Stroke styles other than flat colour
- Stroke positions for shapes (outside/center)
- Stroke positions for text (inside/center)
- Dynamic creation of device fonts
- Autolayout modes
- Fit/Fill Image Modes
- Video Fills
- Star shapes only support five points and non-default radius (missing data from API)
- Star shape only renders at uniform scale
- Polygon Shapes
- Boolean operations
- Line/Arrow
- Consistent UUIDs
- Support for "Scale" constraint
Contributions are very welcome! There's a lot that is missing, and probably a lot of bugs - feel free to send over any PRs or drop me a message on 🐤Twitter or 🐘Mastodon.