Passenger/driver sit still in moving cars: seat pose sent relative to the vehicle (backward-compatible), no backward pull; remote cars/traffic extrapolate in physics time and interpolate; UI polish (shadows, borders, gradient buttons, server list hover, fill bars, colored ping)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Nico Meister
2026-09-28 20:52:56 +02:00
co-authored by Claude Opus 5.5
parent 33a415139b
commit ce2fbdfc10
11 changed files with 274 additions and 24 deletions
+41
View File
@@ -49,6 +49,12 @@ namespace MSCO
Quaternion targetViewRot = Quaternion.identity;
PlayerState last;
// Fahrzeug, in dem die Figur sitzt (setzt der Manager jedes Frame; null = läuft frei)
public Transform Seat;
Transform lastSeat;
Vector3 seatHead;
Quaternion seatView = Quaternion.identity;
Vector3 lastPosition;
float walkPhase, walkAmount, speed;
float airAmount; // 0 = steht am Boden, 1 = in der Luft (Sprung, Fallen)
@@ -258,6 +264,15 @@ namespace MSCO
public void Tick(float dt)
{
if (Seat != null && last.SeatId != 0)
{
TickSeated(dt);
UpdateWalk(dt);
Pose(dt);
return;
}
lastSeat = null;
// Bei großen Sprüngen (Teleport, Laden) direkt setzen statt gleiten
bool snap = (transform.position - targetFeet).sqrMagnitude > 100f;
float t = snap ? 1f : Mathf.Clamp01(dt * Smoothing);
@@ -273,6 +288,32 @@ namespace MSCO
Pose(dt);
}
/// <summary>
/// Im Fahrzeug: relativ zum Fahrzeug glätten und jedes Frame an dessen aktuelle Lage setzen. In Weltkoordinaten
/// hinkt die Figur einem fahrenden Auto um Tempo / Glättung hinterher (bei 90 km/h fast 2 m) und ruckelt.
/// </summary>
void TickSeated(float dt)
{
bool fresh = lastSeat != Seat; // gerade eingestiegen: direkt auf den Sitz
lastSeat = Seat;
float t = fresh ? 1f : Mathf.Clamp01(dt * Smoothing);
seatHead = Vector3.Lerp(seatHead, last.SeatHead, t);
seatView = Quaternion.Slerp(seatView, last.SeatView, t);
Vector3 up = Seat.up;
Quaternion viewRot = Seat.rotation * seatView;
Vector3 forward = viewRot * Vector3.forward;
Vector3 flat = forward - up * Vector3.Dot(forward, up);
if (flat.sqrMagnitude < 0.0001f) flat = Seat.forward;
headWorld = Seat.TransformPoint(seatHead);
transform.rotation = Quaternion.LookRotation(flat, up); // neigt sich mit dem Auto (Berg, Kurve)
transform.position = headWorld - up * 1.2f;
pitch = Mathf.Clamp(-Mathf.Asin(Mathf.Clamp(Vector3.Dot(forward.normalized, up), -1f, 1f)) * Mathf.Rad2Deg, -MaxHeadPitch, MaxHeadPitch);
view.position = headWorld;
view.rotation = viewRot;
}
void UpdateWalk(float dt)
{
Vector3 moved = transform.position - lastPosition;