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:
co-authored by
Claude Opus 5.5
parent
33a415139b
commit
ce2fbdfc10
+25
-5
@@ -25,6 +25,8 @@ namespace MSCO
|
||||
public int OwnerId = NoOwner;
|
||||
public bool OwnerActive; // Besitzer hält/fährt es gerade aktiv
|
||||
public bool WasKinematic; // Zustand bevor ein anderer Spieler es übernommen hat
|
||||
public RigidbodyInterpolation WasInterpolation;
|
||||
public bool InterpolationSet; // Fahrzeug eines anderen: bei uns interpoliert (siehe FreezeForRemote)
|
||||
// Gelenke der angebauten Teile, solange ein anderer das Fahrzeug fährt: unzerbrechlich (vorherige Bruchkraft/-moment)
|
||||
public Dictionary<Joint, Vector2> HeldJoints;
|
||||
public float NextPartScan;
|
||||
@@ -42,7 +44,7 @@ namespace MSCO
|
||||
public Vector3 TargetPos;
|
||||
public Quaternion TargetRot;
|
||||
public Vector3 TargetVel; // Geschwindigkeit beim Besitzer: damit wird die Position vorausberechnet
|
||||
public float TargetTime; // wann TargetPos ankam
|
||||
public float TargetTime; // wann TargetPos ankam (Physik-Zeit, Time.fixedTime)
|
||||
public float LastRecvTime;
|
||||
public float AvatarHoldTime = -100f; // zuletzt von der Hand eines Mitspielers platziert
|
||||
|
||||
@@ -209,6 +211,8 @@ namespace MSCO
|
||||
|
||||
/// <summary>Fährt der lokale Spieler gerade selbst?</summary>
|
||||
public bool IsDriving { get; private set; }
|
||||
/// <summary>Das Fahrzeug, das der lokale Spieler gerade fährt (sonst null).</summary>
|
||||
public SyncedBody Driven { get; private set; }
|
||||
|
||||
/// <summary>Fahrzeuge, die gerade ein anderer Spieler aktiv fährt.</summary>
|
||||
public List<SyncedBody> RemoteDrivenVehicles()
|
||||
@@ -315,6 +319,7 @@ namespace MSCO
|
||||
|
||||
SyncedBody held = HeldBody();
|
||||
SyncedBody driven = DrivenBody();
|
||||
Driven = driven;
|
||||
IsDriving = driven != null;
|
||||
bool motionClaimAllowed = Time.time - loadTime > MotionClaimGrace;
|
||||
|
||||
@@ -387,7 +392,9 @@ namespace MSCO
|
||||
if (Time.time - b.AvatarHoldTime < 0.2f) continue; // sitzt gerade in der Hand eines Mitspielers
|
||||
// Dort, wo das Objekt beim Besitzer JETZT ungefähr ist: letzte Position + Geschwindigkeit * Alter.
|
||||
// Ohne das hinken schnelle Objekte (fahrende Autos) immer einen Paketabstand hinterher und ruckeln.
|
||||
float age = Mathf.Min(Time.time - b.TargetTime, MaxExtrapolation);
|
||||
// Beides in Physik-Zeit: mit der Bildzeit (Time.time beim Empfang) wurde das Alter in den ersten
|
||||
// Physik-Schritten danach negativ - das Auto sprang bei jedem Paket ein Stück zurück (Ruckeln)
|
||||
float age = Mathf.Clamp(Time.fixedTime - b.TargetTime, 0f, MaxExtrapolation);
|
||||
Vector3 predicted = b.TargetPos + b.TargetVel * age;
|
||||
if ((b.Rb.position - predicted).sqrMagnitude > SnapDistance * SnapDistance)
|
||||
{
|
||||
@@ -489,7 +496,15 @@ namespace MSCO
|
||||
{
|
||||
b.WasKinematic = b.Rb.isKinematic;
|
||||
b.Rb.isKinematic = true;
|
||||
if (b.IsVehicle) HoldParts(b);
|
||||
if (b.IsVehicle)
|
||||
{
|
||||
HoldParts(b);
|
||||
// Physik läuft mit 50 Hz, das Bild öfter: ohne Interpolation springt das Auto nur in Physik-Schritten
|
||||
// weiter - wer darin mitfährt, sieht die Welt ruckeln. Nur bei Fahrzeugen (Items setzt die Hand direkt).
|
||||
b.WasInterpolation = b.Rb.interpolation;
|
||||
b.InterpolationSet = true;
|
||||
b.Rb.interpolation = RigidbodyInterpolation.Interpolate;
|
||||
}
|
||||
}
|
||||
|
||||
void HoldParts(SyncedBody b)
|
||||
@@ -508,7 +523,12 @@ namespace MSCO
|
||||
/// <summary>Wieder selbst simulieren: Auto zurück auf seinen Zustand, Gelenke wieder mit ihrer Bruchkraft.</summary>
|
||||
void RestoreKinematic(SyncedBody b)
|
||||
{
|
||||
if (b.Rb != null) b.Rb.isKinematic = b.WasKinematic;
|
||||
if (b.Rb != null)
|
||||
{
|
||||
b.Rb.isKinematic = b.WasKinematic;
|
||||
if (b.InterpolationSet) b.Rb.interpolation = b.WasInterpolation;
|
||||
}
|
||||
b.InterpolationSet = false;
|
||||
if (b.HeldJoints == null) return;
|
||||
foreach (KeyValuePair<Joint, Vector2> kv in b.HeldJoints)
|
||||
{
|
||||
@@ -580,7 +600,7 @@ namespace MSCO
|
||||
b.TargetPos = pos;
|
||||
b.TargetRot = rot;
|
||||
b.TargetVel = vel.sqrMagnitude < 90f * 90f ? vel : Vector3.zero;
|
||||
b.TargetTime = Time.time;
|
||||
b.TargetTime = Time.fixedTime;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user