unity 拷贝文件夹后,新文件夹的预制体引用,动画引用,材质引用,shader引用替换成新文件夹内的文件
时间: 2024-04-06 12:29:30 浏览: 14
可以通过脚本来实现替换操作,以下是一个示例脚本:
```csharp
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Collections.Generic;
public class ReplaceReferences : EditorWindow
{
private string oldFolderPath;
private string newFolderPath;
[MenuItem("Tools/Replace References")]
private static void ShowWindow()
{
ReplaceReferences window = GetWindow<ReplaceReferences>();
window.titleContent = new GUIContent("Replace References");
window.Show();
}
private void OnGUI()
{
GUILayout.Label("Enter old folder path:");
oldFolderPath = EditorGUILayout.TextField(oldFolderPath);
GUILayout.Label("Enter new folder path:");
newFolderPath = EditorGUILayout.TextField(newFolderPath);
if (GUILayout.Button("Replace References"))
{
ReplaceReferencesInFolder(oldFolderPath, newFolderPath);
}
}
private void ReplaceReferencesInFolder(string oldFolder, string newFolder)
{
// Get all assets in the old folder
string[] assetGuids = AssetDatabase.FindAssets("", new string[] { oldFolder });
// Loop through each asset and replace references
foreach (string assetGuid in assetGuids)
{
string assetPath = AssetDatabase.GUIDToAssetPath(assetGuid);
// Check if the asset is a prefab, animation or material
if (assetPath.EndsWith(".prefab") || assetPath.EndsWith(".anim") || assetPath.EndsWith(".mat"))
{
Object asset = AssetDatabase.LoadAssetAtPath<Object>(assetPath);
// Replace prefab references
if (asset is GameObject)
{
GameObject prefab = asset as GameObject;
ReplacePrefabReferences(prefab, oldFolder, newFolder);
}
// Replace animation references
if (asset is AnimationClip)
{
AnimationClip anim = asset as AnimationClip;
ReplaceAnimationReferences(anim, oldFolder, newFolder);
}
// Replace material and shader references
if (asset is Material)
{
Material mat = asset as Material;
ReplaceMaterialReferences(mat, oldFolder, newFolder);
}
}
}
// Refresh the asset database to see changes
AssetDatabase.Refresh();
}
private void ReplacePrefabReferences(GameObject prefab, string oldFolder, string newFolder)
{
// Get all GameObjects in the prefab
GameObject[] objects = GameObject.FindObjectsOfType<GameObject>();
foreach (GameObject obj in objects)
{
// Check if any of the GameObjects in the prefab reference an asset in the old folder
Component[] components = obj.GetComponents<Component>();
foreach (Component component in components)
{
if (component == null)
continue;
SerializedObject so = new SerializedObject(component);
SerializedProperty sp = so.GetIterator();
while (sp.NextVisible(true))
{
if (sp.propertyType == SerializedPropertyType.ObjectReference)
{
if (sp.objectReferenceValue != null)
{
string assetPath = AssetDatabase.GetAssetPath(sp.objectReferenceValue);
if (assetPath.StartsWith(oldFolder))
{
string newAssetPath = assetPath.Replace(oldFolder, newFolder);
Object newAsset = AssetDatabase.LoadAssetAtPath<Object>(newAssetPath);
if (newAsset != null)
{
sp.objectReferenceValue = newAsset;
so.ApplyModifiedProperties();
}
}
}
}
}
}
}
// Save changes to the prefab
PrefabUtility.SaveAsPrefabAsset(prefab, PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(prefab));
}
private void ReplaceAnimationReferences(AnimationClip anim, string oldFolder, string newFolder)
{
// Get all curves in the animation
EditorCurveBinding[] curveBindings = AnimationUtility.GetCurveBindings(anim);
foreach (EditorCurveBinding curveBinding in curveBindings)
{
string propertyName = curveBinding.propertyName;
Object keyframeObject = curveBinding.keyframeCurve;
// Check if the curve references an asset in the old folder
if (keyframeObject != null)
{
string assetPath = AssetDatabase.GetAssetPath(keyframeObject);
if (assetPath.StartsWith(oldFolder))
{
string newAssetPath = assetPath.Replace(oldFolder, newFolder);
Object newAsset = AssetDatabase.LoadAssetAtPath<Object>(newAssetPath);
if (newAsset != null)
{
AnimationUtility.SetObjectReferenceCurve(anim, curveBinding, newAsset);
}
}
}
}
// Save changes to the animation
AssetDatabase.SaveAssets();
}
private void ReplaceMaterialReferences(Material mat, string oldFolder, string newFolder)
{
// Replace the material asset
string matPath = AssetDatabase.GetAssetPath(mat);
if (matPath.StartsWith(oldFolder))
{
string newMatPath = matPath.Replace(oldFolder, newFolder);
Object newMat = AssetDatabase.LoadAssetAtPath<Object>(newMatPath);
if (newMat != null)
{
mat.shader = newMat.shader;
mat.mainTexture = null;
mat.mainTexture = newMat.mainTexture;
}
}
}
}
```
在 Unity 编辑器中,选择 "Tools" 菜单中的 "Replace References" 选项,然后输入旧文件夹路径和新文件夹路径,点击 "Replace References" 按钮即可进行替换操作。请注意备份原始文件,以防误操作。