Persist material scalars, reset the HUD, and split alpha from the picker
Save and restore the emission intensity and the three camo knobs (half-Lambert, half-Lambert brightness, specular dampen) with a named painting. The .paint format moves to v3 with a small scalar block between the header and the pixel maps; v2 paintings still load with their painter values left untouched. Loading re-syncs the emission and camo sliders, and peers pick the values up for free through the existing owner-authoritative paint NetworkVariables. Add a HUD reset (Lib_ResetHud button plus context-menu fallback) that behaves as if the saved hud-layout file were deleted: it removes the file, restores panels to their authored prefab positions, and resets the brush values to the painter/material defaults captured before any carry/restore runs. Remove the alpha bar from HsvColorPicker so alpha is driven by standalone Slider_AlbedoAlpha / Slider_EmissionAlpha bindings; the picker now writes RGB only and the sliders write alpha only, with no feedback between them. Add a generic SliderCurve component that reshapes a slider's handle position into a non-linear value (with an inverse for setting values back), and make the slider wiring curve-aware. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
fe8f12b8bb
commit
057c99fa1d
7 files changed
+313
-128
No files matched your search
@@ -60,6 +60,16 @@ public partial class PaintHud
|
||||
private bool _hasPendingCamo;
|
||||
private bool _camoEverReady;
|
||||
|
||||
// Authored defaults for the runtime reset (= "as if the saved layout file had been deleted"): the
|
||||
// prefab's panel positions, captured before any saved layout is restored over them, and the painter's
|
||||
// prefab/material default brush values, captured before carry/restore mutate the live painter. Camo is
|
||||
// material-backed (readable only once IsReady), so it is filled in the LateUpdate ready-gate instead.
|
||||
private readonly Dictionary<string, Vector2> _authoredPanelPos = new Dictionary<string, Vector2>();
|
||||
private bool _hasAuthoredLayout;
|
||||
private readonly HudValues _defaults = new HudValues();
|
||||
private bool _hasDefaults; // non-camo defaults captured (first bind, before restore/carry)
|
||||
private bool _hasDefaultCamo; // camo defaults captured (first ready-gate, before any pending camo apply)
|
||||
|
||||
private static string HudSaveDir => Path.Combine(Application.persistentDataPath, "MeshPaint");
|
||||
|
||||
private string HudSavePath()
|
||||
@@ -211,6 +221,17 @@ public partial class PaintHud
|
||||
// save file) the material keeps its authored camo and the sliders just reflect it.
|
||||
if (!_camoSynced && painter.IsReady)
|
||||
{
|
||||
// Capture the material's authored camo as the reset default BEFORE any pending (restored or
|
||||
// carried) camo is applied over it. Once per HUD: a later session/respawn keeps the very
|
||||
// first authored value, so a reset always returns to the genuine material default.
|
||||
if (!_hasDefaultCamo)
|
||||
{
|
||||
_defaults.camoHalfLambert = painter.CamoHalfLambert;
|
||||
_defaults.camoHalfLambertBrightness = painter.CamoHalfLambertBrightness;
|
||||
_defaults.camoSpecularDampen = painter.CamoSpecularDampen;
|
||||
_hasDefaultCamo = true;
|
||||
}
|
||||
|
||||
if (_hasPendingCamo)
|
||||
{
|
||||
painter.CamoHalfLambert = _pendingCamo.x;
|
||||
@@ -402,6 +423,80 @@ public partial class PaintHud
|
||||
}
|
||||
}
|
||||
|
||||
// --- Reset to authored defaults (drives the HUD's reset button) ---
|
||||
|
||||
/// <summary>
|
||||
/// Snapshots the authored panel positions from the freshly instantiated layout, before any saved
|
||||
/// layout is restored over them. The runtime reset restores exactly these. Called once from Start
|
||||
/// (right after the layout prefab is instantiated); idempotent.
|
||||
/// </summary>
|
||||
public void CaptureAuthoredLayout()
|
||||
{
|
||||
if (_hasAuthoredLayout || !_panel) return;
|
||||
var root = _panel.transform;
|
||||
foreach (var name in DraggablePanels)
|
||||
if (FindDeep(root, name) is RectTransform rt)
|
||||
_authoredPanelPos[name] = rt.anchoredPosition;
|
||||
_hasAuthoredLayout = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Snapshots the painter's prefab-default brush values on the first bind, before carry/restore mutate
|
||||
/// the live painter. Non-camo only here (a freshly spawned painter holds its prefab defaults); the
|
||||
/// material-backed camo is not readable yet and is captured later in the LateUpdate ready-gate.
|
||||
/// </summary>
|
||||
private void CaptureDefaults()
|
||||
{
|
||||
if (_hasDefaults || !painter) return;
|
||||
CopyValues(painter, _defaults); // CopyValues skips camo until IsReady -> camo stays for the ready-gate
|
||||
_hasDefaults = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the HUD to its authored defaults, exactly as if the saved layout file had been deleted: the
|
||||
/// panels jump back to their prefab positions and every brush value returns to the painter's prefab /
|
||||
/// material defaults. The save file is deleted too, so the reset also survives the next start.
|
||||
/// </summary>
|
||||
[ContextMenu("Reset HUD Layout And Values")]
|
||||
public void ResetHudToDefaults()
|
||||
{
|
||||
// Delete the saved layout so a restart opens at the authored defaults as well (the literal intent).
|
||||
ClearSavedHudState();
|
||||
|
||||
// Panels -> authored prefab positions.
|
||||
if (_panel && _hasAuthoredLayout)
|
||||
{
|
||||
var root = _panel.transform;
|
||||
foreach (var kv in _authoredPanelPos)
|
||||
if (FindDeep(root, kv.Key) is RectTransform rt)
|
||||
rt.anchoredPosition = kv.Value;
|
||||
}
|
||||
|
||||
// Brush values -> painter prefab/material defaults, then push them to every widget.
|
||||
if (painter && _hasDefaults)
|
||||
{
|
||||
// Reset clicked before the ready-gate captured the camo defaults? keep the live camo rather than
|
||||
// slamming it to the not-yet-filled 0 (which would flatten the material's lighting).
|
||||
if (!_hasDefaultCamo && painter.IsReady)
|
||||
{
|
||||
_defaults.camoHalfLambert = painter.CamoHalfLambert;
|
||||
_defaults.camoHalfLambertBrightness = painter.CamoHalfLambertBrightness;
|
||||
_defaults.camoSpecularDampen = painter.CamoSpecularDampen;
|
||||
}
|
||||
|
||||
ApplyValues(painter, _defaults);
|
||||
SyncFromPainter();
|
||||
SyncCamoSliders();
|
||||
|
||||
// ApplyValues wrote the camo straight to the material (painter is ready at a runtime reset), so
|
||||
// drop any still-pending restored camo the ready-gate would otherwise re-apply over the default.
|
||||
_hasPendingCamo = false;
|
||||
|
||||
CaptureCarry(); // a later respawn now carries the defaults, not the pre-reset values
|
||||
SnapshotSavedBaseline(); // values match the (now deleted) save -> the reset itself triggers no auto-save
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Deletes the saved HUD layout (next start opens at the authored layout / defaults). Editor convenience.</summary>
|
||||
[ContextMenu("Clear Saved HUD Layout")]
|
||||
public void ClearSavedHudState()
|
||||
|
||||
Reference in new issue
Block a user