Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Possible to change Time.timeAsDouble manually

Discussion in 'Scripting' started by Bogotoff, May 18, 2022.

  1. Bogotoff

    Bogotoff

    Joined:
    Dec 20, 2013
    Posts:
    7
    I'm making a system to reproduce the gameplay accurately. For this I need to exactly reproduce the order of function calls with the right Time.time, Time.deltaTime,...
    I understand that Time.timeAsDouble changes in WaitForLastPresentationAndUpdateTime (in PlayerLoop), I want to replace this call with my function or overwrite Time.timeAsDouble/Time.fixedTimeAsDouble with its value after this call. Otherwise FixedUpdate is not called in the right order.
    If you find and replace the values (Time.timeAsDouble,...)in the RAM, it seems to give the desired effect, but it's workaround, not reliable and the process is long.

    @Unity Can you add the ability to manually update Time, or the ability to change timeAsDouble/deltaTime/fixedTimeAsDouble values,... After WaitForLastPresentationAndUpdateTime?
    I mean the ability to change native variables from C#.

    P.S. I need this to be able to reproduce bugs with 100% chance, on the same machine.
     
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,612
  3. Bogotoff

    Bogotoff

    Joined:
    Dec 20, 2013
    Posts:
    7
    Thanks, I know about this feature. I mentioned about PlayerLoop and in particular about WaitForLastPresentationAndUpdateTime, which is part of PlayerLoop, which updates Time.
    I want to be able to change exactly Time.deltaTime, Time.timeAsDouble,....
    Right now I don't have that capability and it's not enough to modify PlayerLoop.
    Timeline and many ThirdParty plugins use Time, the number and order of FixedUpdate calls also depends on Time, so I need to change the initial values at the beginning of the frame.
     
  4. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,612
    Yeah I don't think that's happening without source access. Seems way too low level to made accessible, to be honest.

    Unity isn't deterministic. The only way to make it so is to take the over reigns of everything.
     
  5. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,894
    A simpler workaround is to change your code to read your own custom property instead of reading Time.timeAsDouble directly. Then you can do something like:
    Code (CSharp):
    1. double testTime;
    2.  
    3. public static double MyTime {
    4.   get {
    5.     if (inAUnitTest) {
    6.       return testTime;
    7.     }
    8.  
    9.     return Time.timeAsDouble;
    10.   }
    11. }
    Then you can have full control over the time in your tests.
     
    Bunny83 likes this.
  6. Bogotoff

    Bogotoff

    Joined:
    Dec 20, 2013
    Posts:
    7
    Unity physics is deterministic if you run the same logic on the same machine. The rest of the logic should also be deterministic, apart from the use of randomization, but that's easier to deal with. Input, too, I can reproduce.
    The main problem is Time, since it affects the order and number of Update/FixedUpdate calls, and the WaitForSeconds() yield calls work using Time.

    I see only 2 solutions here:
    1 - rework all game logic, remove all Update/FixedUpdate, yield WaitForXXX, Time, etc, and write an alternative for everything.
    2 - at the beginning of the frame set the necessary values Time.time, deltaTime, etc. so that all the logic is repeated.

    Obviously, the first variant needs a lot of time, and access to ThirdParty plugins, and the second variant Unity developer just needs to add setters for the Time class properties.

    I don't have the source code, so I ask the developers to add this little feature :)
    I'm not sure if I'm writing in the right forum thread. I hope unity developers will answer something about it.
     
  7. Bogotoff

    Bogotoff

    Joined:
    Dec 20, 2013
    Posts:
    7
    Unfortunately, it's not enough :(
    If all the logic was mine, I could do so, but unfortunately there is a part of the code to which I do not have access or difficult to modify.
    P.S. I already did a similar system on a custom game engine, but in unity I do not have access to the source code(
     
  8. mubashar0612

    mubashar0612

    Joined:
    Feb 22, 2018
    Posts:
    1
    any success on this? i need the same thing and stuck on same problem:)
     
  9. Bogotoff

    Bogotoff

    Joined:
    Dec 20, 2013
    Posts:
    7
    Unfortunately, no :(
     
  10. Leuki

    Leuki

    Joined:
    Feb 27, 2014
    Posts:
    130
    In Unity, you cannot directly change the value of Time.timeAsDouble, since it is a read-only property. However, you can achieve the same effect by using the Time.timeScale property to manipulate the speed of the game.

    Here's an example script that demonstrates how to manually change the Time.timeScale property to adjust the Time.timeAsDouble value:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class TimeController : MonoBehaviour
    4. {
    5.     public double targetTime = 60.0;
    6.     public float timeScale = 1.0f;
    7.  
    8.     private double startTime;
    9.  
    10.     void Start()
    11.     {
    12.         startTime = Time.timeAsDouble;
    13.     }
    14.  
    15.     void Update()
    16.     {
    17.         double elapsedTime = Time.timeAsDouble - startTime;
    18.         float timeRatio = (float)(elapsedTime / targetTime);
    19.         Time.timeScale = timeScale * timeRatio;
    20.     }
    21. }
    22.  
    In this script, we have a public targetTime field, which is the target time in seconds that we want to reach. We also have a public timeScale field, which is the desired time scale that we want to apply.

    In the Start method, we initialize the startTime variable with the current Time.timeAsDouble value.

    In the Update method, we calculate the elapsed time by subtracting the startTime from the current Time.timeAsDouble value. We then calculate a timeRatio value by dividing the elapsed time by the targetTime. This timeRatio value is used to adjust the Time.timeScale property, which affects the speed of the game.

    By adjusting the timeScale property, we can speed up or slow down the game, and by changing the targetTime value, we can control the duration of the effect.

    Note that changing the Time.timeScale property affects the entire game, not just the time value. So, if you have other time-sensitive features in your game, you need to adjust them accordingly to make sure they behave as expected.
     
  11. Bogotoff

    Bogotoff

    Joined:
    Dec 20, 2013
    Posts:
    7
    I think you missed the point of the problem. But thanks anyway for trying:)
     
  12. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,894
    That guy copy and pasted from ChatGPT :(
     
  13. Leuki

    Leuki

    Joined:
    Feb 27, 2014
    Posts:
    130
    Im not sure thatit matters where information comes from. Does it make you feel good to belittle others for trying to help solve an issue?
     
  14. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,894
    I think if someone wanted a ChatGPT answer, they would have asked ChatGPT, no? People come here to ask the community.