diff --git a/RemotePlayer.cs b/RemotePlayer.cs index 90cd1e1..735e2e7 100644 --- a/RemotePlayer.cs +++ b/RemotePlayer.cs @@ -16,7 +16,7 @@ namespace MSCO const float MaxHeadPitch = 55f; // Körpermaße (Meter) - const float ThighLength = 0.45f, ShinLength = 0.45f; + const float ThighLength = 0.41f, ShinLength = 0.41f; // im Stehen fast gestreckt const float UpperArmLength = 0.3f, ForearmLength = 0.29f; const float TorsoLength = 0.55f; // Hüfte bis Hals const float HipWidth = 0.1f, ShoulderWidth = 0.21f; @@ -88,9 +88,9 @@ namespace MSCO // Körper: Karohemd/Jacke, Jeans, Gürtel, leichter Bauch (wie die Leute in MSC) pelvis = Capsule("Pelvis", r, Jeans); - torso = Textured(Capsule("Torso", r, Color.white), plaid, new Vector2(2f, 3f)); - belly = Textured(Sphere("Belly", r, Color.white, 1f), plaid, new Vector2(2f, 2f)); - belt = Capsule("Belt", r, new Color(0.2f, 0.13f, 0.08f)); + torso = Textured(Capsule("Chest", r, Color.white), plaid, new Vector2(2f, 2f)); + belly = Textured(Capsule("Belly", r, Color.white), plaid, new Vector2(2f, 1f)); + belt = Box("Belt", r, new Color(0.2f, 0.13f, 0.08f)); buckle = Box("Buckle", r, Metal); placket = Box("Buttons", r, jacketDark); collar = Capsule("Collar", r, jacketDark); @@ -112,55 +112,55 @@ namespace MSCO headPivot = new GameObject("Head").transform; headPivot.SetParent(r, false); Transform skull = Sphere("Skull", headPivot, Skin, 0.24f); - skull.localScale = new Vector3(0.21f, 0.255f, 0.235f); + skull.localScale = new Vector3(0.225f, 0.27f, 0.25f); Transform jaw = Sphere("Jaw", headPivot, Skin, 0.2f); - jaw.localPosition = new Vector3(0f, -0.065f, 0.02f); - jaw.localScale = new Vector3(0.18f, 0.13f, 0.19f); + jaw.localPosition = new Vector3(0f, -0.07f, 0.022f); + jaw.localScale = new Vector3(0.19f, 0.14f, 0.2f); Transform hair = Sphere("Hair", headPivot, hairColor, 0.24f); - hair.localPosition = new Vector3(0f, 0.025f, -0.03f); - hair.localScale = new Vector3(0.22f, 0.24f, 0.22f); + hair.localPosition = new Vector3(0f, 0.028f, -0.032f); + hair.localScale = new Vector3(0.235f, 0.255f, 0.235f); for (int i = 0; i < 2; i++) { float side = i == 0 ? -1f : 1f; Transform ear = Sphere("Ear", headPivot, Skin * 0.96f, 0.05f); - ear.localPosition = new Vector3(side * 0.105f, -0.005f, 0f); + ear.localPosition = new Vector3(side * 0.112f, -0.005f, 0f); ear.localScale = new Vector3(0.035f, 0.065f, 0.05f); - Transform eye = Sphere("Eye", headPivot, Dark, 0.028f); - eye.localPosition = new Vector3(side * 0.042f, 0.018f, 0.105f); + Transform eye = Sphere("Eye", headPivot, Dark, 0.026f); + eye.localPosition = new Vector3(side * 0.045f, 0.018f, 0.112f); Transform brow = Box("Brow", headPivot, hairColor); - brow.localPosition = new Vector3(side * 0.043f, 0.045f, 0.108f); + brow.localPosition = new Vector3(side * 0.046f, 0.046f, 0.117f); brow.localScale = new Vector3(0.045f, 0.012f, 0.012f); brow.localRotation = Quaternion.Euler(0f, 0f, side * -8f); } Transform nose = Box("Nose", headPivot, Skin * 0.93f); - nose.localPosition = new Vector3(0f, -0.012f, 0.12f); + nose.localPosition = new Vector3(0f, -0.012f, 0.128f); nose.localScale = new Vector3(0.035f, 0.055f, 0.045f); // Der typische Schnurrbart Transform mustache = Box("Mustache", headPivot, hairColor); - mustache.localPosition = new Vector3(0f, -0.052f, 0.113f); + mustache.localPosition = new Vector3(0f, -0.054f, 0.12f); mustache.localScale = new Vector3(0.085f, 0.024f, 0.03f); Transform mouth = Box("Mouth", headPivot, new Color(0.45f, 0.25f, 0.22f)); - mouth.localPosition = new Vector3(0f, -0.078f, 0.108f); + mouth.localPosition = new Vector3(0f, -0.082f, 0.114f); mouth.localScale = new Vector3(0.05f, 0.01f, 0.01f); if (sunglasses) { Transform glasses = Box("Sunglasses", headPivot, Dark); - glasses.localPosition = new Vector3(0f, 0.018f, 0.113f); - glasses.localScale = new Vector3(0.14f, 0.035f, 0.012f); + glasses.localPosition = new Vector3(0f, 0.018f, 0.121f); + glasses.localScale = new Vector3(0.15f, 0.035f, 0.012f); } if (wearsCap) { // Kappe ("lippis") in der Jackenfarbe Transform cap = Sphere("Cap", headPivot, jacketDark, 0.25f); - cap.localPosition = new Vector3(0f, 0.075f, -0.005f); - cap.localScale = new Vector3(0.235f, 0.15f, 0.245f); + cap.localPosition = new Vector3(0f, 0.08f, -0.005f); + cap.localScale = new Vector3(0.25f, 0.16f, 0.26f); Transform brim = Box("CapBrim", headPivot, jacketDark); - brim.localPosition = new Vector3(0f, 0.078f, 0.13f); - brim.localScale = new Vector3(0.19f, 0.018f, 0.11f); - brim.localRotation = Quaternion.Euler(-10f, 0f, 0f); + brim.localPosition = new Vector3(0f, 0.07f, 0.15f); + brim.localScale = new Vector3(0.2f, 0.014f, 0.1f); + brim.localRotation = Quaternion.Euler(8f, 0f, 0f); // Schirm leicht nach unten Transform patch = Box("CapPatch", headPivot, new Color(0.9f, 0.88f, 0.8f)); - patch.localPosition = new Vector3(0f, 0.105f, 0.112f); + patch.localPosition = new Vector3(0f, 0.115f, 0.118f); patch.localScale = new Vector3(0.06f, 0.035f, 0.01f); patch.localRotation = Quaternion.Euler(-25f, 0f, 0f); } @@ -220,6 +220,9 @@ namespace MSCO Destroy(go.GetComponent()); // stört sonst Physik/Trigger var renderer = go.GetComponent(); renderer.material.color = color; + // Matt wie Stoff/Haut statt glänzendem Plastik (Standard-Shader) + if (renderer.material.HasProperty("_Glossiness")) renderer.material.SetFloat("_Glossiness", 0.08f); + if (renderer.material.HasProperty("_Metallic")) renderer.material.SetFloat("_Metallic", 0f); renderer.receiveShadows = true; go.transform.SetParent(parent, false); return go.transform; @@ -306,18 +309,19 @@ namespace MSCO // Rumpf Quaternion torsoRot = Quaternion.LookRotation(forward, up); - Segment(torso, hip + up * 0.08f, neckBase, 0.4f, 0.25f); - belly.localPosition = hip + up * 0.2f + forward * 0.06f; - belly.localRotation = torsoRot; - belly.localScale = new Vector3(0.34f, 0.28f, 0.27f); - Segment(belt, hip + up * 0.05f, hip + up * 0.1f, 0.38f, 0.26f); - buckle.localPosition = hip + up * 0.075f + forward * 0.13f; + // Brust (breit oben) und Bauch (etwas tiefer = leichter Bauch) - fließend statt Klotz mit Kugel + Segment(torso, hip + up * 0.26f, neckBase - up * 0.04f, 0.37f, 0.22f); + Segment(belly, hip + up * 0.07f + forward * 0.015f, hip + up * 0.3f + forward * 0.015f, 0.33f, 0.25f); + belt.localPosition = hip + up * 0.06f; + belt.localRotation = torsoRot; + belt.localScale = new Vector3(0.345f, 0.045f, 0.275f); + buckle.localPosition = hip + up * 0.06f + forward * 0.14f; buckle.localRotation = torsoRot; - buckle.localScale = new Vector3(0.06f, 0.045f, 0.015f); - placket.localPosition = Vector3.Lerp(hip + up * 0.1f, neckBase, 0.62f) + forward * 0.122f; + buckle.localScale = new Vector3(0.055f, 0.04f, 0.012f); + placket.localPosition = Vector3.Lerp(hip + up * 0.12f, neckBase, 0.6f) + forward * 0.124f; placket.localRotation = torsoRot; - placket.localScale = new Vector3(0.025f, 0.26f, 0.01f); - Segment(pelvis, hip - right * HipWidth, hip + right * HipWidth, 0.22f, 0.24f); + placket.localScale = new Vector3(0.022f, 0.3f, 0.01f); + Segment(pelvis, hip - right * (HipWidth * 0.8f) - up * 0.02f, hip + right * (HipWidth * 0.8f) - up * 0.02f, 0.2f, 0.22f); Segment(collar, neckBase - up * 0.02f, neckBase + up * 0.035f, 0.17f, 0.15f); Segment(neck, neckBase, neckTop, 0.1f, 0.1f); @@ -339,8 +343,8 @@ namespace MSCO else ankle = new Vector3(HipWidth * side, AnkleHeight + Mathf.Max(0f, Mathf.Cos(walkPhase + i * Mathf.PI)) * 0.07f * walkAmount, phase * 0.3f); Vector3 knee = Joint(hipJoint, ankle, ThighLength, ShinLength, Vector3.forward); - Segment(thigh[i], hipJoint, knee, 0.17f, 0.17f); - Segment(shin[i], knee, ankle, 0.14f, 0.14f); + Segment(thigh[i], hipJoint, knee, 0.15f, 0.16f); + Segment(shin[i], knee, ankle, 0.12f, 0.13f); boot[i].localPosition = ankle + new Vector3(0f, -0.015f, 0.05f); boot[i].localRotation = Quaternion.identity; boot[i].localScale = new Vector3(0.12f, 0.1f, 0.27f); @@ -358,7 +362,7 @@ namespace MSCO else if (last.Seated) handTarget = shoulder + new Vector3(-side * 0.05f, -0.3f, 0.38f); // Hände nach vorne (Lenkrad) else - handTarget = shoulder + new Vector3(side * 0.03f, -(UpperArmLength + ForearmLength) + 0.04f, -phase * 0.22f); + handTarget = shoulder + new Vector3(side * 0.06f, -(UpperArmLength + ForearmLength) + 0.05f, 0.02f - phase * 0.22f); // Nicht weiter als die Armlänge Vector3 reach = handTarget - shoulder; @@ -366,12 +370,12 @@ namespace MSCO if (reach.magnitude > maxReach) handTarget = shoulder + reach.normalized * maxReach; Vector3 elbow = Joint(shoulder, handTarget, UpperArmLength, ForearmLength, new Vector3(side * 0.4f, -0.2f, -1f)); - Segment(upperArm[i], shoulder, elbow, 0.12f, 0.12f); - Segment(forearm[i], elbow, handTarget, 0.11f, 0.11f); - Vector3 wrist = Vector3.Lerp(elbow, handTarget, 0.86f); - Segment(cuff[i], wrist, Vector3.Lerp(elbow, handTarget, 0.94f), 0.12f, 0.12f); + Segment(upperArm[i], shoulder, elbow, 0.11f, 0.11f); + Segment(forearm[i], elbow, handTarget, 0.095f, 0.095f); + Segment(cuff[i], Vector3.Lerp(elbow, handTarget, 0.82f), Vector3.Lerp(elbow, handTarget, 0.9f), 0.105f, 0.105f); hand[i].localPosition = handTarget; - hand[i].localScale = new Vector3(0.085f, 0.1f, 0.1f); + hand[i].localRotation = Quaternion.LookRotation(Vector3.forward, (handTarget - elbow).sqrMagnitude > 0f ? elbow - handTarget : Vector3.up); + hand[i].localScale = new Vector3(0.075f, 0.115f, 0.1f); } } diff --git a/VehicleStateSync.cs b/VehicleStateSync.cs index 0e978af..ac81ab9 100644 --- a/VehicleStateSync.cs +++ b/VehicleStateSync.cs @@ -74,11 +74,16 @@ namespace MSCO outgoing.Clear(); foreach (Var v in vars.Values) { - if (!Changed(v)) continue; - Remember(v); - // Fährt/schiebt ein anderer das Fahrzeug, ist seine Version maßgeblich + // Fährt/schiebt ein anderer das Fahrzeug, ist seine Version maßgeblich - nichts senden int owner = objects.VehicleOwner(v.Root); - if (owner == SyncedBody.NoOwner || owner == localId) outgoing.Add(v); + if (owner != SyncedBody.NoOwner && owner != localId) { if (Changed(v, false)) Remember(v); continue; } + + // Eigenes Fahrzeug: jede Änderung. Freies Fahrzeug: nur deutliche Sprünge (Öl nachfüllen, tanken ...) - + // langsames Abdriften (z.B. Abkühlen) rechnet jeder selbst, sonst überschreiben sich alle gegenseitig + bool big = owner == SyncedBody.NoOwner; + if (!Changed(v, big)) continue; + Remember(v); + outgoing.Add(v); } for (int start = 0; start < outgoing.Count; start += MaxPerMessage) @@ -176,13 +181,16 @@ namespace MSCO return false; } - static bool Changed(Var v) + static bool Changed(Var v, bool bigOnly) { switch (v.Type) { case 1: float f = ((FsmFloat)v.Variable).Value; - return Mathf.Abs(f - v.LastF) > Mathf.Max(0.01f, Mathf.Abs(v.LastF) * 0.002f); + float delta = Mathf.Abs(f - v.LastF); + return bigOnly + ? delta > Mathf.Max(0.5f, Mathf.Abs(v.LastF) * 0.05f) + : delta > Mathf.Max(0.01f, Mathf.Abs(v.LastF) * 0.002f); case 2: return ((FsmInt)v.Variable).Value != v.LastI; default: return ((FsmBool)v.Variable).Value != v.LastB; }