Nicer player figure: chest + belly instead of box and ball, bigger head, straight legs, flat belt, cap brim down, matte materials; free vehicles only sync big value jumps
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+46
-42
@@ -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<Collider>()); // stört sonst Physik/Trigger
|
||||
var renderer = go.GetComponent<Renderer>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+14
-6
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user