using UnityEngine; using System.Collections.Generic; public class WallCombineManager : CombineTileByCPU, IMethodHandler { [SerializeField] private Material material; [SerializeField] private Shader cutoutShader; [SerializeField] private Shader segmentationShader; private JsonConfigParser.TileConfig currentConfig; private JsonConfigParser.TileConfig originalConfig; private Shader originalShader; private const string TEXTURE_PREFIX = "_Texture"; private const string PERCENTAGE_PREFIX = "_Percentage"; public static WallCombineManager Instance { get; private set; } // 添加字典来跟踪当前使用的纹理 private Dictionary currentTextures = new Dictionary(); private void CleanupOldTextures() { foreach (var texture in currentTextures.Values) { if (texture != null) { // 在编辑器模式下使用 DestroyImmediate,运行时使用 Destroy if (Application.isPlaying) Destroy(texture); else DestroyImmediate(texture); } } currentTextures.Clear(); } // 在对象销毁时清理资源 private void OnDestroy() { CleanupOldTextures(); } private void Awake() { if (Instance != null && Instance != this) { Destroy(gameObject); return; } Instance = this; DontDestroyOnLoad(gameObject); SaveOriginalShader(); } public void HandleMethod(string methodName, string jsonParameter) { switch (methodName) { case "SetTexture": SetTexture(jsonParameter); break; case "GetCombinedTexture": GetCombinedTexture(jsonParameter); break; case "SetSegTexture": SetSegTexture(jsonParameter); break; default: Debug.LogWarning($"Unknown method: {methodName}"); break; } } private void SaveOriginalShader() { if (material != null) { originalShader = material.shader; } else { Debug.LogWarning("Material is not assigned in WallCombineManager"); } } public override JsonConfigParser.TileConfig GetConfig() { return currentConfig; } public override void SetTileConfig(string jsonContent) { if (string.IsNullOrEmpty(jsonContent)) { Debug.LogError("Invalid JSON content provided"); return; } try { if (originalConfig == null) { originalConfig = ConfigManager.getTestTileConfig(jsonContent); } currentConfig = ConfigManager.getTestTileConfig(jsonContent); } catch (System.Exception e) { Debug.LogError($"Error parsing tile config: {e.Message}"); } } public override Material GetCurrentMaterial() { if (material == null) { Debug.LogWarning("Material or original shader is null"); return null; } material.shader = originalShader; return material; } public override Shader GetCurrentShader() { return cutoutShader; } public void SetTexture(string jsonStr) { if (string.IsNullOrEmpty(jsonStr)) { Debug.LogError("Invalid JSON string provided"); return; } if (material == null) { Debug.LogWarning("Material or original shader is null"); return; } material.shader = originalShader; ConfigCache.Instance.SetConfig("wall", jsonStr); UpdateMaterial(jsonStr); } public void SetSegTexture(string jsonStr) { if (!ValidateSegTextureInput(jsonStr)) { return; } try { ApplySegmentationShader(); SetTileConfig(jsonStr); var config = GetConfig(); ApplyTextureConfiguration(config); } catch (System.Exception e) { Debug.LogError($"Error setting segmentation texture: {e.Message}"); } } private bool ValidateSegTextureInput(string jsonStr) { if (string.IsNullOrEmpty(jsonStr)) { Debug.LogError("Invalid JSON string provided"); return false; } if (segmentationShader == null) { Debug.LogWarning("Material or segmentation shader is null"); return false; } return true; } private void ApplySegmentationShader() { material.shader = segmentationShader; } private void ApplyTextureConfiguration(JsonConfigParser.TileConfig config) { if (config == null) { Debug.LogError("Config is null"); return; } SetMaterialProperties(config); LoadAndSetTextures(config); } private void SetMaterialProperties(JsonConfigParser.TileConfig config) { material.SetVector("_tiling", new Vector2(config.tiles[0], config.tiles[1])); material.SetInt("_Vertical", config.isVertical); material.SetFloat("_Gap", config.vSeam); for (int i = 0; i < config.instances.Count; i++) { material.SetFloat($"{PERCENTAGE_PREFIX}{i + 1}", config.instances[i].seg.vRange); } } private void LoadAndSetTextures(JsonConfigParser.TileConfig config) { // 清理旧纹理 CleanupOldTextures(); for (int i = 0; i < config.base64Textures.Length; i++) { if (string.IsNullOrEmpty(config.base64Textures[i])) { continue; } var texture = Base64ToTexture.ConvertBase64ToTexture(config.base64Textures[i]); if (texture != null) { string textureName = $"{TEXTURE_PREFIX}{i + 1}"; currentTextures[textureName] = texture; material.SetTexture(textureName, texture); } } } public new void GetCombinedTexture(string jsonStr) { if (string.IsNullOrEmpty(jsonStr)) { Debug.LogError("Invalid JSON string provided"); return; } base.GetCombinedTexture(jsonStr); } }