unity3d
Importeure und (Post-) Prozessoren
Suche…
Syntax
- AssetPostprocessor.OnPreprocessTexture ()
Bemerkungen
Verwenden Sie String.Contains()
, um nur Assets zu verarbeiten, die eine angegebene Zeichenfolge in ihren Asset-Pfaden haben.
if (assetPath.Contains("ProcessThisFolder"))
{
// Process asset
}
Textur-Postprozessor
Erstellen TexturePostProcessor.cs
Datei TexturePostProcessor.cs
beliebiger Stelle im Ordner 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;
}
}
Jedes Mal, wenn Unity eine Textur importiert, hat es die folgenden Parameter:
Wenn Sie einen Postprozessor verwenden, können Sie die Texturparameter nicht ändern, indem Sie die Importeinstellungen im Editor bearbeiten .
Wenn Sie auf die Schaltfläche " Übernehmen" klicken, wird die Textur erneut importiert und der Postprozessor-Code wird erneut ausgeführt.
Ein einfacher Importeur
Angenommen, Sie haben eine benutzerdefinierte Datei, für die Sie einen Importer erstellen möchten. Es kann eine .xls-Datei sein oder was auch immer. In diesem Fall verwenden wir eine JSON-Datei, da es einfach ist, aber wir werden eine benutzerdefinierte Erweiterung auswählen, um zu erkennen, welche Dateien unsere sind.
Nehmen wir an, das Format der JSON-Datei ist
{
"someValue": 123,
"someOtherValue": 456.297,
"someBoolValue": true,
"someStringValue": "this is a string",
}
Speichern wir das jetzt als Example.test
irgendwo außerhalb von Assets.
Als Nächstes MonoBehaviour
ein MonoBehaviour
mit einer benutzerdefinierten Klasse nur für die Daten. Die benutzerdefinierte Klasse dient ausschließlich zur Erleichterung der Deserialisierung des JSON. Sie müssen KEINE benutzerdefinierten Klasse verwenden, aber dieses Beispiel wird kürzer. Wir speichern dies in 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();
}
Wenn Sie dieses Skript manuell zu einem GameObject hinzufügen, sehen Sie so etwas wie
Als nächstes erstellen Sie einen Editor
Ordner irgendwo unter Assets
. Ich kann auf jeder Ebene sein. TestDataAssetPostprocessor.cs
im Editor-Ordner eine TestDataAssetPostprocessor.cs
Datei und TestDataAssetPostprocessor.cs
diese ein.
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
dem Example.test
sollten Sie die oben erstellte Datei Example.test
in Ihren Unity Assets-Ordner ziehen und ablegen können. Das entsprechende Prefab sollte nun erstellt werden. Wenn Sie Example.test
bearbeiten, werden die Daten im Prefab sofort aktualisiert. Wenn Sie das Prefab in die Szenenhierarchie ziehen, werden sowohl die Aktualisierung als auch die Änderungen in Example.test
. Wenn Sie Example.test
in einen anderen Ordner verschieben, wird das entsprechende Prefab mit verschoben. Wenn Sie ein Feld in einer Instanz ändern und dann die Datei Example.test
ändern, werden nur die Felder aktualisiert, die Sie in der Instanz nicht Example.test
.
Verbesserungen: Nachdem Sie in dem obigen Beispiel Example.test
in Ihren Assets
Ordner gezogen haben, werden Sie sehen, dass es sowohl Example.test
als auch Example.test.prefab
. Es wäre großartig zu wissen, dass es so funktioniert, als würden die Example.test
funktionieren. Wir würden magisch nur Example.test
und es ist ein AssetBundle
oder AssetBundle
. Wenn Sie wissen, geben Sie bitte dieses Beispiel an