When I was approaching making “Replace Tool for Level Designers” I encounter ScriptableWizard. I didn’t know that such a thing existed in Unity! ?
It got me curious as I was planning to make that tool using regular Custom Editor Window, but all of a sudden, there was space to try something new! Unfortunately, I didn’t use ScriptableWizard as it wasn’t suited for what I wanted.
But I think it’s time to revisit it and learn more about it!
The first thing that stroke me was that ScriptableWizard class existed. I didn’t know about it until fairly recently! ?
However my shock didn’t prevent me from learning about it a little. I found out that it can be pretty useful! Especially for building tools as it has a few things already in place. ?
If you want to see what there is to use, I would recommend checking official documentation on ScriptableWizard.
We will use it to build a simple tool to create some folders in your project!
The idea ?
The idea is simple. Create a tool which will create default folders in your project, so YOU don’t have to do it. We will have a bunch of available folders which the user can pick to create.
Also, we will show an error message when the selected folder is already created.
Sound easy? Let’s do it!
Coding ??
The process of creating custom ScriptableWizard is very similar to process of creating custom editor window.
On the beginning, you have to open the window, and then you can provide content of that window. However, unlike in an editor window, in a wizard, Unity will display our public and serialized variables. With that, we don’t need to write OnGUI() to view them, which saves us a little time.
Let’s write some code finally!
using UnityEditor; using UnityEngine; using System.IO; /// <summary> /// Folder creator wizard. /// </summary> public class FolderCreatorWizard : ScriptableWizard { // Flags for folder creation. // Animations public bool CreateAnimationsFolder; // Materials public bool CreateMaterialsFolder; // Prefabs public bool CreatePrefabsFolder; // Resources public bool CreateResourcesFolder; // Scripts public bool CreateScriptsFolder; /// <summary> /// Creating and displaying wizard. /// </summary> [MenuItem("Tools/Create Default Folders")] public static void CreateWizard() { DisplayWizard<FolderCreatorWizard>("Create Default Folders", "Create"); } }
This is enough code to display our wizard window, so let’s see how it looks!
Looks cool! And we didn’t do much yet! ?
What you can also notice is that you can’t dock the wizard window. But the wizard is meant to do his things and disappear, so it’s not a problem. ?
ScriptableWizard comes with a few methods that we can implement. In our example we need just two of them – OnWizardUpdate() and OnWizardCreate().
The first one runs whenever the window needs to be updated. We can use this method to determine if selected folders already exist and show an error message accordingly.
The second method is called when user click Create button on the bottom of the window. We will use it to create folders that the user picked in the wizard window.
So let’s implement them!
using UnityEditor; using UnityEngine; using System.IO; /// <summary> /// Folder creator wizard. /// </summary> public class FolderCreatorWizard : ScriptableWizard { ... /// <summary> /// Wizard Update. /// Runs when window need to be refreshed. /// </summary> private void OnWizardUpdate() { // Shows message what to do. helpString = "Select folders to create!"; // Building error message if any of the selected folder exists. errorString = ""; if (CreateAnimationsFolder && Directory.Exists(Path.Combine(Application.dataPath, Keys.AnimationsFolder))) { // check is folder exist and maybe set error. errorString += string.Format("Folder \"{0}\" already exists!\n", Keys.AnimationsFolder); } if (CreateMaterialsFolder && Directory.Exists(Path.Combine(Application.dataPath, Keys.MaterialsFolder))) { // check is folder exist and maybe set error. errorString += string.Format("Folder \"{0}\" already exists!\n", Keys.MaterialsFolder); } if (CreatePrefabsFolder && Directory.Exists(Path.Combine(Application.dataPath, Keys.PrefabsFolder))) { // check is folder exist and maybe set error. errorString += string.Format("Folder \"{0}\" already exists!\n", Keys.PrefabsFolder); } if (CreateResourcesFolder && Directory.Exists(Path.Combine(Application.dataPath, Keys.ResourcesFolder))) { // check is folder exist and maybe set error. errorString += string.Format("Folder \"{0}\" already exists!\n", Keys.ResourcesFolder); } if (CreateScriptsFolder && Directory.Exists(Path.Combine(Application.dataPath, Keys.ScriptsFolder))) { // check is folder exist and maybe set error. errorString += string.Format("Folder \"{0}\" already exists!\n", Keys.ScriptsFolder); } // Set flag to enable Create button. isValid = (CreateAnimationsFolder || CreateMaterialsFolder || CreatePrefabsFolder || CreateResourcesFolder || CreateScriptsFolder) && errorString.Length == 0; } /// <summary> /// Method called on Create button click. /// Used here to create selected folder. /// </summary> private void OnWizardCreate() { // Creating paths and new folders. // Animations string path = Path.Combine(Application.dataPath, Keys.AnimationsFolder); if (CreateAnimationsFolder && !Directory.Exists(path)) { Directory.CreateDirectory(path); Debug.LogFormat("Directory created: {0}", path); } // Materials path = Path.Combine(Application.dataPath, Keys.MaterialsFolder); if (CreateMaterialsFolder && !Directory.Exists(path)) { Directory.CreateDirectory(path); Debug.LogFormat("Directory created: {0}", path); } // Prefabs path = Path.Combine(Application.dataPath, Keys.PrefabsFolder); if (CreatePrefabsFolder && !Directory.Exists(path)) { Directory.CreateDirectory(path); Debug.LogFormat("Directory created: {0}", path); } // Resources path = Path.Combine(Application.dataPath, Keys.ResourcesFolder); if (CreateResourcesFolder && !Directory.Exists(path)) { Directory.CreateDirectory(path); Debug.LogFormat("Directory created: {0}", path); } // Scripts path = Path.Combine(Application.dataPath, Keys.ScriptsFolder); if (CreateScriptsFolder && !Directory.Exists(path)) { Directory.CreateDirectory(path); Debug.LogFormat("Directory created: {0}", path); } // Refresh Project view to see newly created folders. AssetDatabase.Refresh(); } }
With this part done, I think we can check our final result!
The result ?
I think it might be useful as a setup tool. ?
And with ScriptableWizard there might be even more things to create!
So what do you think about it? Are you planning to use it? Let me know in the comment section below!
If you want to get notified on future content, sign up for the newsletter!
As always, the whole project is available at my public repository. ?
And I hope to see you next time! ?
Great job, helped a lot 🙂
Never even knew about this! Looks like it could be very powerful and useful!