基本导入商
假设你有一个要为其创建导入程序的自定义文件。它可能是 .xls 文件或其他什么。在这种情况下,我们将使用 JSON 文件,因为它很容易,但我们将选择一个自定义扩展,以便轻松判断哪些文件是我们的?
我们假设 JSON 文件的格式是
{
"someValue": 123,
"someOtherValue": 456.297,
"someBoolValue": true,
"someStringValue": "this is a string",
}
让我们暂时将其保存为资产之外的某个地方。
接下来只为数据创建一个带有自定义类的 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,你会看到类似的内容
接下来在 Assets
下的某个地方制作一个 Editor
文件夹。我可以在任何级别。在 Editor 文件夹中创建一个 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
,你将看到预制件中的数据立即更新。如果将预制件拖动到场景层次结构中,你将看到它更新以及 Example.test
更改。如果将 Example.test
移动到另一个文件夹,相应的预制件将随之移动。如果更改实例上的字段,则更改 Example.test
文件,你将看到只有实例上未修改的字段才会更新。
改进:在上面的示例中,将 Example.test
拖到 Assets
文件夹后,你会看到 Example.test
和 Example.test.prefab
。很高兴知道让它的工作更像模型导入商的工作我们你只是神奇地看到了 Example.test
并且它是一个 AssetBundle
或者其他类似的东西。如果你知道请如何提供该示例