Having trouble with Time.time. I have found induced skips that I can not correct. Any help?

I have come across a situation where if Time.time is called at two different places at different passes in Update() the value will differ in its increment thus any use of Vector3(0,Time.time,0) will cause jumps in the results. I have a gameobject that starts a path in section of code then transitions to another set of code further along in the script. The gap execution of Time.time in the first call and the second call is different than the gaps in the loop of the first call. That is why I am asking about a replacement. Its not about the code. Its about the Time.time variance between the two Time.time usages. I believe there is an execution caused variance.

    void Update () {
 
            synchTime = Time.time;
            // This proc releases gameobject from center into an outward spiralling trajectory till the height orbit path attained,
            // then disables itself releasing the gameobject into the sine wave orbital path.
            if (!reachedElevation)
            {
                transform.Translate(0, Time.deltaTime, 0);
                reachedElevation = true;
                _AgentY = Mathf.Sin(synchTime);//Keeps value started and in synch with usage below
             
            }else{
 
            // The trouble is making the 'Y' synch between where the spiral left off and this sine. It has to do with Time.time
            _AgentY = Mathf.Sin(synchTime);
 
            Debug.Log("Before transform.localPosition.y: " + transform.localPosition.y);
            transform.localPosition = new Vector3(transform.localPosition.x, _AgentY, transform.localPosition.z);
            Debug.Log("After transform.localPosition.y: " + transform.localPosition.y);
         
        }
}

It appears to be that it’s about the code. Notice on line 10 you’re returning. This means that there are no Update calls, ever, the way you’ve written it, where your Time.time call on line 8 will occur on the same frame as your Time.time call on line 14. Understand that `return’ will causing none of the code below it to execute on that frame. So I’d say that in 100% of cases, the Time.time value you get on line 8 would be different than the Time.time value you’d get on line 14.

Just to be clear, calling Time.time repeatedly within Update, in the same frame, will result in the same value each time. But you’re not doing that. You’re calling it in two different frames.

1 Like

The logic has two areas. The first !reachedElevation shuts itself off, then calls Time.time, then returns.
In the next update the second area is executed and the Time.time is called. So there is a Time.time first loop then a Time.time second loop split by the boolean check.
The _AgentY = Mathf.Sin(Time.time); is always called at some point.
If I am to understand your response then I should remove the return(); and finish the boolean ‘if’ statement with an else.

I added the ‘else’, removed the return();, put synchTime = Time.time; as first line in update, removed the synchTime increment, changed to _AgentY = Mathf.Sin(synchTime). The results havent changed. There is still a jump in the _AgentY variable value.

There is no guarantee that the elapsed time between two different frames will always be the same. By default, on PC, Unity will make frames as fast as it can, so the time between frames depends on how expensive it is to calculate the new frame and what else your computer is doing. Even if you “cap” the framerate, that creates a minimum time between frames, but not a maximum–frames still take as long as they take.

I would guess that something “special” is happening in your game on the frame when reachedElevation becomes true that causes that frame to take longer than usual to calculate.

In terms of code organization, I suggest you move the line _AgentY = Mathf.Sin(Time.time); to be before your “if” check, since it works the same in both branches anyway. That will make its independence more obvious.

I am also running in the editor and not compiled. The profiler shows +75% editor usage. I have been trying to avoid the compile and device push till this point. I am guessing I just have to belay this issue, keep working on my game and then push to see the real performance issues. I was so hoping keep developing long term. This point has to crossed at some point.
I did update the code and added an image.

The jump happens across the ‘else’ statement. The spiral and the sine paths work great unto themselves.

Doesn’t matter if build, editor, different platform, etc. The time between frames cannot be guaranteed, even if you were somehow able to eliminate anything causing a frame rate drop from within your game. Background applications, CPU/GPU temperature throttling, an OS update starting, etc, etc, will all cause frame rate variance. You need to design your system to function independent of frame rate instead of trying to smooth out the frame rate.

1 Like

Hold on. First you were saying that Time.time has an unexpected value; but now you seem to be saying that your object’s movement has a discontinuity.

But why would you expect the movement to be continuous when you start out moving it in a straight line and then suddenly switch to a sine wave? That’s got nothing to do with whether Time.time is smooth.

You aren’t outputting the value of _AgentY (or using it for anything) until you get to the “else” branch. The value of _AgentY is probably smooth (within reason), it’s just that you switch from ignoring it to using it.

Yes. In first loop I started it and kept it updated till I could transition it the second loop.
The transition is what is the switch point. I am digging deeper into this part now. I have no doubt it is my fault. I just have to ask questions and get the outside view to break my spell. There is something loose or mismatched some where that I have to find.
What I have realized over the years is that if one could ask the main question upfront the answer would come quick. This one is deep and twisty to me at the moment.
This whole thread could turn out to be ridiculous but I wont know till I hammer out all the inputs and outputs.
I am only expecting the last Y of the spiral path to be the same as the first Y of the sine path. They are not and that is where the jump comes from. Been on this two days and the headache and stress wont go away.

Can you sketch a quick diagram of what you want to have happen?

Top picture is test results with jump in localPosition.Y
Bottom image is correction with what I want to have happen.
The sharp turn is ok as the Gameobject doesnt jump but is part of the game play.

4488094--413425--2019-04-30 21_31_47-Unity 2018.2.2f1 Personal (64bit) - [PREVIEW PACKAGES IN USE] - Agent1.png

What exactly do you think you are “keeping updated”? You’re not using the variable for anything during that time (at least, not in the posted code).

In the first branch of your “if”, you are incrementing your object’s Y coordinate by Time.deltaTime. That means its position is going to be Time.time + k for some constant k (assuming nothing else is moving it on the Y axis during this time).

In the “else” branch, you are setting your object’s Y coordinate to Mathf.Sin(Time.time).

What makes you think that Time.time + k is going to be anywhere close to Mathf.Sin(Time.time)? Why wouldn’t that cause a wild jump?

Thanks for the reply.
I was hoping to read the localPosition.Y then use that as a starting point in the sine path. I am struggling to get the data to calculate correctly.
And yes you are correct. The two delta and time dont match. But I should be able to use the localPosition.Y data to transition.

Well, you certainly haven’t posted any code that does that, or that appears to be aimed at doing that.

One way to accomplish that would be to calculate an offset to the Y position that would make the coordinates equal on the first frame of the transition, and then save that offset and continue applying it in all subsequent frames.

That might look something like this:

    float offset;
    void Update () {
            _AgentY = Mathf.Sin(Time.time);
            // This proc releases gameobject from center into an outward spiralling trajectory till the height orbit path attained,
            // then disables itself releasing the gameobject into the sine wave orbital path.
            if (!reachedElevation)
            {
                transform.Translate(0, Time.deltaTime, 0);
                reachedElevation = true;
                offset = transform.localPosition.y - _AgentY;
            }else{
            Debug.Log("Before transform.localPosition.y: " + transform.localPosition.y);
            transform.localPosition = new Vector3(transform.localPosition.x, _AgentY + offset, transform.localPosition.z);
            Debug.Log("After transform.localPosition.y: " + transform.localPosition.y);
        }
}

@Antistone ! The offset was it. You saved me hours. I knew there was a link between the two functions and could not begin to dig in. Too much time spent in my own code. Turns out it was a simple as I hoped it would be. And no matter how large the diameter of the spiral this still works.
Thanks.
Where do I send money?