unity3d
Импортеры и (пост) процессоры
Поиск…
Синтаксис
- AssetPostprocessor.OnPreprocessTexture ()
замечания
Используйте String.Contains()
для обработки только активов, которые имеют заданную строку в своих путях активов.
if (assetPath.Contains("ProcessThisFolder"))
{
// Process asset
}
Постпроцессор текстуры
Создайте файл TexturePostProcessor.cs
любом месте папки « Активы »:
using UnityEngine;
using UnityEditor;
public class TexturePostProcessor : AssetPostprocessor
{
void OnPostprocessTexture(Texture2D texture)
{
TextureImporter importer = assetImporter as TextureImporter;
importer.anisoLevel = 1;
importer.filterMode = FilterMode.Bilinear;
importer.mipmapEnabled = true;
importer.npotScale = TextureImporterNPOTScale.ToLarger;
importer.textureType = TextureImporterType.Advanced;
}
}
Теперь, каждый раз, когда Unity импортирует текстуру, он будет иметь следующие параметры:
Если вы используете постпроцессор, вы не можете изменять параметры текстуры, управляя настройками импорта в редакторе.
Когда вы нажмете кнопку « Применить» , текстура будет переименована, а постпроцессорный код снова запустится.
Основной импортер
Предположим, у вас есть собственный файл, для которого вы хотите создать импортер. Это может быть файл .xls или что-то еще. В этом случае мы собираемся использовать файл JSON, потому что это легко, но мы собираемся выбрать пользовательское расширение, чтобы было легко определить, какие файлы являются нашими?
Предположим, что формат JSON-файла
{
"someValue": 123,
"someOtherValue": 456.297,
"someBoolValue": true,
"someStringValue": "this is a string",
}
Давайте сохраним это как Example.test
где-то за пределами активов.
Затем создайте MonoBehaviour
с пользовательским классом только для данных. Пользовательский класс предназначен исключительно для облегчения десериализации JSON. Вы не должны использовать пользовательский класс, но это делает этот пример короче. Мы сохраним это в TestData.cs
using UnityEngine;
using System.Collections;
public class TestData : MonoBehaviour {
[System.Serializable]
public class Data {
public int someValue = 0;
public float someOtherValue = 0.0f;
public bool someBoolValue = false;
public string someStringValue = "";
}
public Data data = new Data();
}
Если вы должны вручную добавить этот скрипт в GameObject, вы увидите что-то вроде
Затем создайте папку Editor
где-нибудь в разделе « Assets
. Я могу быть на любом уровне. Внутри папки Editor TestDataAssetPostprocessor.cs
файл TestDataAssetPostprocessor.cs
и поместите его в него.
using UnityEditor;
using UnityEngine;
using System.Collections;
public class TestDataAssetPostprocessor : AssetPostprocessor
{
const string s_extension = ".test";
// NOTE: Paths start with "Assets/"
static bool IsFileWeCareAbout(string path)
{
return System.IO.Path.GetExtension(path).Equals(
s_extension,
System.StringComparison.Ordinal);
}
static void HandleAddedOrChangedFile(string path)
{
string text = System.IO.File.ReadAllText(path);
// should we check for error if the file can't be parsed?
TestData.Data newData = JsonUtility.FromJson<TestData.Data>(text);
string prefabPath = path + ".prefab";
// Get the existing prefab
GameObject existingPrefab =
AssetDatabase.LoadAssetAtPath(prefabPath, typeof(Object)) as GameObject;
if (!existingPrefab)
{
// If no prefab exists make one
GameObject newGameObject = new GameObject();
newGameObject.AddComponent<TestData>();
PrefabUtility.CreatePrefab(prefabPath,
newGameObject,
ReplacePrefabOptions.Default);
GameObject.DestroyImmediate(newGameObject);
existingPrefab =
AssetDatabase.LoadAssetAtPath(prefabPath, typeof(Object)) as GameObject;
}
TestData testData = existingPrefab.GetComponent<TestData>();
if (testData != null)
{
testData.data = newData;
EditorUtility.SetDirty(existingPrefab);
}
}
static void HandleRemovedFile(string path)
{
// Decide what you want to do here. If the source file is removed
// do you want to delete the prefab? Maybe ask if you'd like to
// remove the prefab?
// NOTE: Because you might get many calls (like you deleted a
// subfolder full of .test files you might want to get all the
// filenames and ask all at once ("delete all these prefabs?").
}
static void OnPostprocessAllAssets (string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
{
foreach (var path in importedAssets)
{
if (IsFileWeCareAbout(path))
{
HandleAddedOrChangedFile(path);
}
}
foreach (var path in deletedAssets)
{
if (IsFileWeCareAbout(path))
{
HandleRemovedFile(path);
}
}
for (var ii = 0; ii < movedAssets.Length; ++ii)
{
string srcStr = movedFromAssetPaths[ii];
string dstStr = movedAssets[ii];
// the source was moved, let's move the corresponding prefab
// NOTE: We don't handle the case if there already being
// a prefab of the same name at the destination
string srcPrefabPath = srcStr + ".prefab";
string dstPrefabPath = dstStr + ".prefab";
AssetDatabase.MoveAsset(srcPrefabPath, dstPrefabPath);
}
}
}
С сохранением вы сможете перетащить файл Example.test
который мы создали выше, в вашу папку Unity Assets, и вы должны увидеть соответствующий сборник. Если вы отредактируете Example.test
вы увидите, что данные в prefab будут немедленно обновлены. Если вы перетащите сборку в иерархию сцен, вы увидите ее обновление, а также изменения Example.test
. Если вы переместите Example.test
в другую папку, соответствующий сборник будет перемещаться вместе с ним. Если вы измените поле в экземпляре, то измените файл Example.test
вы увидите только обновленные поля, которые вы не изменяли.
Усовершенствования. В приведенном выше примере, после того, как вы перетащили Example.test
в свою папку « Assets
», вы увидите, что есть пример Example.test
и Example.test.prefab
. Было бы здорово , чтобы знать , чтобы сделать его работу более как модельные импортеры работают мы вы бы волшебно видеть только Example.test
и что это AssetBundle
или некоторые такие вещи. Если вы знаете, как, пожалуйста, укажите этот пример