Unity 编辑器模式下查找引用指定图片的所有预制件,并替换成新的指定图片

public Sprite oldSprite;
public Sprite newSprite;
public string path = "Assets/";

public void FindAndChangePrefab()
    {
        if (oldSprite == null)
        {
            Debug.Log("请先设置查找引用的图片");
            return;
        }
        if (newSprite == null)
        {
            Debug.Log("请先设置替换的图片");
            return;
        }
        // 搜索所有预制件,并检查它们是否引用了该Sprite
        int changeCount = 0;
        string[] guids = AssetDatabase.FindAssets("t:Prefab", new[] { path});
        foreach (string guid in guids)
        {
            string assetPath = AssetDatabase.GUIDToAssetPath(guid);
            GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(assetPath);
            Image[] AllImage = prefab.transform.GetComponentsInChildren<Image>(true);
            bool isChange = false;
            foreach (Image spriteRenderer in AllImage)
            {
                if (spriteRenderer.sprite == oldSprite)
                {
                    Debug.Log(string.Format("预制件:{0}  里的 {1} 查找到引用",prefab.name,spriteRenderer.transform.name));
                    spriteRenderer.sprite = newSprite;
                    isChange = true;
                }
            }

            if (isChange)
            {
                EditorUtility.SetDirty(prefab);
                changeCount++;
            }
        }
        
        // 输出结果
        if (changeCount == 0)
        {
            Debug.Log("没有预制件在引用此图片");
        }
        else
        {
            AssetDatabase.SaveAssets();
            Debug.Log("查找并替换完成");
        }
    }

如果你在 Unity 拷贝了一个文件夹,并且想要将该文件夹的所有预制引用替换为文件夹预制,你可以使用 Unity 的 AssetDatabase API 来实现。 以下是一个示例代码,可以将一个名为 "OldFolder" 的文件夹所有预制引用替换为名为 "NewFolder" 的文件夹预制: ```csharp using UnityEngine; using UnityEditor; using System.IO; public class ReplacePrefabReferences : AssetPostprocessor { // 监听资源导入事件 void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) { // 遍历所有导入的资源 foreach (string str in importedAssets) { // 判断是否为预制 if (str.EndsWith(".prefab")) { // 加载预制 GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(str); // 获取预制所有组件 Component[] components = prefab.GetComponentsInChildren<Component>(true); // 遍历组件 foreach (Component component in components) { // 判断组件是否为引用类型 if (component == null || component.GetType().IsValueType) continue; // 获取组件的 SerializedObject SerializedObject so = new SerializedObject(component); SerializedProperty sp = so.GetIterator(); // 遍历组件的 SerializedProperty while (sp.NextVisible(true)) { // 判断 SerializedProperty 是否为 ObjectReference 类型 if (sp.propertyType == SerializedPropertyType.ObjectReference) { // 获取 SerializedProperty 引用的对象 Object obj = sp.objectReferenceValue; // 判断对象是否为预制或场景的 GameObject if (obj != null && (PrefabUtility.IsPartOfPrefabAsset(obj) || PrefabUtility.IsPartOfPrefabInstance(obj) || PrefabUtility.GetPrefabAssetType(obj) == PrefabAssetType.Regular || obj is GameObject)) { // 获取对象的 AssetPath string assetPath = AssetDatabase.GetAssetPath(obj); // 判断 AssetPath 是否在 OldFolder if (assetPath.StartsWith("Assets/OldFolder/")) { // 替换对象的引用 string newPath = assetPath.Replace("Assets/OldFolder/", "Assets/NewFolder/"); Object newObject = AssetDatabase.LoadAssetAtPath(newPath, obj.GetType()); sp.objectReferenceValue = newObject; } } } } // 应用修改 so.ApplyModifiedProperties(); } // 保存修改 PrefabUtility.SaveAsPrefabAssetAndConnect(prefab, str, InteractionMode.AutomatedAction); } } } } ``` 这段代码监听了 Unity 的资源导入事件,当导入的资源为预制时,遍历预制的所有组件,查找所有 ObjectReference 类型的 SerializedProperty,并判断该 SerializedProperty 引用的对象是否在 OldFolder ,如果是,则将对象的引用替换为 NewFolder 的对应对象。最后,保存修改后的预制
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值