c# - 无法为子游戏对象创建碰撞网格
问题描述
我正在创建 fbx 处理脚本来更改某些网格参数,创建预制件并自动添加碰撞网格。现在我被困在尝试将碰撞网格组件添加到我的游戏对象的某些子项中。但到目前为止还没有运气。我有一条错误消息“无法将组件 'MeshCollider' 添加到 UCX_SM_bench_1_LOD0,因为游戏对象是生成的预制件,只能通过 AssetPostprocessor 进行修改。” 我正在使用 Unity 2017.1。
我是一名 3D 艺术家,这是我第一次尝试编写脚本。
using System;
using System.IO;
using UnityEngine;
using UnityEditor;
public class ModelAssetPostprocessor : AssetPostprocessor
{
public void OnPreprocessModel()
{
ModelImporter modelImporter = assetImporter as ModelImporter;
modelImporter.importAnimation = false;
modelImporter.importBlendShapes = false;
modelImporter.importCameras = false;
modelImporter.importVisibility = false;
modelImporter.importLights = false;
modelImporter.importTangents = ModelImporterTangents.Import;
}
private const string PREFAB_DESTINATION_DIRECTORY = "Assets/Prefabs/";//setting up constant for prefabs destination directory
private static void OnPostprocessAllAssets(
string[] importedAssets,
string[] deletedAssets,
string[] movedAssets,
string[] movedFromAssetPaths)
{
foreach (string path in importedAssets)
{
if (!path.EndsWith(".fbx", StringComparison.OrdinalIgnoreCase)) //skipping all the files, which are not .fbx
continue;
GameObject modelAsset = AssetDatabase.LoadAssetAtPath<GameObject>(path); //As far as I understand here we declare local variable "modelAsset"
//It will become GameObject, which took from AssetDatabase using path we saved before. So
//Now we have a GameObject.
CreatePrefabFromModel(path, modelAsset);
//And now we declare a function to create prefab from our game object
}
}
private static void CreatePrefabFromModel(string path, GameObject modelAsset)
{
EnsureDirectoryExists(PREFAB_DESTINATION_DIRECTORY);
string modelFileName = Path.GetFileNameWithoutExtension(path);
string destinationPath = PREFAB_DESTINATION_DIRECTORY + modelFileName + ".prefab";
if (!File.Exists(destinationPath))
{
GameObjectUtility.SetStaticEditorFlags(modelAsset, StaticEditorFlags.LightmapStatic | StaticEditorFlags.NavigationStatic | StaticEditorFlags.BatchingStatic | StaticEditorFlags.OccludeeStatic | StaticEditorFlags.OccluderStatic | StaticEditorFlags.OffMeshLinkGeneration | StaticEditorFlags.ReflectionProbeStatic);
foreach (Transform child in modelAsset.transform)
{
if (child.transform.name.Contains("UCX_"))
{
Renderer rend;
rend = child.GetComponent<Renderer>();
rend.enabled = !rend.enabled;
string childname = child.transform.name;
GameObject childobject = modelAsset.transform.Find(childname).gameObject;
childobject.AddComponent<MeshCollider>();
}
}
PrefabUtility.CreatePrefab(
destinationPath,
modelAsset);
}
else
{
PrefabUtility.ReplacePrefab(
modelAsset,
AssetDatabase.LoadAssetAtPath<GameObject>(destinationPath),
ReplacePrefabOptions.ReplaceNameBased);
}
}
private static void EnsureDirectoryExists(string directory)
{
if (!Directory.Exists(directory))
Directory.CreateDirectory(directory);
}
}
解决方案
我不知道你想要实现什么,但首先,尝试检查Generate Colliders
模型导入中的复选框(https://docs.unity3d.com/Manual/FBXImporter-Model.html)也许它会解决你所有的问题.
第二个建议 - 更新统一(不,您的脚本将不起作用,但拥有新版本总是更好的方法)
并根据您最初的要求。我只能建议(统一代码 2018.3):
var go = GameObject.Instantiate(modelAsset);
GameObjectUtility.SetStaticEditorFlags(modelAsset, (StaticEditorFlags)(-1));
foreach (Transform child in go.transform)
{
if (child.name.Contains("UCX_"))
{
Renderer rend;
rend = child.GetComponent<Renderer>();
rend.enabled = !rend.enabled;
child.gameObject.AddComponent<MeshCollider>();
}
}
PrefabUtility.SaveAsPrefabAsset(go, destinationPath);
GameObject.DestroyImmediate(go);
我稍微修改了你的脚本。现在网格将首先被实例化,并且预制件将从实例化的对象中创建,而不是从资产中创建。
出现错误的原因是:您正在尝试修改fbx
文件,就像它是一个场景对象一样。你应该先实例化它,然后做任何你想做的改变,然后将它保存为预制件。
推荐阅读
- node.js - 在nodejs中访问函数外部的restAPI响应
- javascript - Chrome 扩展中 tabs.create 之后的 tabs.executeScript
- python-3.x - 如何关闭以前的帧并稍后在 tkinter 中重用它们
- python - 用matplotlib python绘制散点图的平均线
- python-3.x - Command to install Rasa_nlu using conda
- android - Google play iap customer details
- ruby-on-rails - 检索与 Rails 中关联资源列之一匹配的对象
- java - 无法附加到 JTextArea
- pcre - 在 macOS Mojave 上安装 phalcon
- ios - Alamofire:失败响应序列化失败