Tutorials
Editor
folder contains any editor scripts. It allows no mono behavior scripts in it.
AssetPostprocessor
is one of the editor class. One of the properties is assetPath, the path name of the asset being imported.
A series of function is called in the following order during the model import:
OnPreprocessModel
: I can overrideModelImporter
settings in here.- After meshes and materials are imported, GameObjects hierarchy is created from the imported nodes. Use
OnPostProcessMeshHierarchy
to change the hierarchy. Every GameObject that represents an imported node is given a corresponding MeshFilter, MeshRenderer, and MeshCollider component.OnAssignMaterialModel
is invoked before assigning a Material to the MeshRenderer. - After MeshRenderers and “userdata” exists, and before children game objects are generated,
OnPostprocessGameObjectWithUserProperties
is called - if animation generation was not disabled at previous stages, SkinnedMesh and Animations are generated. Avatar is also created and GameObjects hierarchy is optimized if possible. Then
OnPostprocessModel
is called for the root GameObject.
Code example: change texture type to “Sprite” when a new texture is imported to the “Sprites” folder.
using UnityEditor;
using UnityEngine;
public class SpriteProcessor : AssetPostprocessor
{
private void OnPostprocessTexture(Texture2D texture)
{
string lowerCaseAssetPath = assetPath.ToLower();
// check if it's in sprites directory
bool isInSpirtesDirectory = lowerCaseAssetPath.IndexOf("/sprites/") != -1;
if (isInSpirtesDirectory)
{
TextureImporter textureImporter = (TextureImporter) assetImporter;
textureImporter.textureType = TextureImporterType.Sprite;
}
}
}
ScriptableWizard
It’s to create an editor wizard. Editor wizards are typically opened using a menu item.
using UnityEngine;
using System.Collections;
using UnityEditor;
public class SelectAllOfTag : ScriptableWizard
{
public string searchTag = "Your tag here";
[MenuItem ("My Tools/Select All Of Tag...")]
static void SelectAllOfTagWizard()
{
ScriptableWizard.DisplayWizard<SelectAllOfTag> ("Select All Of Tag...", "Make Selection");
}
void OnWizardCreate()
{
GameObject[] gameObjects = GameObject.FindGameObjectsWithTag (searchTag);
Selection.objects = gameObjects;
}
}
ScriptabelWizard has 3 messages: OnWizardCreate
is called when the Create button is clicked. OnWizardOtherButton
is called when the other button is lcicked. OnWizardUpdate
is called when the wizard is opened or user changed something in the wizard.
Source:
- YouTube: Live Training 3rd October 2016 - Creating Basic Editor Tools
- Unity Documentation: AssetPostprocessor
- Unity Documentation: ScriptableWizard
My Application
Q: A batch of texture’s format was set wrong, especially the max size and compression.
A: Apply AssetPostprocessor to change the current setting when reimporting.
public class TextureFormatReimporter : AssetPostprocessor
{
private static string mainPath = "assets/textures/path";
void OnPreprocessTexture()
{
string lowerCasePat = assetPath.ToLower();
if (lowerCasePat.Contains(mainPath))
{
TextureImporter texImporter = (TextureImporter)assetImporter;
if (/*in some condition*/)
{
texImporter.isReadable = false;
}
texImporter.mipmapEnabled = false;
TextureImporterPlatformSettings defaultSetting = texImporter.GetDefaultPlatformTextureSettings();
TextureImporterPlatformSettings standAloneSetting = texImporter.GetPlatformTextureSettings("Standalone");
TextureImporterPlatformSettings iOSSetting = texImporter.GetPlatformTextureSettings("iPhone");
TextureImporterPlatformSettings androidSetting = texImporter.GetPlatformTextureSettings("Android");
if (androidSetting.overridden)
{
defaultSetting.maxTextureSize = androidSetting.maxTextureSize;
}
else if (iOSSetting.overridden)
{
defaultSetting.maxTextureSize = iOSSetting.maxTextureSize;
}
if ( /* in some condition */ )
{
defaultSetting.textureCompression = TextureImporterCompression.Uncompressed;
}
else if (/* in some condition */)
{
defaultSetting.format = TextureImporterFormat.Automatic;
}
texImporter.SetPlatformTextureSettings(defaultSetting);
texImporter.ClearPlatformTextureSettings("Android");
texImporter.ClearPlatformTextureSettings("Standalone");
}
}
}
It’s a Preprocessor, so the importer doesn’t need to save and reimport.
Q: how to find the application’s path?
A:
Path.GetDirectoryName( Application.dataPath )
This will return a root of the full path that is relative to the Unity.
Q: How to find the subdirectories in the EditorWindow?
A:
Directory.GetDirectories(dir);
// return the sub directories in dir
// recursively use the method will return all the possible subdirectories in dir
List<string> subdirs = new List<string>();
FindSubdir(dir)
static void FindSubdirectoryRecursion(string directory)
{
var subdirectories = Directory.GetDirectories(directory);
foreach (var dir in subdirectories )
{
subdirs .Add(dir);
FindSubdirectoryRecursion(dir);
}
}
Q: How to access the Importer Settings in EditorWindow?
A:
TextureImporter textureImporter = AssetImporter.GetAtPath(relativePath) as TextureImporter;
Q: Can the EditorWindow output a log?
A:
StreamWriter writer = new StreamWriter(outputPath, true);
writer.WriteLine(outputline);
writer.Close();