From 3df855597a635c3a0d1f3ee33edd6c0032808538 Mon Sep 17 00:00:00 2001 From: MelekTaus Moribundus Date: Wed, 24 Jun 2026 20:38:11 +0200 Subject: [PATCH] Sync HUD and enable all paint channels on pipette pick After a successful pipette pick the painter now enables all four paint channels (albedo, metallic/smoothness, occlusion, emission) and raises a Picked event. The HUD subscribes and re-syncs every widget (toggles, sliders, both colour pickers) to the adopted brush values. Co-Authored-By: Claude Opus 4.8 --- Assets/Scripts/MeshPainter.Pick.cs | 16 +++++++++ Assets/Scripts/PaintHud.cs | 57 ++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/Assets/Scripts/MeshPainter.Pick.cs b/Assets/Scripts/MeshPainter.Pick.cs index f4465e8..ca54ce9 100644 --- a/Assets/Scripts/MeshPainter.Pick.cs +++ b/Assets/Scripts/MeshPainter.Pick.cs @@ -1,3 +1,4 @@ +using System; using UnityEngine; public partial class MeshPainter @@ -18,6 +19,12 @@ public partial class MeshPainter "(all alphas set to 1) instead of painting. Held button picks only once.")] public bool pipette = false; + /// + /// Raised after a successful pick, once the brush has adopted the sampled values and all four + /// paint-channel flags have been enabled. The in-game HUD listens to re-sync its widgets. + /// + public event Action Picked; + private bool _pickHeld; // edge tracking so a held button picks once, not every frame /// @@ -67,5 +74,14 @@ public partial class MeshPainter // "Set all alpha values to 1": full-strength adoption across every opacity control. metallicSmoothnessOpacity = 1f; occlusionOpacity = 1f; + + // Picking a whole material implies repainting all of it, so enable every channel. + paintAlbedo = true; + paintMetallicSmoothness = true; + paintOcclusion = true; + paintEmission = true; + + // Let listeners (the in-game HUD) refresh their widgets to the adopted values + flags. + Picked?.Invoke(); } } diff --git a/Assets/Scripts/PaintHud.cs b/Assets/Scripts/PaintHud.cs index 5ba10ac..a780240 100644 --- a/Assets/Scripts/PaintHud.cs +++ b/Assets/Scripts/PaintHud.cs @@ -112,10 +112,18 @@ public class PaintHud : MonoBehaviour WirePanel(_panel.transform); + // Re-sync every widget when the pipette adopts a sampled material (painter -> HUD). + if (painter) painter.Picked += SyncFromPainter; + // Set initial visibility (the manager's first SwitchTo may have fired before this Start). OnModeChanged(modeManager ? modeManager.ActiveMode : null); } + private void OnDestroy() + { + if (painter) painter.Picked -= SyncFromPainter; + } + private void OnModeChanged(GameMode mode) { if (_panel) _panel.SetActive(mode is PaintMode); @@ -204,6 +212,55 @@ public class PaintHud : MonoBehaviour MakeDraggable(panel, name); } + /// + /// Pushes the painter's current values back into every widget (painter -> HUD), e.g. after a + /// pipette pick changed them outside the UI. No listeners are added here: setting a toggle/slider + /// value fires its existing change listener, which keeps the painter, value labels and panel-fade + /// alphas in sync; the colour pickers update silently via SetColor (it does not raise Changed). + /// + private void SyncFromPainter() + { + if (!_panel || !painter) return; + var panel = _panel.transform; + + SetToggle(panel, ToggleAlbedo, painter.paintAlbedo); + SetToggle(panel, ToggleMetallicSmoothness, painter.paintMetallicSmoothness); + SetToggle(panel, ToggleOcclusion, painter.paintOcclusion); + SetToggle(panel, ToggleEmission, painter.paintEmission); + SetToggle(panel, ToggleSpray, painter.spray); + SetToggle(panel, TogglePipette, painter.pipette); + + SetPicker(panel, PickerAlbedo, painter.brushColor); + SetPicker(panel, PickerEmission, painter.emissionColor); + + SetSlider(panel, SliderMetallic, painter.metallic); + SetSlider(panel, SliderSmoothness, painter.smoothness); + SetSlider(panel, SliderMetallicSmoothnessAlpha, painter.metallicSmoothnessOpacity); + SetSlider(panel, SliderOcclusion, painter.occlusion); + SetSlider(panel, SliderOcclusionAlpha, painter.occlusionOpacity); + SetSlider(panel, SliderEmissionIntensity, painter.emissionIntensity); + SetSlider(panel, SliderBrushSize, painter.brushSize); + } + + private static void SetToggle(Transform panel, string name, bool value) + { + var toggle = Find(panel, name); + if (toggle) toggle.isOn = value; // only fires onValueChanged when it actually changes + } + + private static void SetSlider(Transform panel, string name, float value) + { + var cell = FindDeep(panel, name); + var slider = cell ? cell.GetComponentInChildren() : null; + if (slider) slider.value = value; // listener refreshes the value label + painter + } + + private static void SetPicker(Transform panel, string name, Color color) + { + var picker = Find(panel, name); + if (picker) picker.SetColor(color); + } + /// /// Attaches (idempotently) a to the whole panel so it can be dragged /// from any of its non-interactive surface (header, padding, labels, background); the component