unity3d
Importeurs en (post) verwerkers
Zoeken…
Syntaxis
- AssetPostprocessor.OnPreprocessTexture ()
Opmerkingen
Gebruik String.Contains()
om alleen activa te verwerken die een gegeven string in hun String.Contains()
hebben.
if (assetPath.Contains("ProcessThisFolder"))
{
// Process asset
}
Textuur nabewerker
Maak het TexturePostProcessor.cs
bestand overal in de map Activa :
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;
}
}
Elke keer dat Unity een textuur importeert, heeft het de volgende parameters:
Als u een postprocessor gebruikt, kunt u de textuurparameters niet wijzigen door de importinstellingen in de editor te manipuleren.
Wanneer u op de knop Toepassen klikt, wordt de textuur opnieuw geïmporteerd en wordt de postprocessorcode opnieuw uitgevoerd.
Een eenvoudige importeur
Stel dat u een aangepast bestand hebt waarvoor u een importeur wilt maken. Het kan een .xls-bestand zijn of wat dan ook. In dit geval gaan we een JSON-bestand gebruiken omdat het eenvoudig is, maar we gaan een aangepaste extensie kiezen om het gemakkelijk te maken om te bepalen welke bestanden van ons zijn?
Laten we aannemen dat het formaat van het JSON-bestand is
{
"someValue": 123,
"someOtherValue": 456.297,
"someBoolValue": true,
"someStringValue": "this is a string",
}
Laten we opslaan die als Example.test
ergens buiten van de activa voor nu.
Maak vervolgens een MonoBehaviour
met een aangepaste klasse alleen voor de gegevens. De aangepaste klasse is uitsluitend bedoeld om het JSON gemakkelijk te deserialiseren. U hoeft GEEN aangepaste klasse te gebruiken, maar dit maakt dit voorbeeld korter. We slaan dit op 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();
}
Als je dat script handmatig aan een GameObject zou toevoegen, zou je zoiets zien
Maak vervolgens een Editor
map ergens onder Assets
. Ik kan op elk niveau zijn. Maak in de map Editor een bestand TestDataAssetPostprocessor.cs
en plaats dit erin.
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);
}
}
}
Als dat is opgeslagen, moet je het Example.test
bestand dat we hierboven hebben gemaakt naar je Unity Assets-map kunnen slepen en neerzetten en zou je het overeenkomstige prefab moeten zien. Als u Example.test
bewerkt, ziet u dat de gegevens in het prefab onmiddellijk worden bijgewerkt. Als u het prefab naar de scènehiërarchie sleept, ziet u het bijwerken en wijzigingen in Example.test
. Example.test
. Als u Example.test
naar een andere map verplaatst, verplaatst het bijbehorende prefab mee. Als u een veld in een exemplaar wijzigt, wijzigt u het bestand Example.test
Alleen de velden die u niet in het exemplaar hebt gewijzigd, worden bijgewerkt.
Verbeteringen: in het bovenstaande voorbeeld, nadat je Example.test
naar je map Assets
hebt gesleept, zie je dat er zowel een Example.test
als een Example.test.prefab
. Het zou geweldig zijn om te weten dat het meer werkt als de AssetBundle
. We zien dat je op magische wijze alleen Example.test
en het is een AssetBundle
of zoiets. Als u weet hoe u dat voorbeeld moet geven