using UnityEngine; [ExecuteAlways] [RequireComponent(typeof(MeshRenderer))] public class FurnitureVisuals : MonoBehaviour { private MeshRenderer _meshRenderer; private MaterialPropertyBlock _mpb; // Кэшируем новые ID для производительности private static readonly int AtlasRectProp = Shader.PropertyToID("_AtlasRect"); private static readonly int MetallicProp = Shader.PropertyToID("_Metallic"); private static readonly int SmoothnessProp = Shader.PropertyToID("_Smoothness"); private static readonly int EmissionColorProp = Shader.PropertyToID("_EmissionColor"); [Header("Live Preview")] public bool enableLivePreview = false; public FurnitureItemSO previewItem; private void Awake() { _meshRenderer = GetComponent(); _mpb = new MaterialPropertyBlock(); } private void Update() { if (!Application.isPlaying && enableLivePreview && previewItem != null) { if (previewItem.availablePresets.Count > 0) { ApplyPreset(previewItem.availablePresets[0]); } } } public void ApplyPreset(FurniturePreset preset) { if (preset == null || preset.slotStyles == null) return; if (_mpb == null) _mpb = new MaterialPropertyBlock(); if (_meshRenderer == null) _meshRenderer = GetComponent(); for (int i = 0; i < preset.slotStyles.Length; i++) { // --- НОВАЯ ЗАЩИТА --- // Если индекс стиля больше, чем количество материалов на модели - пропускаем! if (i >= _meshRenderer.sharedMaterials.Length) { Debug.LogWarning($"[FurnitureVisuals] Пытаемся покрасить слот {i}, но на модели {_meshRenderer.gameObject.name} всего {_meshRenderer.sharedMaterials.Length} материалов. Лишние стили проигнорированы."); continue; } // --------------------- AtlasStyleSO style = preset.slotStyles[i]; if (style != null) { _meshRenderer.GetPropertyBlock(_mpb, i); _mpb.SetVector(AtlasRectProp, style.atlasRect); _mpb.SetFloat(MetallicProp, style.metallic); _mpb.SetFloat(SmoothnessProp, style.smoothness); Color finalEmissionColor = style.useEmission ? style.emissionColor : Color.black; _mpb.SetColor(EmissionColorProp, finalEmissionColor); _meshRenderer.SetPropertyBlock(_mpb, i); } } } }