what exactly does Time.time do in Mathf.PingPong?

I’m sorry for the stupid question but I can’t seem to get my head around this one.

Whenever I see PingPong used, I see it with Time.time, but I don’t understand how it works exactly.

From the Scripting-Reference:

Mathf.PingPong
static function PingPong (t : float, length : float) : float

PingPongs the value t, so that it is never larger than length and never smaller than 0.

The returned value will move back and forth between 0 and length.


function Update () {
    // Set the x position to loop between 0 and 3
    transform.position = Vector3(
       Mathf.PingPong(Time.time, 3), transform.position.y, transform.position.z);
} 

So…

Mathf.PingPong PingPongs value t (=Time.time), so that it is never larger than length and never smaller than 0.

How does it work, that it PingPongs ‘value t’??

Time.time is read-only. Time.time is an ever-increasing value dependent on timescale and seconds-since-game-started.

So how can Time.time be ‘PingPonged’ to be never larger than length and never smaller than 0?

If it’s clear that Mathf.PingPong returns a value between 0 and lenght, the ‘value t’ must be to somehow set the speed, but why do we want this speed to be an ever-increasing float. And why doesn’t this ever-increasing float make the speed actually… you know… increase?? O-o

I have a nebulous hunch, that PingPong probably needs a constantly increasing value to work (though I don’t get why…)

So could I also use something like this?:


var counter : float = 1.0;
function Update () {
  counter += 0.2;
  transform.position = Vector3 (Mathf.PingPong(counter, 4), tr.pos.y, tr.pos.z);
}

Can someone explain to me why PingPong works in such a weird way and doesn’t look more like

static function PingPong (startvalue:float, endvalue:float, speed:float): float

which would have the convenient side-effect that we don’t have to subtract something if we want to ping-pong around 0?

Greetz, Ky.

Yes, any increasing value works for ping-pong. Time.time is the easiest, but if you want to start ping-ponging after a certain event, than using Time.time will snap you to a randomish spot (if you start doing a length 4 ping-pong at time 7, you’ll jump to 1 unit away, coming back to the start.) In that case, your counter method is exactly what you want.

The version of ping-pong you’re thinking of is a fire-and-forget. It could be written in a coroutine with yield. Yes, that would be more useful, but coroutines confuse a lot of people and they are tricky to stop. That’s probably why iTween is so popular.

PingPong is a simple 1-output math function. Not great, but better than nothing. You give it inputs, it gives you an output. If no inputs change, the output doesn’t change. Take a look at Mathf.SmoothDamp. It ramps your speed up, moving you, then coasts down to the end. You still have to call it every frame with an increasing value. You also have to create the currentVelocity variable, start it at 0, and pass it in by reference. SmoothDamp changes it, but the only way it “remembers” it for next time is because you pass it back in.

PingPong could have been written as with a start besides 0, as you suggest: PingPong(time, start, stop). Think of pingPong like Mathf.Abs. You could just use an if – Abs is just a tiny bit nicer.

  1. L = 2 * length

  2. T = t modulo L

  3. x = L - T

  4. return x

As t increase from 0 to length return t. If t is in the range length to 2length return 2length-t. This will change from length back to zero. The modulo operation essentially repeatedly subtracts 2length until the result is in the range zero to 2length.

Just try it with some numerical values.

To answer your question, time is never changed. The ping-ponged value is returned by the function.

var position = new vector3 ( 0, 0, Mathf.PingPong( (SpeedValue*Time.time),EndPos ) );
// This Will Run In Z Axis Only Between 0, Endpos;

//But if you want Custom Minimum Value like = 5, -3, etc.
//If you want negative Number then minus that number like this =
var position = new vector3 ( 0, 0, Mathf.PingPong( (SpeedValue*Time.time), ( EndPos + MinValue ) ) - MinValue);

//If you want positive Number then Plus that number like this =
var position = new vector3 ( 0, 0, Mathf.PingPong( (SpeedValue*Time.time), ( EndPos - MinValue ) ) + MinValue);