Unity工程随着复杂度的提升,常会有Prefab上的脚本丢失的情况,如下图所示:

  

  首先失去关联的脚本,是没有线索找到原来是什么文件的,那么有没有办法批处理将这些MissingScript进行一下清理呢?就我使用的Unity4.6所提供的接口来说,没有非常完美的解决办法,但有一些还算可以用来解决问题的做法。

  方法1:找到所有包含有Missing脚本的Prefab,然后逐个手动删除。

  方法2:通过代码自动批处理解决。

  第一种方法比较笨拙,对于资源量不是很大的工程,可以这样做,查找Missing脚本Prefab的代码如下:

using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic; public class ClearMissingScript
{
[MenuItem("Custom/SelectMissing")]
static void SelectMissing(MenuCommand command)
{
string []guids=AssetDatabase.FindAssets("t:Prefab", ["Assets/PrefabDir"]); List<GameObject> selection = new List<GameObject>(); foreach (string guid in guids)
{
string path = AssetDatabase.GUIDToAssetPath(guid);
GameObject obj=AssetDatabase.LoadAssetAtPath(path, typeof(GameObject)) as GameObject;
Component[] cs = obj.GetComponents<Component>(); foreach (Component c in cs)
{
if (c == null)
{
selection.Add(obj);
}
}
} Selection.objects = selection.ToArray();
}
}

  上面的脚本会帮你自动选中所有的包含脚本丢失的Prefab,有耐心的话就挨个处理吧...

  第二种方法会智能一下,但是有一些问题,不确定是不是我代码写的有问题哈,代码如下所示:

  

public class CleanUpMissingScripts
{
[MenuItem("Edit/CleanupMissingScripts &c")]
public static void CleanupMissingScripts()
{
for(int i = ; i < Selection.gameObjects.Length; ++i)
{
var gameObject = Selection.gameObjects[i]; var components = gameObject.GetComponents<Component>(); SerializedObject serializedObject = new SerializedObject(gameObject); SerializedProperty prop = serializedObject.FindProperty("m_Component"); int r = ; for(int j = ; j < components.Length; j++)
{
if(components[j] == null)
{
prop.DeleteArrayElementAtIndex(j - r);
r++;
}
} serializedObject.ApplyModifiedProperties();
} AssetDatabase.Refresh();
}
}

  这个脚本利用SerializedObject和SerializedProperty两个类来进行处理,思路上比较清晰,但是有问题:处理完之后看似清除了所有的Missing脚本,但一运行游戏,这些Missing脚本又回来了,于是换个思路,我们先将处理asset实例化出来,然后对实例化后的GameObject进行处理,再将处理完毕的GameObject写进asset,代码如下所示:

public class MissingScriptsEditor : EditorWindow
{
private static EditorWindow window;
private List<GameObject> lstTmp = new List<GameObject>(); [MenuItem("Custom/MissingScripteEditor")]
private static void Execute()
{
if (window == null)
window = (MissingScriptsEditor)GetWindow(typeof(MissingScriptsEditor));
window.Show();
} private void OnGUI()
{
GUILayout.BeginVertical("box");
if (GUILayout.Button("CleanUpSelection", GUILayout.Height(30f)))
{
CleanUpSelection();
}
GUILayout.EndVertical();
} private void CleanUpSelection()
{
var lstSelection = Selection.GetFiltered(typeof(GameObject), SelectionMode.DeepAssets); for(int i = ; i < lstSelection.Length; ++i)
{
EditorUtility.DisplayProgressBar("Checking", "逐个分析中,请勿退出!", (float)i / (float)lstSelection.Length);
var gameObject = lstSelection[i] as GameObject;
var components = gameObject.GetComponents<Component>(); for (int j = ; j < components.Length; j++)
{
// 如果组建为null
if (components[j] == null)
{
CleanUpAsset(gameObject);
break;
}
}
}
EditorUtility.ClearProgressBar();
AssetDatabase.Refresh(); foreach (var go in lstTmp)
{
GameObject.DestroyImmediate(go);
}
lstTmp.Clear();
} private void CleanUpAsset(Object asset)
{
GameObject go = PrefabUtility.InstantiatePrefab(asset) as GameObject; // 创建一个序列化对象
SerializedObject serializedObject = new SerializedObject(go);
// 获取组件列表属性
SerializedProperty prop = serializedObject.FindProperty("m_Component"); var components = go.GetComponents<Component>();
int r = ;
for (int j = ; j < components.Length; j++)
{
// 如果组建为null
if (components[j] == null)
{
// 按索引删除
prop.DeleteArrayElementAtIndex(j - r);
r++;
}
} // 应用修改到对象
serializedObject.ApplyModifiedProperties(); // 将数据替换到asset
// PrefabUtility.ReplacePrefab(go, asset);
PrefabUtility.CreatePrefab(AssetDatabase.GetAssetPath(asset), go); go.hideFlags = HideFlags.HideAndDontSave; // 删除临时实例化对象
lstTmp.Add(go);
} }

  

  此代码提供了简单的编辑器界面,对于在Project中选中的Prefab进行处理,处理完之后可以很干净的删除所有的MissingScript引用,但是在Ctrl+S或运行游戏的时候会出现一些额外的提示,或者会直接崩掉。但是,重新开启Unity之后就好了,并且问题也解决了。

  所以建议使用这种方法,并且在处理完之后重启一下Unity,然后问题成功解决!

  上面的代码仅供参考,并且此处贴出编辑器处理完之后的报错,希望知道此问题的人能够留言帮我解答一下原因:

  

