2.8: sync bought/consumed items, wheel spin, crash damage, jobs/shop, traffic
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+102
@@ -0,0 +1,102 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MSCO
|
||||
{
|
||||
/// <summary>
|
||||
/// Räder an Fahrzeugen, die ein anderer Spieler fährt, drehen sich mit. Bei uns wird so ein Auto nur verschoben
|
||||
/// (kinematisch), die Rad-Physik des Spiels (CarDynamics "Wheel") dreht die Räder dann nicht. Wir drehen das
|
||||
/// Rad-Modell passend zur Geschwindigkeit um seine Achse - nach dem Spiel (LateUpdate), ohne dessen Werte zu ändern.
|
||||
/// </summary>
|
||||
public class WheelSpin
|
||||
{
|
||||
const float CacheRefresh = 5f; // Räder können ab-/angebaut werden
|
||||
|
||||
class WheelInfo
|
||||
{
|
||||
public Transform Model;
|
||||
public Transform Hub; // Transform der Wheel-Komponente (Fahrtrichtung)
|
||||
public float Radius;
|
||||
public float Angle;
|
||||
public Quaternion Base; // Drehung ohne unsere Rollbewegung
|
||||
public Quaternion Written; // zuletzt von uns gesetzt
|
||||
public bool HasWritten;
|
||||
}
|
||||
|
||||
class Vehicle
|
||||
{
|
||||
public float BuiltAt;
|
||||
public readonly List<WheelInfo> Wheels = new List<WheelInfo>();
|
||||
}
|
||||
|
||||
readonly Dictionary<int, Vehicle> vehicles = new Dictionary<int, Vehicle>();
|
||||
static System.Type wheelType;
|
||||
static FieldInfo modelField, radiusField;
|
||||
static bool lookedUp;
|
||||
|
||||
public void Reset() { vehicles.Clear(); }
|
||||
|
||||
public void Apply(ObjectSync objects, float dt)
|
||||
{
|
||||
if (!Lookup()) return;
|
||||
List<SyncedBody> driven = objects.RemoteDrivenVehicles();
|
||||
if (driven.Count == 0) { if (vehicles.Count > 0) vehicles.Clear(); return; }
|
||||
|
||||
foreach (SyncedBody b in driven)
|
||||
{
|
||||
Vehicle v;
|
||||
if (!vehicles.TryGetValue(b.Id, out v) || Time.time - v.BuiltAt > CacheRefresh)
|
||||
{
|
||||
v = Build(b.Rb.transform);
|
||||
vehicles[b.Id] = v;
|
||||
}
|
||||
|
||||
Vector3 vel = b.TargetVel;
|
||||
foreach (WheelInfo w in v.Wheels)
|
||||
{
|
||||
if (w.Model == null || w.Hub == null) continue;
|
||||
float speed = Vector3.Dot(vel, w.Hub.forward);
|
||||
w.Angle = Mathf.Repeat(w.Angle + speed / w.Radius * Mathf.Rad2Deg * dt, 360f);
|
||||
|
||||
// Hat das Spiel das Modell in diesem Frame selbst gedreht (z.B. Lenkung), ist das die neue Basis
|
||||
Quaternion current = w.Model.localRotation;
|
||||
if (!w.HasWritten || current != w.Written) w.Base = current;
|
||||
w.Written = w.Base * Quaternion.Euler(w.Angle, 0f, 0f);
|
||||
w.Model.localRotation = w.Written;
|
||||
w.HasWritten = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Vehicle Build(Transform root)
|
||||
{
|
||||
var v = new Vehicle { BuiltAt = Time.time };
|
||||
foreach (Component c in root.GetComponentsInChildren(wheelType, true))
|
||||
{
|
||||
var model = modelField.GetValue(c) as GameObject;
|
||||
float radius = radiusField != null ? (float)radiusField.GetValue(c) : 0.3f;
|
||||
if (model == null || radius < 0.05f || radius > 2f) continue;
|
||||
v.Wheels.Add(new WheelInfo { Model = model.transform, Hub = c.transform, Radius = radius });
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static bool Lookup()
|
||||
{
|
||||
if (lookedUp) return wheelType != null;
|
||||
lookedUp = true;
|
||||
foreach (Assembly a in System.AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
if (a.GetName().Name != "Assembly-CSharp") continue;
|
||||
wheelType = a.GetType("Wheel");
|
||||
break;
|
||||
}
|
||||
if (wheelType == null) { MscoLog.Warning("[MSCO] Wheel type not found - remote wheels will not spin"); return false; }
|
||||
modelField = wheelType.GetField("model", BindingFlags.Public | BindingFlags.Instance);
|
||||
radiusField = wheelType.GetField("radius", BindingFlags.Public | BindingFlags.Instance);
|
||||
if (modelField == null) { wheelType = null; return false; }
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user