Unity资源替换工具,旧模型替换新模型,替换GUID,替换meta文件,文件丢失等问题

Unity资源替换工具,旧模型替换新模型,替换GUID,替换meta文件,文件丢失等问题

使用说明

第一次写,不是很规范,好东西分享给大家,学点编辑器扩展好处多啊!

如何使用

这个小工具确实帮到我了,替我省了不少时间
直接上代码:

using UnityEngine;
using System.Collections;
using UnityEditor;
using System.Linq;
using System.IO;
using System.Text.RegularExpressions;
using System.Collections.Generic;

/// <summary>
/// 解决项目中 一样的资源(名字或者路径不同)存在两份的问题  (多人做UI出现的问题, 或者美术没有管理好资源)
/// 如果是要替换资源的话, 那就直接替换好了
/// 
/// 以上可以这么操作的基础是,你的Unity项目内的.prefab .Unity 都可以直接用文本开看到数据,而不是乱码(二进制)。这一步很关键,怎么设置呢?
/// 打开项目Unity编辑器:Edit —-> Project Settings —-> Editor 这样就会调到你的Inspector面板的Editor Settings 
/// 设置 Asset Serialization 的Mode类型为:Force Text(默认是Mixed); 这样你就能看到你的prefab文件引用了哪些贴图,字体,prefab 等资源了
/// </summary>
public class ResourcesReplace : EditorWindow
{
    private static ResourcesReplace _window;
    private Object _sourceOld;
    private Object _sourceNew;

    private string _oldGuid;
    private string _newGuid;

    private bool isContainScene = true;
    private bool isContainPrefab = true;
    private bool isContainMat = true;
    private bool isContainAsset = false;

    private List<string> withoutExtensions = new List<string>();


    [MenuItem("Tools/资源替换")]   // 菜单开启并点击的   处理
    public static void GUIDRefReplaceWin()
    {

        // true 表示不能停靠的
        _window = (ResourcesReplace)EditorWindow.GetWindow(typeof(ResourcesReplace), true, "引用替换 (●'◡'●)");
        _window.Show();

    }

    void OnGUI()
    {
        // 要被替换的(需要移除的)
        GUILayout.Space(20);


        _sourceOld = EditorGUILayout.ObjectField("旧的资源", _sourceOld, typeof(Object), true);
        _sourceNew = EditorGUILayout.ObjectField("新的资源", _sourceNew, typeof(Object), true);


        // 在那些类型中查找(.unity\.prefab\.mat)
        GUILayout.Space(20);
        GUILayout.Label("要在哪些类型中查找替换:");
        EditorGUILayout.BeginHorizontal();

        isContainScene = GUILayout.Toggle(isContainScene, ".unity");
        isContainPrefab = GUILayout.Toggle(isContainPrefab, ".prefab");
        isContainMat = GUILayout.Toggle(isContainMat, ".mat");
        isContainAsset = GUILayout.Toggle(isContainAsset, ".asset");

        EditorGUILayout.EndHorizontal();


        GUILayout.Space(20);
        if (GUILayout.Button("开始替换!"))
        {
            if (EditorSettings.serializationMode != SerializationMode.ForceText)
            {
                Debug.LogError("需要设置序列化模式为 SerializationMode.ForceText");
                ShowNotification(new GUIContent("需要设置序列化模式为 SerializationMode.ForceText"));
            }
            else if (_sourceNew == null || _sourceOld == null)
            {
                Debug.LogError("不能为空!");
                ShowNotification(new GUIContent("不能为空!"));
            }
            else if (_sourceNew.GetType() != _sourceOld.GetType())
            {
                Debug.LogError("两种资源类型不一致!");
                ShowNotification(new GUIContent("两种资源类型不一致!"));
            }
            else if (!isContainScene && !isContainPrefab && !isContainMat && !isContainAsset)
            {
                Debug.LogError("要选择一种 查找替换的类型");
                ShowNotification(new GUIContent("要选择一种 查找替换的类型"));
            }
            else   // 执行替换逻辑
            {
                StartReplace();
            }
        }
    }

    private void StartReplace()
    {
        var path = AssetDatabase.GetAssetPath(_sourceOld);

        _oldGuid = AssetDatabase.AssetPathToGUID(path);
        _newGuid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(_sourceNew));

        Debug.Log("oldGUID = " + _oldGuid + "  " + "_newGuid = " + _newGuid);

        withoutExtensions = new List<string>();
        if (isContainScene)
        {
            withoutExtensions.Add(".unity");
        }
        if (isContainPrefab)
        {
            withoutExtensions.Add(".prefab");
        }
        if (isContainMat)
        {
            withoutExtensions.Add(".mat");
        }
        if (isContainAsset)
        {
            withoutExtensions.Add(".asset");
        }

        Find();
    }

    /// <summary>
    /// 查找  并   替换 
    /// </summary>
    private void Find()
    {
        if (withoutExtensions == null || withoutExtensions.Count == 0)
        {
            withoutExtensions = new List<string>() { ".prefab", ".unity", ".mat", ".asset" };
        }

        string[] files = Directory.GetFiles(Application.dataPath, "*.*", SearchOption.AllDirectories)
        .Where(s => withoutExtensions.Contains(Path.GetExtension(s).ToLower())).ToArray();
        int startIndex = 0;

        if (files == null || files.Length == 0)
        {
            Debug.Log("没有找到 筛选的引用");
            return;
        }

        EditorApplication.update = delegate ()
        {
            string file = files[startIndex];

            bool isCancel = EditorUtility.DisplayCancelableProgressBar("匹配资源中", file, (float)startIndex / (float)files.Length);

            var content = File.ReadAllText(file);
            if (Regex.IsMatch(content, _oldGuid))
            {
                Debug.Log("替换了资源的路径:" + file, AssetDatabase.LoadAssetAtPath<Object>(GetRelativeAssetsPath(file)));

                content = content.Replace(_oldGuid, _newGuid);

                File.WriteAllText(file, content);
            }
            else
            {
                Debug.Log("查看了的路径:" + file);
            }

            startIndex++;
            if (isCancel || startIndex >= files.Length)
            {
                EditorUtility.ClearProgressBar();
                EditorApplication.update = null;
                startIndex = 0;

                AssetDatabase.Refresh();
                Debug.Log("替换结束");
            }

        };
    }

    private string GetRelativeAssetsPath(string path)
    {
        return "Assets" + Path.GetFullPath(path).Replace(Path.GetFullPath(Application.dataPath), "").Replace('\\', '/');
    }

}

导入代码后打开Tools里的资源替换
小窗口写的明明白白的,一看就懂
我当时是一起合作的项目,用的同一个模型,结果合并时发现Unity识别同样的FBX要替换说GUID不同
文件里两个FBX一模一样,就因为meta文件不一样,要么他的场景里的模型显示不出来,要么是我的场景里的模型显示不出来

在这里插入图片描述

用的时候把两个模型以不同名字导进去,导入之后两个模型放入新的资源与旧的资源里
下面如果不太清楚需要替换那些 建议全部勾选
在这里插入图片描述
链接: 代码出处.

  • 5
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

唐沢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值