unity 代码批量修改Remove Missing Script和批量修改指定组件的内容

昨天在项目开发中,发现一个问题,就是一些脚本已经被废弃,但是这些废弃脚本还是被绑定在某些预制体中,这时候运行就会产生很多Missing Script的警告信息,这些警告虽不影响代码的实际运行,但是一个大项目肯定不能出现的N多的警告信息,并且这里通过手动去找肯定不现实,所以这里我们就同一个脚本去实现自动去遍历所有的prefab然后移除Missing的组件,下面是具体的代码信息。

1.首先在工程中创建一个Editro文件夹,将脚本放在Editor文件夹下

2.通过选中文件,通过编辑器实现遍历该文件夹下的所有prefab:

    [MenuItem("工具/对象移除丢失脚本")]
    static void GetAllGo()
    {
        //寻找你选中文件夹下的所有文件
        object[] obj = Selection.GetFiltered(typeof(object), SelectionMode.DeepAssets);
        for (int i = 0; i < obj.Length; i++)
        {
            //获取文件的后缀信息
            string ext = System.IO.Path.GetExtension(obj[i].ToString());
            //这里筛选出不是预制体的物体
            if (!ext.Contains(".GameObject"))
            {
                continue;
            }

            GameObject go = (GameObject)obj[i];

            // 移除子物体下的脚本丢失
            foreach (Transform trans in go.GetComponentsInChildren<Transform>(true))
            {
                CleanMissingScript(trans.gameObject, go);
            }
        }
    }

3.找到prefab,去遍历她的所有子物体,并实现直接移除相应的空组件:

    static void CleanMissingScript(GameObject go, GameObject parentGO)
    {
        var components = go.GetComponents<Component>();
        var serializedObject = new SerializedObject(go);
        var prop = serializedObject.FindProperty("m_Component");
        int r = 0;
        for (int j = 0; j < components.Length; j++)
        {
            if (components[j] == null)
            {
                prop.DeleteArrayElementAtIndex(j - r);
                MyDebug.Log("成功移除丢失脚本,gameObject name: " + go.name + " ---父类prefab name:" + parentGO.name);
                r++;
            }
        }
        serializedObject.ApplyModifiedProperties();
    }

4.如果还要做其他操作,比如我们写了一个扩展的button脚本,这时候我们不可能通过手动去把所有之前的button换成新的butonPlus,所以这时候就需要去代码自动实现:

    static void CleanMissingScript(GameObject go, GameObject parentGO)
    {
        var components = go.GetComponents<Component>();

        //如果当前组件有按钮
        if (go.GetComponent<UnityEngine.UI.Button>() != null)
        {
            Button btn = go.GetAddComponent<Button>();
            //copy之前的组件信息
            UnityEditorInternal.ComponentUtility.CopyComponent(btn);
            //移除组件信息
            GameObject.DestroyImmediate(btn);
            //TODO:添加新的组件信息

        }       
        serializedObject.ApplyModifiedProperties();
    }

5.下面是完整脚本:

using UnityEngine;
using UnityEditor;
using UnityEngine.UI;

/// <summary>
/// 移除项目中go上丢失的脚本
/// </summary>
public class RemoveMissingScript
{
    [MenuItem("SlgTool/程序工具/对象移除丢失脚本")]
    static void GetAllGo()
    {
        object[] obj = Selection.GetFiltered(typeof(object), SelectionMode.DeepAssets);
        for (int i = 0; i < obj.Length; i++)
        {
            string ext = System.IO.Path.GetExtension(obj[i].ToString());
            Debug.Log("name:" + ext);
            if (!ext.Contains(".GameObject"))
            {
                continue;
            }

            GameObject go = (GameObject)obj[i];

            // 移除子物体下的脚本丢失
            foreach (Transform trans in go.GetComponentsInChildren<Transform>(true))
            {
                CleanMissingScript(trans.gameObject, go);
            }
        }

    }

    static void CleanMissingScript(GameObject go, GameObject parentGO)
    {
        var components = go.GetComponents<Component>();   
        var serializedObject = new SerializedObject(go);
        var prop = serializedObject.FindProperty("m_Component");
        int r = 0;
        for (int j = 0; j < components.Length; j++)
        {
            if (components[j] == null)
            {
                prop.DeleteArrayElementAtIndex(j - r);
                MyDebug.Log("成功移除丢失脚本,gameObject name: " + go.name + " ---父类prefab name:" + parentGO.name);
                r++;
            }
        }
        serializedObject.ApplyModifiedProperties();
    }

}

这里就是一个完整的代码自动查找prefab下的空组件,然后移除的代码。

想了解更多请添加下方公众号,或者添加QQ群:879354767

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值