Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save kwalkerxxi/84c76ae701d5f577bf04dac7faae8ed6 to your computer and use it in GitHub Desktop.
Save kwalkerxxi/84c76ae701d5f577bf04dac7faae8ed6 to your computer and use it in GitHub Desktop.
demonstration of precise race finish line timing
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