Add Cinemachine third-person orbit camera and fix paint raycast
- Install Cinemachine 3.1.7 and set up an orbital third-person camera rig (CinemachineBrain, OrbitalFollow, RotationComposer, Deoccluder). - Add ThirdPersonOrbitInput: mouse-driven orbit and wheel zoom with a Tab toggle that unlocks the cursor and pauses rotation. - Fix MeshPainter so the paint ray skips the player's CharacterController capsule (and any other collider) and always targets the mesh collider, so painting works from every camera angle. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
792c8c964f
commit
6e8ab4bc6d
6 files changed
+545
-10
No files matched your search
@@ -89,6 +89,7 @@ public class MeshPainter : MonoBehaviour
|
||||
private int[] _fillStamp; // transient marker for padding texels per dilation call
|
||||
private int _dilateStamp; // incremented per call -> padding from previous frames does not count as a source
|
||||
private readonly List<int> _dilateScratch = new List<int>(512);
|
||||
private readonly RaycastHit[] _rayHits = new RaycastHit[32]; // buffer so other colliders (player capsule, etc.) cannot block painting
|
||||
private int _dx0, _dy0, _dx1, _dy1; // dirty rectangle (CPU upload)
|
||||
|
||||
// --- GPU backend ---
|
||||
@@ -480,8 +481,27 @@ public class MeshPainter : MonoBehaviour
|
||||
private void PaintAtScreen(Vector2 screenPos)
|
||||
{
|
||||
Ray ray = paintCamera.ScreenPointToRay(screenPos);
|
||||
if (!(Physics.Raycast(ray, out RaycastHit hit, 1000f) && hit.collider == _collider))
|
||||
return;
|
||||
|
||||
// Collect all hits and pick the nearest one that belongs to the paint mesh.
|
||||
// A plain Physics.Raycast returns only the closest collider, so anything in
|
||||
// front of the mesh (the player's CharacterController capsule, future props,
|
||||
// the camera-collision proxy) would block painting. Filtering by collider
|
||||
// keeps painting working from every camera angle.
|
||||
int hitCount = Physics.RaycastNonAlloc(ray, _rayHits, 1000f, ~0, QueryTriggerInteraction.Ignore);
|
||||
RaycastHit hit = default;
|
||||
float nearest = float.MaxValue;
|
||||
bool found = false;
|
||||
for (int i = 0; i < hitCount; i++)
|
||||
{
|
||||
if (_rayHits[i].collider != _collider) continue;
|
||||
if (_rayHits[i].distance < nearest)
|
||||
{
|
||||
nearest = _rayHits[i].distance;
|
||||
hit = _rayHits[i];
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (!found) return;
|
||||
if (_verts == null || hit.triangleIndex < 0) return;
|
||||
|
||||
// Bring the hit point into local mesh space (= collider/vertex space).
|
||||
|
||||
Reference in new issue
Block a user