问题一 LoadAssetAtPath 返回空
public class ProcessModel : AssetPostprocessor
{
private void OnPostprocessModel(GameObject input)
{
if (input.name != "Enemy2b") return;
//取得导入模型相关信息
ModelImporter importer = assetImporter as ModelImporter;
//将该模型从工程中读取出来
string path = "Assets/airplane/Enemy2b.FBX";
path = importer.assetPath;
GameObject tar = AssetDatabase.LoadAssetAtPath<GameObject>(path);
Debug.Log(importer.assetPath);
Debug.Log(tar);
}
}
如上所示的代码,这是从一本书《Unity 3D/2D手机游戏开发 从学习到产品》中看到的一段代码。
书中最后写到在工程窗口中选择Enemy2b,然后右键选择Reimport重新导入Enemy2b.FBX,上述代码会运行。
但是经过试验后,发现上述代码 tar 是一个空对象,也就是说 AssetDatabase.LoadAssetAtPath方法返回的是空,也就是说这个path是找不到FBX资源,所以自然返回空对象。
我在Project窗口中,将Enemy2b.FBX删除,没有触发OnPostprocessModel方法,然后Import New Assets后触发了OnPostprocessModel方法,依旧tar是空。
我将上述代码注释掉if后,然后在Enemy.FBX上Reimport,结果tar不为空,那么也就是说,LoadAssetAtPath只能获取已经加载了的FBX资源,Reimport应该是删除再导入的操作咯?
public class ProcessModel : AssetPostprocessor
{
private void OnPostprocessModel(GameObject input)
{
// if (input.name != "Enemy2b") return;
//取得导入模型相关信息
ModelImporter importer = assetImporter as ModelImporter;
//将该模型从工程中读取出来
string path = "Assets/airplane/Enemy2b.FBX";
// path = importer.assetPath;
GameObject tar = AssetDatabase.LoadAssetAtPath<GameObject>(path);
Debug.Log(importer.assetPath);
Debug.Log(tar);
}
}
然后我去unity手册里面查了下,如下网址
https://docs.unity.cn/cn/2020.2/ScriptReference/AssetPostprocessor.OnPostprocessModel.html
我对标红的地方理解就是,这个OnPostprocessModel是用于模型导入后调用的,模型的话也就是FBX文件。
关于创建prefab这段我觉得还是看英文好一点,从英文来看,当模型导入后,所有对游戏对象和网格的引用将失效,因此当fbx模型有mesh信息时,无法使用OnPostprocessModel方法从导入的fbx文件去创建一个预制体。
而如下图这个模型,拥有col,enemy2两个mesh信息,大概是不能创建预制体。
但是这里有个疑问,为啥我在Enemy2b导入完成后,Reimport Enemy.FBX可以获取到Enemy2b.FBX的信息呢,不应该无法获取信息么?
问题二 创建预制体失败
在第二步中,根据资源创建预制体,当返回unity界面,Reimport Enemy.FBX来创建Enemy2b.FBX的预制体时,会发现预制体文件创建了, 但代码中prefab是空对象。
//将这个模型创建为Prefab
//GameObject prefab = PrefabUtility.SaveAsPrefabAsset(tar, "Assets/Prefabs/Enemey2b_0.prefab");
GameObject prefab = PrefabUtility.CreatePrefab("Assets/Prefabs/Enemey2b_0.prefab",tar);
prefab.tag = "Enemy";
当我有了Enemey2b_0.prefab文件时,再Reimport Enemy.FBX时会运行成功,没有任何报错。
也就是说此时prefab不是空对象了。
那么上述操作其实是异步操作?
一段代码两个问题点没搞明白,我也是服了我自己了。
完整代码
using UnityEngine;
using UnityEditor;
public class ProcessModel : AssetPostprocessor
{
private void OnPostprocessModel(GameObject input)
{
//if (input.name != "Enemy2b") return;
//取得导入模型相关信息
ModelImporter importer = assetImporter as ModelImporter;
//将该模型从工程中读取出来
string path = "Assets/airplane/Enemy2b.FBX";
//path = importer.assetPath;
GameObject tar = AssetDatabase.LoadAssetAtPath<GameObject>(path);
//Debug.Log(importer.assetPath);
Debug.Log(tar);
//return;
//将这个模型创建为Prefab
//GameObject prefab = PrefabUtility.SaveAsPrefabAsset(tar, "Assets/Prefabs/Enemey2b_0.prefab");
GameObject prefab = PrefabUtility.CreatePrefab("Assets/Prefabs/Enemey2b_0.prefab",tar);
prefab.tag = "Enemy";
foreach (Transform obj in prefab.GetComponentInChildren<Transform>())
{
if (obj.name == "col")
{
//取消碰撞模型的显示
MeshRenderer r = obj.GetComponent<MeshRenderer>();
r.enabled = false;
//添加Mesh 碰撞体
if (obj.gameObject.GetComponent<MeshCollider>() == null)
{
obj.gameObject.AddComponent<MeshCollider>();
}
obj.tag = "Enemy";
}
}
//设置刚体
Rigidbody rigid = prefab.AddComponent<Rigidbody>();
rigid.useGravity = false;
rigid.isKinematic = true;
//为prefab 添加音乐组件
prefab.AddComponent<AudioSource>();
//获取子弹prefab
GameObject rocket = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Prefabs/EnemyRocket.prefab");
//取得爆炸效果prefab
GameObject fx = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/FX/Explosion.prefab");
//添加敌人脚本
SuperEnemy enemy = prefab.AddComponent<SuperEnemy>();
enemy.m_life = 5;
enemy.m_point = 5;
enemy.m_rocket = rocket.transform;
enemy.m_explosionFx = fx.transform;
}
}
标签:prefab,tar,GameObject,FBX,LoadAssetAtPath,AssetDatabase,path,Enemy2b From: https://www.cnblogs.com/weiyanei/p/17739076.html