So hear me out… Has this ever happened to you? You’re looking for an icon or an image to use in Unity. You open up a website, search for an image, and instead of saving it, you right-click and Copy image.
So far, so good, right? Now you go back into Unity, and oops, you can’t paste it because, well, it’s not possible. The only thing you CAN do is go back to the website, right-click, and select “Save Image As.”
Now you’re going to see this familiar dialog (attaching a Windows screenshot, but Mac users can relate as well).
There are two options now:
- You try to find the project directory and save the image there directly.
- You save it in an easy, accessible folder and after that, drag and drop the file into the Unity project window.
Both these options have some issues.
#1: You’re never able to find the project folder. You can’t have all your projects in your favorites/quick access, and it’s just a lot of trouble to navigate your way into the Sprites or whatever folder you need to (often again and again because for some reason the OS forgets the last path)
#2: You’re going to end up with a desktop looking like this.
Hey, and what if the file is a webp file? You might need to convert that to a .png before you can add it in Unity. Or what if the filename looks like
icon_452_Clock_final_final1_final.png when it’s saved? There are a lot of unnecessary clicks, keypresses, and frustration.
That’s something I faced for many months until I decided …
There’s got to be a better way!
First, I looked for a ready-made solution. None exist. Okay, no problem — let’s create an editor utility that reads the clipboard. Sounds easy right?!
An editor utility in Unity is a custom tool or script that enhances the Unity Editor’s functionality, streamlining the development workflow. These utilities can automate repetitive tasks, create custom inspectors, or add new features to the editor interface.
All I need to do is use EditorGUIUtility.systemCopyBuffer and get the image data?
Well, unfortunately you CAN’T read the raw clipboard data. Yes, you can get text, but not an image.
After numerous back-and-forth and trying multiple libraries, I gave up. There is no way this can be done just within the Unity editor. We need to be able to read the entire clipboard and perform certain operations that are just not exposed in Unity editor scripting.
So drum roll… 🥁 presenting the “actual” use of multiple tech stacks that I mentioned in the first line.
I turned to my favorite framework for creating desktop apps: ElectronJS.
Now you can read the clipboard using the built-in Electron.Clipboard library. It has built-in functions called readText and readImage that do pretty much what they are supposed to.
Okay, so now I can get the image that I’ve copied in an ElectronJS desktop application. Now I need to transfer this image to my Unity project/editor.
The tricky thing here is inter-app communication. Or in my case, standalone Electron app to Unity editor script communication.
Still with me? Let’s recap the problem and my proposed solution clearly now:
Problem: I want to be able to paste any image that I’ve copied into the Unity project window (preferably in the folder that is currently open). I just want to be able to copy images from anywhere (web browser, Photoshop etc. ) and paste them in Unity without any complication.
Proposed Solution: Electron app and Unity will work in tandem. The Electron app will monitor and manage the clipboard — if there is an image copy event triggered on the OS, the Electron app will process it and create an image file in a common folder.
The Unity editor script will monitor the Ctrl + V keypress (only if inside the project window) — if triggered, the function will copy the image (created by the ElectronJS app) from the common folder and paste it in the current active folder inside the Unity project.
Challenges:
- How to capture Ctrl + V hotkey inside the project window of the Unity Editor.
- How to capture the clipboard onChange event in ElectronJS.
- Image metadata is not saved in the clipboard, so what should the name of the image be?
- Handling all error scenarios: What if text is copied? What if the image is in webp format? etc.
So, it took the whole of Saturday (20th July 2024), but I managed to do it! Yay! 😺
Some workarounds (or “jugars” as we call them in my native language):
- Clipboard change event does not exist. The only way to monitor the clipboard is to have a function running (setInterval) that compares the clipboard data to the last data.
- Ctrl + V inside the project window of Unity can only be done using Reflection. Unity doesn’t expose this function, so we have to use reflection to peek inside the class and get its value.
- We cannot get the name of the image; that’s just not stored in the clipboard. Instead, what we can do is quickly show a dialog and ask the user to enter the name of the image that they are pasting. This is actually better because the developer can use their appropriate naming convention instead of leaving it for later and ending up with a whole bunch of sprites with ridiculous names.
- There is no need to show the Electron app. So I decided to put it into the system tray.
Here is another look at the code in Electron that handles the clipboard.
And here is the C# snippet that handles the Ctrl + V hotkey and pastes the image inside the Unity window.
Results
It works as expected. The Electron app runs in the background like a service — and does it’s job of saving images to a common folder. Unity editor works like a charm as well — capturing the paste hotkey and using file operations to paste the image.
So while wrapping up, I had another AHA moment.
When I completed the image paste functionality and tested it multiple times, including on a live project I was working on, I figured, what if we had the ability to paste different files as well? — and not just images?
For example, if we’re copying some code from ChatGPT — we have to create a C# file, name it, change its location and then paste the code … etc.
Q: What if I could copy the code generated by ChatGPT and simply paste (CTRL + V) it inside Unity, and that would create a .cs class for me?
Q: What if I could copy a JSON file and just paste it to create a .json file in the current project window folder that I have opened?
So, here it is, presenting — Instant Clipboard 1.0.
The features are as follows and the utility (both electron and Unity is available on GitHub: https://github.com/saadnkhawaja/instant-clipboard-unity
- Paste images from any source directly into Unity.
- Paste C# code, and the utility will create a C# class for you automatically.
- Paste .webp files directly as .png in Unity with one hotkey.
- No need to convert .SVG or other complex image files (all images will be converted to .png with alpha channel intact)
- Multiple formats supported: XML, JSON, markup (MD), shaders, etc.
*** Save a lot of time and improve your productivity.
The code is available on GitHub.
How to use:
Step 1: Run the Electron app first, maybe put it in the startup folder (or equivalent on Mac), so that it runs when your PC starts.
Step 2: Make sure the InstantClipboard Electron app is running (check system tray)
Step 3: Copy the InstantClipboard.cs file in whichever Unity project you wish to use this. (inside an Editor folder)
Step 4: Copy and paste away…
Download:
https://github.com/saadnkhawaja/instant-clipboard-unity
Enjoy pasting whatever you want directly inside the Unity editor!
Here’s a video for you to enjoy.
/media/4d5470fba56738f2dafb7504b3d5d5c1
Follow me on Twitter: https://www.x.com/saadskhawaja
My Unity Asset Store Page: https://assetstore.unity.com/publishers/5951