unity3d
Importateurs et processeurs (post)
Recherche…
Syntaxe
- AssetPostprocessor.OnPreprocessTexture ()
Remarques
Utilisez String.Contains()
pour traiter uniquement les actifs ayant une chaîne donnée dans leurs chemins d'actifs.
if (assetPath.Contains("ProcessThisFolder"))
{
// Process asset
}
Postprocesseur de texture
Créez le fichier TexturePostProcessor.cs
n'importe où dans le dossier Assets :
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;
}
}
Maintenant, chaque fois que Unity importe une texture, elle aura les paramètres suivants:
Si vous utilisez le postprocesseur, vous ne pouvez pas modifier les paramètres de texture en manipulant les paramètres d' importation dans l'éditeur.
Lorsque vous appuyez sur le bouton Appliquer, la texture est réimportée et le code post-processeur est exécuté à nouveau.
Un importateur de base
Supposons que vous ayez un fichier personnalisé pour lequel vous souhaitez créer un importateur. Ce pourrait être un fichier .xls ou autre. Dans ce cas, nous allons utiliser un fichier JSON car il est facile, mais nous allons choisir une extension personnalisée pour faciliter l'identification des fichiers?
Supposons que le format du fichier JSON est
{
"someValue": 123,
"someOtherValue": 456.297,
"someBoolValue": true,
"someStringValue": "this is a string",
}
Sauvegardons cela comme Example.test
quelque part en dehors des actifs pour le moment.
Ensuite, créez un MonoBehaviour
avec une classe personnalisée uniquement pour les données. La classe personnalisée est uniquement destinée à faciliter la désérialisation du JSON. Vous n'avez PAS besoin d'utiliser une classe personnalisée, mais cet exemple est plus court. Nous allons enregistrer cela dans 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();
}
Si vous deviez ajouter manuellement ce script à un GameObject, vous verriez quelque chose comme
Ensuite, créez un dossier Editor
quelque part sous Assets
. Je peux être à n'importe quel niveau. Dans le dossier Editor, créez un fichier TestDataAssetPostprocessor.cs
et insérez-le.
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);
}
}
}
Avec cela sauvegardé, vous devriez pouvoir faire glisser le fichier Example.test
que nous avons créé ci-dessus dans votre dossier Unity Assets et vous devriez voir le préfabriqué correspondant créé. Si vous modifiez Example.test
vous verrez que les données du préfabriqué sont immédiatement mises à jour. Si vous faites glisser le préfabriqué dans la hiérarchie de la scène, vous le verrez aussi bien que les modifications de Example.test
. Si vous déplacez Example.test
vers un autre dossier, le préfabriqué correspondant se déplacera avec lui. Si vous modifiez un champ sur une instance, modifiez le fichier Example.test
. Seuls les champs que vous n'avez pas modifiés sur l'instance sont mis à jour.
Améliorations: Dans l'exemple ci-dessus, après avoir Example.test
dans votre dossier Assets
, vous verrez à la fois un Example.test
et un Example.test.prefab
. Il serait bon de savoir que cela fonctionne plus comme les importateurs de modèles fonctionnent, nous ne verrons que par magie Example.test
et c'est un AssetBundle
ou quelque chose du genre. Si vous savez comment s'il vous plaît fournir cet exemple