feat: Camo/Height/Emission-Slider nicht mehr persistieren

Die 8 HUD-Slider (Half Lambert, Brightness, Saturation, Specular Damp,
Occlusion Threshold, Normal/Parallax/Emission Intensity) als
[NonSerialized] markiert: bleiben zur Laufzeit ueber Respawn erhalten,
werden aber nicht mehr im PaintHud.json gespeichert/geladen. Tote
hasCamoValues/hasHeightValues-Flags entfernt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 4.8 committed 2026-07-15 08:29:25 +02:00
1 parent 0128203160
commit c7e3b6cad7
1 file changed
+13 -29
@@ -70,8 +70,6 @@ public partial class PaintHud
{
public int version = HudFileVersion;
public bool hasValues; // false = no painter was bound when saved -> restore positions only
public bool hasCamoValues; // false = pre-camo save file -> keep the material's authored camo (no clobber)
public bool hasHeightValues; // false = pre-height save file -> keep the material's authored height knobs (no clobber)
public List<PanelPos> panels = new List<PanelPos>();
public HudValues values = new HudValues();
}
@@ -91,14 +89,19 @@ public partial class PaintHud
public Color brushColor;
public float metallic, smoothness, metallicSmoothnessOpacity, occlusion, occlusionOpacity;
public Color emissionColor;
public float emissionIntensity;
public float furLength;
public int brushSize;
public int activeBrushIndex;
public int sprayDots;
public float sprayDotSizeMin, sprayDotSizeMax, sprayDotAlphaMin, sprayDotAlphaMax;
public float camoHalfLambert, camoHalfLambertBrightness, camoSpecularDampen, camoSaturation; // PlayerCamoLit material knobs
public float occlusionThreshold, heightNormalIntensity, parallaxIntensity; // painted-height knobs (material-backed)
// [NonSerialized] = these ride the in-memory _carry (survive the respawn a scene switch triggers)
// but are deliberately kept OUT of the JSON save file: JsonUtility skips NonSerialized fields on
// both write and read, so they are never persisted and reset to the prefab/material defaults each
// session. The restore path below also skips applying them (they load back as 0).
[NonSerialized] public float emissionIntensity;
[NonSerialized] public float camoHalfLambert, camoHalfLambertBrightness, camoSpecularDampen, camoSaturation; // PlayerCamoLit material knobs
[NonSerialized] public float occlusionThreshold, heightNormalIntensity, parallaxIntensity; // painted-height knobs (material-backed)
}
/// <summary>A draggable panel was dropped -> persist the layout immediately.</summary>
@@ -124,16 +127,12 @@ public partial class PaintHud
{
CopyValues(painter, state.values);
state.hasValues = true;
state.hasCamoValues = painter.IsReady; // only claim camo when it was actually readable
state.hasHeightValues = painter.IsReady; // height knobs share the camo readiness
}
else if (_hasCarry)
{
// No painter bound at teardown (e.g. quit with no avatar) -> persist the last mirrored values.
state.values = _carry;
state.hasValues = true;
state.hasCamoValues = _camoEverReady; // _carry holds valid camo only after a ready painter
state.hasHeightValues = _camoEverReady;
}
Directory.CreateDirectory(Application.persistentDataPath);
@@ -164,30 +163,15 @@ public partial class PaintHud
if (painter && state.hasValues && state.values != null)
{
// emissionIntensity + the camo/height knobs are [NonSerialized] -> they load back as 0. Keep the
// painter's authored/prefab default for emissionIntensity (a plain field) instead of the 0, and
// deliberately do NOT stash camo/height from disk below: these values are in-session only (they
// survive respawn via _carry) and must reset to their material defaults each new session.
state.values.emissionIntensity = painter.emissionIntensity;
ApplyValues(painter, state.values);
SyncFromPainter();
}
// Camo is material-backed -> stash for the LateUpdate ready-gate. hasCamoValues guards pre-camo
// save files (applying their 0 would clobber the authored camo).
if (state.hasCamoValues && state.values != null)
{
_pendingCamo = new Vector4(state.values.camoHalfLambert,
state.values.camoHalfLambertBrightness,
state.values.camoSpecularDampen,
state.values.camoSaturation);
_hasPendingCamo = true;
}
// Same deferral + guard for the painted-height knobs.
if (state.hasHeightValues && state.values != null)
{
_pendingHeight = new Vector3(state.values.occlusionThreshold,
state.values.heightNormalIntensity,
state.values.parallaxIntensity);
_hasPendingHeight = true;
}
// Point-anchored panels: anchoredPosition is resolution-independent under the canvas'
// ScaleWithScreenSize scaler, so the raw saved value places them identically next session.
var root = _panel.transform;