-
-
Save kwalkerxxi/84c76ae701d5f577bf04dac7faae8ed6 to your computer and use it in GitHub Desktop.
demonstration of precise race finish line timing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
// @kurtdekker - precise timing on two cars passing the finish line at the same instant | |
// | |
// from forum post: | |
// | |
// https://discussions.unity.com/t/how-do-you-measure-milliseconds-at-runtime/1562308 | |
// | |
// To use: make a scene, drop it on a GameObject, press PLAY | |
// | |
// Optional: create your own cars, drag 'em in. | |
// | |
// Now wiggle the cars around, rotate the whole contraption if you like, whatever | |
// | |
// Output: tells you the precise time between T1 and T2 | |
// that each car's centroid crosses the finish line plane. | |
public class RacingPreciseFinishLine : MonoBehaviour | |
{ | |
[Header("Make 'em or we make 'em.")] | |
public GameObject Car1_T1; | |
public GameObject Car1_T2; | |
public GameObject Car2_T1; | |
public GameObject Car2_T2; | |
[Header("Input times:", order = 1)] | |
[Header("-> Previous Frame Time:", order = 2)] | |
public float TimeT1 = 1.000f; | |
[Header("-> Current Frame Time:")] | |
public float TimeT2 = 1.020f; | |
[Header("By fiat, the normal of finish line is transform.right")] | |
[Header("This normal is in the direction of travel.")] | |
public Transform FinishLinePlane; | |
void Start() | |
{ | |
if (!Car1_T1) | |
{ | |
// create them | |
Car1_T1 = GameObject.CreatePrimitive(PrimitiveType.Cube); | |
Car1_T2 = GameObject.CreatePrimitive(PrimitiveType.Cube); | |
Car2_T1 = GameObject.CreatePrimitive(PrimitiveType.Cube); | |
Car2_T2 = GameObject.CreatePrimitive(PrimitiveType.Cube); | |
// position them | |
float x = -3.0f; | |
float y1 = +2.0f; | |
float y2 = -2.0f; | |
Car1_T1.transform.position = new Vector3(x, y1, 0); | |
Car1_T2.transform.position = new Vector3(x + 5, y1, 0); | |
Car2_T1.transform.position = new Vector3(x, y2, 0); | |
Car2_T2.transform.position = new Vector3(x + 8, y2, 0); | |
// name them | |
Car1_T1.name = "Car1_T1"; | |
Car1_T2.name = "Car1_T2"; | |
Car2_T1.name = "Car2_T1"; | |
Car2_T2.name = "Car2_T2"; | |
} | |
if (!FinishLinePlane) | |
{ | |
FinishLinePlane = GameObject.CreatePrimitive(PrimitiveType.Cube).transform; | |
FinishLinePlane.transform.position = new Vector3(1, 0, 0); | |
FinishLinePlane.localScale = new Vector3(0.01f, 8, 4); | |
FinishLinePlane.name = "Finish Line Plane"; | |
} | |
} | |
void Update() | |
{ | |
Vector3 finishPosition = FinishLinePlane.position; | |
// arbitrary: use any direction you like | |
Vector3 finishNormal = FinishLinePlane.right; | |
// relative position to finish line position | |
Vector3 Car1_T1_RelativePosition = finishPosition - Car1_T1.transform.position; | |
Vector3 Car1_T2_RelativePosition = finishPosition - Car1_T2.transform.position; | |
Vector3 Car2_T1_RelativePosition = finishPosition - Car2_T1.transform.position; | |
Vector3 Car2_T2_RelativePosition = finishPosition - Car2_T2.transform.position; | |
// linear track space, before to after the finish line | |
float car1Pos1 = Vector3.Dot(Car1_T1_RelativePosition, finishNormal); | |
float car1Pos2 = Vector3.Dot(Car1_T2_RelativePosition, finishNormal); | |
float car2Pos1 = Vector3.Dot(Car2_T1_RelativePosition, finishNormal); | |
float car2Pos2 = Vector3.Dot(Car2_T2_RelativePosition, finishNormal); | |
// how far in linear space did each car travel this final frame? | |
float car1Delta = car1Pos2 - car1Pos1; | |
float car2Delta = car2Pos2 - car2Pos1; | |
// careful! we're lerping "backwards" from now (T2) to previous (T1)!! | |
// that makes these sort of "back fractions..." | |
float fraction1 = car1Pos2 / car1Delta; | |
float fraction2 = car2Pos2 / car2Delta; | |
float car1Time = Mathf.Lerp(TimeT2, TimeT1, fraction1); | |
float car2Time = Mathf.Lerp(TimeT2, TimeT1, fraction2); | |
// help yourself to whatever precision you want to claim, but | |
// single-precision float is about 6-9 decimal places max, and | |
string output = System.String.Format( | |
"Car1: {0:0.00000} Car2: {1:0.00000} ", car1Time, car2Time); | |
Debug.Log(output); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment