diff --git a/examples/ShowBoltSize/ShowBoltSize.cs b/examples/ShowBoltSize/ShowBoltSize.cs index 31dc5e8..f0e4210 100644 --- a/examples/ShowBoltSize/ShowBoltSize.cs +++ b/examples/ShowBoltSize/ShowBoltSize.cs @@ -7,9 +7,9 @@ using UnityEngine; [assembly: AssemblyTitle("Show Bolt Size")] [assembly: AssemblyProduct("Show Bolt Size")] [assembly: AssemblyDescription("Shows the size of the bolt you look at, so you pick the right wrench.")] -[assembly: AssemblyVersion("1.0.1.0")] -[assembly: AssemblyFileVersion("1.0.1.0")] -[assembly: AssemblyInformationalVersion("1.0.1")] +[assembly: AssemblyVersion("1.0.2.0")] +[assembly: AssemblyFileVersion("1.0.2.0")] +[assembly: AssemblyInformationalVersion("1.0.2")] namespace ShowBoltSize { @@ -22,16 +22,17 @@ namespace ShowBoltSize { public override string ID { get { return "showboltsize"; } } public override string Name { get { return "Show Bolt Size"; } } - public override string Version { get { return "1.0.1"; } } + public override string Version { get { return "1.0.2"; } } public override string Author { get { return "MBM"; } } - const float MaxDistance = 1.3f; - const float BoltRadius = 0.025f; // so groß wirkt eine Schraube beim Zielen + const float MaxDistance = 1.5f; + const float AimTolerance = 0.05f; // so weit (m) darf die Schraube neben der Blicklinie liegen const float ScanInterval = 5f; sealed class Bolt { public Transform Transform; + public Renderer Renderer; // sichtbarer Schraubenkopf (Kind-Objekt) - sein Mittelpunkt statt des Drehpunkts public FsmFloat SizeF; public FsmInt SizeI; } @@ -43,6 +44,9 @@ namespace ShowBoltSize GUIStyle style; Camera camera; bool reported; + int diagnostics; // die ersten Male ins Log schreiben, was in Blickrichtung liegt + float nextDiagnostic; + bool shownOnce; public override void OnMenuLoad() { inGame = false; bolts.Clear(); label = null; camera = null; reported = false; } public override void OnGameLoad() { inGame = true; nextScan = 0f; } @@ -60,6 +64,8 @@ namespace ShowBoltSize return camera; } + static Vector3 Center(Bolt b) { return b.Renderer != null ? b.Renderer.bounds.center : b.Transform.position; } + public override void Update() { label = null; @@ -68,28 +74,42 @@ namespace ShowBoltSize if (cam == null) return; if (Time.realtimeSinceStartup >= nextScan) Scan(cam); + // Die Schraube, die am nächsten an der Blicklinie liegt (Abstand zur Linie, nicht Winkel) Transform eye = cam.transform; Vector3 eyePos = eye.position, forward = eye.forward; - Bolt best = null; - float bestAngle = float.MaxValue; + Bolt best = null, nearest = null; + float bestOff = float.MaxValue, nearestOff = float.MaxValue; for (int i = 0; i < bolts.Count; i++) { Bolt b = bolts[i]; - if (b.Transform == null) continue; - Vector3 to = b.Transform.position - eyePos; - float sq = to.sqrMagnitude; - if (sq > MaxDistance * MaxDistance || sq < 0.0025f) continue; - if (!b.Transform.gameObject.activeInHierarchy) continue; - float distance = Mathf.Sqrt(sq); - float angle = Vector3.Angle(forward, to); - float limit = Mathf.Atan2(BoltRadius, distance) * Mathf.Rad2Deg + 0.5f; - if (angle < limit && angle < bestAngle) - { - bestAngle = angle; - best = b; - } + if (b.Transform == null || !b.Transform.gameObject.activeInHierarchy) continue; + Vector3 to = Center(b) - eyePos; + float along = Vector3.Dot(to, forward); + if (along < 0.05f || along > MaxDistance + 0.5f) continue; + float off = Vector3.Cross(forward, to).magnitude; // Abstand zur Blicklinie + if (off < nearestOff) { nearestOff = off; nearest = b; } + if (along <= MaxDistance && off < AimTolerance && off < bestOff) { bestOff = off; best = b; } } - if (best != null) label = Describe(best); + if (best != null) + { + label = Describe(best); + if (!shownOnce) { shownOnce = true; Log("first bolt: " + Info(best, eyePos, forward) + " -> " + label); } + } + else if (nearest != null && diagnostics < 8 && Time.realtimeSinceStartup >= nextDiagnostic) + { + // Hilft bei der Fehlersuche: was liegt in Blickrichtung, warum wird nichts angezeigt? + nextDiagnostic = Time.realtimeSinceStartup + 4f; + if (nearestOff < 0.3f) { diagnostics++; Log("nearest bolt (not shown): " + Info(nearest, eyePos, forward)); } + } + } + + static string Info(Bolt b, Vector3 eyePos, Vector3 forward) + { + Vector3 to = Center(b) - eyePos; + float raw = b.SizeF != null ? b.SizeF.Value : (b.SizeI != null ? b.SizeI.Value : -1); + return b.Transform.name + " under " + (b.Transform.parent != null ? b.Transform.parent.name : "-") + + ", distance " + Vector3.Dot(to, forward).ToString("0.00") + " m, off the line " + (Vector3.Cross(forward, to).magnitude * 100f).ToString("0") + " cm" + + ", angle " + Vector3.Angle(forward, to).ToString("0.0") + "°, BoltSize=" + raw + (b.Renderer != null ? "" : " (no renderer)"); } /// @@ -106,7 +126,7 @@ namespace ShowBoltSize FsmFloat f = fsm.FsmVariables.FindFsmFloat("BoltSize"); FsmInt i = fsm.FsmVariables.FindFsmInt("BoltSize"); if (f == null && i == null) continue; - bolts.Add(new Bolt { Transform = fsm.transform, SizeF = f, SizeI = i }); + bolts.Add(new Bolt { Transform = fsm.transform, SizeF = f, SizeI = i, Renderer = fsm.GetComponentInChildren() }); } if (!reported) { @@ -119,7 +139,7 @@ namespace ShowBoltSize static string Describe(Bolt b) { float value = b.SizeF != null ? b.SizeF.Value : b.SizeI.Value; - if (value <= 0f) return null; + if (value <= 0f) return "? mm"; // Größe unbekannt - aber die Schraube wurde erkannt float mm = value < 2.5f ? value * 10f : value; return Mathf.RoundToInt(mm) + " mm"; }