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