using UnityEngine; using UnityEditor; using System.IO; public class TreeModelReplacer : MonoBehaviour { [Header("树木模型替换配置")] [SerializeField] private GameObject[] availableTreeModels; [SerializeField] private string stageItemPrefabPath = "Assets/GAME/Prefabs/Stages/Stage_Item.prefab"; [Header("替换设置")] [SerializeField] private bool replacePineTrees = true; [SerializeField] private bool replaceRocks = false; [SerializeField] private bool replaceHerbs = false; [SerializeField] private float scaleMultiplier = 1.0f; [ContextMenu("替换树木模型")] public void ReplaceTreeModels() { #if UNITY_EDITOR // 备份原始Prefab string backupPath = stageItemPrefabPath.Replace(".prefab", "_backup.prefab"); if (!File.Exists(backupPath)) { File.Copy(stageItemPrefabPath, backupPath); Debug.Log($"已备份原始Prefab到: {backupPath}"); } // 加载Stage_Item Prefab GameObject stageItemPrefab = AssetDatabase.LoadAssetAtPath(stageItemPrefabPath); if (stageItemPrefab == null) { Debug.LogError($"无法加载Prefab: {stageItemPrefabPath}"); return; } // 查找并替换树木模型 Transform[] allChildren = stageItemPrefab.GetComponentsInChildren(); foreach (Transform child in allChildren) { if (child.name.Contains("Pine") && replacePineTrees) { ReplaceModel(child, "Tree"); } else if (child.name.Contains("Rock") && replaceRocks) { ReplaceModel(child, "Rock"); } else if (child.name.Contains("Herb") && replaceHerbs) { ReplaceModel(child, "Flower"); } } // 保存修改 EditorUtility.SetDirty(stageItemPrefab); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); Debug.Log("树木模型替换完成!"); #endif } private void ReplaceModel(Transform targetTransform, string modelType) { #if UNITY_EDITOR // 获取MeshFilter和MeshRenderer MeshFilter meshFilter = targetTransform.GetComponent(); MeshRenderer meshRenderer = targetTransform.GetComponent(); if (meshFilter == null || meshRenderer == null) { Debug.LogWarning($"对象 {targetTransform.name} 缺少MeshFilter或MeshRenderer组件"); return; } // 根据类型选择新模型 GameObject newModel = null; switch (modelType) { case "Tree": if (availableTreeModels.Length > 0) { newModel = availableTreeModels[Random.Range(0, availableTreeModels.Length)]; } break; case "Rock": newModel = Resources.Load("Props/Rock_1"); break; case "Flower": newModel = Resources.Load("Props/Flower"); break; } if (newModel == null) { Debug.LogWarning($"未找到 {modelType} 类型的模型"); return; } // 获取新模型的Mesh和Material MeshFilter newMeshFilter = newModel.GetComponent(); MeshRenderer newMeshRenderer = newModel.GetComponent(); if (newMeshFilter != null && newMeshRenderer != null) { // 替换Mesh meshFilter.mesh = newMeshFilter.sharedMesh; // 替换Material if (newMeshRenderer.sharedMaterials.Length > 0) { meshRenderer.materials = newMeshRenderer.sharedMaterials; } // 调整缩放 targetTransform.localScale *= scaleMultiplier; Debug.Log($"已替换 {targetTransform.name} 为 {newModel.name}"); } #endif } [ContextMenu("恢复原始模型")] public void RestoreOriginalModels() { #if UNITY_EDITOR string backupPath = stageItemPrefabPath.Replace(".prefab", "_backup.prefab"); if (File.Exists(backupPath)) { File.Copy(backupPath, stageItemPrefabPath, true); AssetDatabase.Refresh(); Debug.Log("已恢复原始模型"); } else { Debug.LogError("未找到备份文件"); } #endif } [ContextMenu("预览可用树木模型")] public void PreviewAvailableTrees() { #if UNITY_EDITOR Debug.Log("=== 可用的树木模型 ==="); foreach (GameObject tree in availableTreeModels) { if (tree != null) { Debug.Log($"- {tree.name}"); } } #endif } }