Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Convert Real Life Speed to Unity Units

Discussion in 'Scripting' started by BeBox2017, Jul 10, 2023.

  1. BeBox2017

    BeBox2017

    Joined:
    Jan 22, 2017
    Posts:
    21
    I am currently taking in live location data and would like to convert it to speed usable by Unity. My game scale is absurdly small all things considered. It is based off a real world map, so it encompasses a real world coordinate area. In unity, my area is roughly 2 by 3 units. I get real world speed in knots per hour so I start by converting knots to kilometers per hour, dividing it by 0.539957. I then divide this by 216,000. Thats 60 (hours) times 60 (minutes) times 60 (frames per second). The code looks like this:
    speed = (knots / 0.539957f) / 216000;
    This however fails to mimic the real life speed so I hope somebody could help me figure that out! Thankyou so much in advance!
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,563
    You have about 6 to 9 digits of precision with single-precision
    float
    s, eg, using what you call "Unity units."

    https://en.wikipedia.org/wiki/Single-precision_floating-point_format

    Your other options would be to implement a floating origin, or else do all your own data tracking in something with more precision, such as a
    double


    For the sake of the physics system, 1 Unity unit is 1 meter.
     
    Bunny83 likes this.
  3. BeBox2017

    BeBox2017

    Joined:
    Jan 22, 2017
    Posts:
    21
    Thankyou! I believe what I was looking for was that 1 Unity Unit is 1 meter. I unfortunately cannot use a double as all my object.transform action require it to be a float. I believe 6 digits of precision is enough.
     
  4. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,913
    Well, no. The preset value for gravity, which only applies to rigidbodies, it set to 9.8. That works for the real world if 1 unit = 1 meter. That's the only link to a scale, and only if you use rigidbodies with gravity, and you can easily change that value. I suppose the other place could be if you use real-world physics formulas based in meters and don't want to change them.

    This means that Unity has no set scale, which is good -- pick whichever seems best for your project. Or if that blows your mind, use 1 meter/unit. BUT, if you later think "gee, I wish I could use 1 unit=10 meters", go ahead. Have all of your math use that conversion and Unity won't care, since it never cares.
     
    Kurt-Dekker likes this.
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,563
    The funnest physics can come from objects of wildly different masses... they have the most non-linear solutions forces and wilder error terms.

    To see what I mean, like stack three cubes on top of each other, the top two cubes with Rigidbodies (or Rigidbody2Ds).

    Press play and let them fall... then select the top cube and slowly start doubling the mass... 1, 2, 4, 8, 16, 32, 64, 128 .. peeew!!! off she goes
     
  6. Yuchen_Chang

    Yuchen_Chang

    Joined:
    Apr 24, 2020
    Posts:
    104
    A bit off topic, but I would like to mention that 3d-model import settings are also effected by the scale: 1cm in other software is default to be 0.01 Unity unit. (ofcourse you can change them, but that needs reimporting)
     
  7. BeBox2017

    BeBox2017

    Joined:
    Jan 22, 2017
    Posts:
    21
    The objects I'm using thankfully dont use any sort of physics, so gravity and object mass dont matter. All that matters at the moment is getting them to move similar to how they do in real life. Is there a way I can specifically tell unity to use a certain unit to real life distance conversion?
     
  8. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,495
    No, you can't "tell" Unity to do something like that since Unity uses unitless "units" which are just virtual numbers in a virtual world. When you want to down or upscale your virtual world you can do that. All you need to know is your scaling factor of your world, We can't tell you what that is, it's your world.

    I'm not sure how you arrive at your value of "216000". If you have a speed in kilometers per hour you can convert it to meter per second by dividing by 3.6 (dividing by 3600 to convert "per hour" to "per second" and multiplying by 1000 to convert km to m). What's the point of your third 60? Is that your assumed frame rate? Don't do that. Unity has Time.deltaTime to convert a "per second" value into a "per frame" value. The framerate is not necessarily constant.

    However this gives you m/s. Now you need to apply your scaling factor. You talk about "your area" and that it is "roughly" 2 or 3 units. This isn't really helpful. How large is that area in the real world? If you don't know your scaling factor anything else you do it pretty pointless.

    I once made a solar system visualization (sun, earth moon in line but to scale). I can't remember exactly but I think I used a 1:10000 scale between 1 unit and 1 km. Since I need to go up to 150000000km this was some kind of compromise. The actual visualization is a single shader. So the sun, earth and moon as well as the umbra / penumbra lines are drawn by a single shader. Soo the script does is adjust some scaling and offset values.
     
  9. BeBox2017

    BeBox2017

    Joined:
    Jan 22, 2017
    Posts:
    21
    Gotcha. I got 216,000 now apperantly falsely, I didnt realize that unity took framerate into consideration using Time.deltaTime conversion, which may have been my biggest problem. To answer the question though, yes the 3rd 60 was to represent framerate. The area covered in the real world is a 300km by 300km area, which is 3.52842 units on the x axis and 2.69533 units on the z axis. .
     
  10. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,913
    But it's not as if _Unity_ does that. If you're applying speed every frame, you'd use speed/60, in the code. If you don't know the framerate will always be 60, you'd use speed/framerate. Unity provide lots of values, some used, some mostly ignored. Time.deltaTime is one, and is roughly 1/framerate, so many coders find it easier to use speed*Time.deltaTime. If Unity didn't have it, they'd use 2 extra lines of code to compute it themselves.

    That's how it is with the scale as well: if a person wanted 1 unit=4 inches they'd manually enforce that in various places. A car which is 120 inches in the real-world would be hand-rescaled to be 30 units long. The miles-per-hour to inches-per-second calculation would have an extra divided-by-4 (or use a UNITS_PER_MILE constant).
     
    Bunny83 likes this.
  11. BeBox2017

    BeBox2017

    Joined:
    Jan 22, 2017
    Posts:
    21
    Okay. I've updated my forumla a bit. I now have
    (((real speed / .53xxx) / 3.6) / 99000) * Time.deltaTime
    Real speed = knots per hour, .53xxx = conversion from knots per hour to kilometers per hour, 3.6 = conversion from kilometers per hour to meters per second, 99000 = real life scale roughly 1 unit is 99 real life kilometers scaled. This feels much better, when I plug in 99 (for kilometers per hour) I get roughly .00028, which then multiplied by 3600 (seconds per hour) I get 1, which is how far it should travel in unity (being 99 kilometers = 1 unit).