Refactor scripts: dedup remainder, remove dead code, perf hardening

Iteration 4 over Assets/Scripts (no component/file splits, no Unity assets touched):

Dedup:
- Route inline cursor-release, material guards, Ctrl-held and undo/redo
  input through existing InputUtil / SetMatFloat helpers
- Add ungated InputUtil.KeyPressedThisFrame; GameplayKeyPressed builds on it
- Unify FindDeep/FindDeepChild into GeometryUtil.FindDeep

Dead code / stale docs:
- Remove unused code-gen bake path (HsvColorPicker.Build, PaintHud factory)
- Drop unreferenced symbols (SubPhaseChanged event, LocalPhaseDuration,
  IsLocalSceneMain, MouseSensitivity.Changed, IsPaused, InSession,
  NetworkControlled, PreviousPose, JointCount, voxel-count accessors)
- Fix incorrect PlayerRole / PaintHud / Pick / PlayerPose docs

Perf / robustness (behaviour-neutral):
- ConcealmentMeter.Evaluate: reuse vertex/topology buffers, two-pointer
  crossing count
- BuildMeshCaches: alloc-free vertex copy, cached topology/UVs
- Guard all PlayerPaintSync LogSync sites behind logSync
- Cache LocalViewerIsHunter / controller / CanShoot / TypingGuard lookups;
  dedup LocalIsHunter with MatchHud
- Change-guard RefreshEmissionColor and HeroCutout.Disarm
- Cache scene/countdown string comparisons per frame
- Grow NonAlloc buffers and log-once on saturation

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 4.8 committed 2026-07-02 13:33:18 +02:00
1 parent 2243cc823e
commit 382bfb36df
32 files changed
+292 -348

No files matched your search

+25 -19
View File
@@ -7,7 +7,7 @@ using UnityEngine;
/// Each evaluation bakes the character's current (deformed) skinned mesh, voxelizes its
/// SOLID volume, and reports what fraction of that volume sits INSIDE environment colliders
/// (= embedded / hidden) versus exposed. <see cref="EmbeddedPercent"/> is the headline value,
/// <see cref="VisiblePercent"/> its complement.
/// <see cref="visiblePercent"/> its complement.
///
/// Pipeline:
/// 1. <see cref="SkinnedMeshRenderer.BakeMesh(Mesh)"/> -> mesh in the renderer's LOCAL space, then the
@@ -66,15 +66,15 @@ public class ConcealmentMeter : MonoBehaviour
/// <summary>Percentage [0..100] of the character's solid volume embedded inside environment colliders.</summary>
public float EmbeddedPercent { get; private set; }
public float visiblePercent;
public float visiblePercent; // Inspector debug readout (complement of EmbeddedPercent)
public int InteriorVoxelCount { get; private set; }
public int EmbeddedVoxelCount { get; private set; }
public bool HasResult { get; private set; }
private Mesh _baked;
private Vector3[] _verts;
private int[] _tris;
private readonly List<Vector3> _verts = new List<Vector3>(); // refilled per eval without allocating
private int[] _tris; // topology is invariant across bakes of the same renderer -> fetched once
private int _trisVertexCount = -1; // vertex count _tris was fetched for (detects a renderer/mesh swap)
private bool _overlapSaturated; // log-once guard for a saturated broadphase buffer
private float _timer;
private readonly List<Vector3> _vbuf = new List<Vector3>(); // reused scale-fixup scratch; nothing allocated per eval
@@ -133,9 +133,16 @@ public class ConcealmentMeter : MonoBehaviour
// player's uniform scale guarantees. Mirrors SkinnedColliderBaker's identical fixup.
GeometryUtil.RescaleToUnitScale(_baked, targetRenderer.transform.lossyScale, _vbuf);
_verts = _baked.vertices;
_tris = _baked.triangles;
if (_verts.Length == 0 || _tris.Length < 3) return;
// mesh.vertices/.triangles return fresh arrays per call - at 10 evals/s that is steady GC
// pressure. Vertices go into a reused list; the (bake-invariant) index buffer is fetched only
// when the source mesh actually changed.
_baked.GetVertices(_verts);
if (_tris == null || _trisVertexCount != _baked.vertexCount)
{
_tris = _baked.triangles;
_trisVertexCount = _baked.vertexCount;
}
if (_verts.Count == 0 || _tris.Length < 3) return;
Bounds lb = _baked.bounds; // local-space AABB of the baked pose
Vector3 size = lb.size;
@@ -175,16 +182,13 @@ public class ConcealmentMeter : MonoBehaviour
if (col == null || col.Count < 2) continue;
col.Sort();
// col is sorted and cy grows monotonically with iy, so a single running index
// replaces a from-scratch scan per voxel: O(ny + crossings) per column.
int below = 0;
for (int iy = 0; iy < ny; iy++)
{
float cy = origin.y + (iy + 0.5f) * voxel;
int below = 0;
for (int k = 0; k < col.Count; k++)
{
if (col[k] <= cy) below++;
else break; // sorted ascending
}
while (below < col.Count && col[below] <= cy) below++;
if ((below & 1) == 0) continue; // even crossings below -> outside the solid
interior++;
@@ -203,8 +207,6 @@ public class ConcealmentMeter : MonoBehaviour
}
}
InteriorVoxelCount = interior;
EmbeddedVoxelCount = embedded;
EmbeddedPercent = interior > 0 ? 100f * embedded / interior : 0f;
visiblePercent = 100 - EmbeddedPercent;
HasResult = true;
@@ -285,7 +287,11 @@ public class ConcealmentMeter : MonoBehaviour
int n = Physics.OverlapBoxNonAlloc(wb.center, wb.extents, _overlap, Quaternion.identity,
environmentMask, QueryTriggerInteraction.Ignore);
if (n > _overlap.Length) n = _overlap.Length;
if (n == _overlap.Length && !_overlapSaturated)
{
_overlapSaturated = true; // silently dropped colliders would skew EmbeddedPercent low
Debug.LogWarning($"ConcealmentMeter: broadphase buffer saturated ({n}); environment colliders may be missed.", this);
}
for (int i = 0; i < n; i++)
{