对于资源上MissingScript的清理方案讨论的更多相关文章

  1. 价值100W的经验分享: 基于JSPatch的iOS应用线上Bug的即时修复方案,附源码.

    限于iOS AppStore的审核机制,一些新的功能的添加或者bug的修复,想做些节日专属的活动等,几乎都是不太可能的.从已有的经验来看,也是有了一些比较常用的解决方案.本文先是会简单说明对比大部分方 ...

  2. 读写分离,读写分离死锁解决方案,事务发布死锁解决方案,发布订阅死锁解决方案|事务(进程 ID *)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务

    前言:         由于网站访问压力的问题,综合分析各种因素后结合实际情况,采用数据库读写分离模式来解决当前问题.实际方案中采用“事务发布”模式实现主数据库和只读数据库的同步,其中: 发布服务器1 ...

  3. 关于七牛云存储,HTTPS资源上传不成功问题

    关于七牛云存储,HTTPS资源上传不成功问题 官方给出了一个解决方案,亲测可用.特此记录一下. 找到QNConfiguration.m文件.然后重写两个方法,直接上代码. + (instancetyp ...

  4. Maven私服(Nexus)资源上传下载

    1.settings.xml (向私服上传资源需要) <!-- Snapshot包的管理/Releases包的管理/第三方包管理--> <server> <id>l ...

  5. 事务(进程 ID 64)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。

    访问频率比较高的app接口,在后台写的异常日志会偶尔出现以下错误. 事务(进程 ID 64)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品.请重新运行该事务 实所有的死锁最深层的原因就是一个 ...

  6. Kettle 解决数据锁的问题(事务(进程 ID 51)与另一个进程被死锁在 锁 资源上)

    1.Kettle做了一个作业, 执行的时候问题发生在步骤2和步骤3之间,也就是步骤2还未完全执行完的时候,步骤3就要更新步骤2插入的数据,造成死锁.(我的理解是既然都分开作业了,那么每个作业都是一个单 ...

  7. 并发错误:事务(进程 ID )与另一个进程已被死锁在 lock 资源上,且该事务已被选作死锁牺牲品

    这个是并发情况下导致的数据库事务错误,先介绍下背景. 背景 springboot+springmvc+sqlserver+mybatis 一个controller里有五六个接口,这些接口都用到了spr ...

  8. C# 最基本的涉及模式(单例模式) C#种死锁:事务(进程 ID 112)与另一个进程被死锁在 锁 | 通信缓冲区 资源上,并且已被选作死锁牺牲品。请重新运行该事务,解决方案: C#关闭应用程序时如何关闭子线程 C#中 ThreadStart和ParameterizedThreadStart区别

    C# 最基本的涉及模式(单例模式) //密封,保证不能继承 public sealed class Xiaohouye    { //私有的构造函数,保证外部不能实例化        private  ...

  9. hadoop-09-安装资源上传

    hadoop-09-安装资源上传 在/software/www/html 下面上传 ambari  HDP  HDP-UTILS-1.1.0.21 文件,之后解压:

随机推荐

  1. Windows Phone 8.1 新特性 - 控件之FlipView

    本篇为大家介绍 Windows Phone 8.1 中新增的 FlipView 控件,它的中文名字叫做:翻转视图. 虽然听起来有点拗口,但是它的用途大家一定不会陌生.在 Windows Phone 8 ...

  2. Alpha、Beta、RC、GA版本的区别 ZT

    http://www.blogjava.net/RomulusW/archive/2008/05/04/197985.html Alpha:是内部测试版,一般不向外部发布,会有很多Bug.一般只有测试 ...

  3. win32 COM组件编写

    win32的com组件: 1. 编辑idl,idl文件会生成对应的com class和com interface,例如 [ object, uuid(xxxxxxxx-xxxx-xxxx-xxxx-x ...

  4. SAS零散知识总结

    1,变量名命名规范:以字母或者下划线开始,可包含字母.下划线.数字,且不超过32个字符: 2,INFILE用于读取外部数据文件,一般于FILENAME(和LIBNAME用户一致,但路径要精确到文件名( ...

  5. (混合背包 多重背包+完全背包)The Fewest Coins (poj 3260)

    http://poj.org/problem?id=3260   Description Farmer John has gone to town to buy some farm supplies. ...

  6. 用UEFI安装ArchLinux 20140105

    为了在E431上用UEFI安装Arch一个晚上重装了5,6次系统,整整做了一个通宵,还好是周六.今天刚好有时间正好 来总结一下.因为要用UEFI来安装,所以安装了两次之后发现UEFI环境变量不可用(用 ...

  7. ios申请真机调试( xcode 5)详细解析

    已经有开发证书的直接跳过第一步 第一步:申请"开发证书" 进入苹果开发者99美元账号: 选择:Certificates, Identifiers & Profiles 关于 ...

  8. CPU与内存的关系

    至今才对cpu和内存有一定了解了,下面有几个比喻的理解,很形象呦~ 1# 例如你要吃东西时,硬盘是锅,内存是碗,CPU是你,浅显点就是这样子了~ 2# 例如电脑是企业,内存是车间,cpu是生产线,硬盘 ...

  9. Linux内核--网络栈实现分析(五)--传输层之UDP协议(上)

    本文分析基于Linux Kernel 1.2.13 原创作品,转载请标明出处http://blog.csdn.net/yming0221/article/details/7532512 更多请看专栏, ...

  10. PDF

    源代码请从这里下载: http://download.csdn.net/source/2984395 使用的是JSP编程 ‍ 这是导出后的效果 ‍ 这是数据库中的内容 ‍ 部分代码: <%@ p ...