- Home /
Mathf.PingPong make the leaf jittering when the speed is changed.
following to this code. When I change the speed it make my object rotation jittering 1frame . How to make the mathf.pingpong smooth when changing speed?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BB_LEAVE_Aon : MonoBehaviour
{
public float min_y;
public float max_y;
float range;
float speed =20;
void Start()
{
range = Random.Range(min_y,max_y);
}
private void Update()
{
if(WindChange.wind <= 1)
{
speed = 20;
}
if (WindChange.wind >1)
{
speed = 30;
}
transform.localEulerAngles = new Vector3(0, -Mathf.PingPong(Time.time * speed, range), 0);
}
}
Answer by Bunny83 · May 02, 2020 at 11:47 AM
Of course it does. Keep in mind what you are doing here. You use Time.time directly as input. Time.time steadily increases over time. You multiply that value by speed. So assuming speed is 20 after one second we get a value of 20, after another second we get a value of 40 then 60, 80, 100, ...
You use pingpong with a certain length / range. So your input value will be "folded" back into the range you want. We don't know what that range might be but we just assume the range is 6. Have a look at this table:
// time | * 20 | PP(*20,6) | * 30 | PP(*30,6) |
// ---------------------------------------------
// 0.0 | 0 | 0 | 0 | 0 |
// 0.1 | 2 | 2 | 3 | 3 |
// 0.2 | 4 | 4 | 6 | 6 |
// 0.3 | 6 | 6 | 9 | 3 |
// 0.4 | 8 | 4 | 12 | 0 |
// 0.5 | 10 | 2 | 15 | 3 |
// 0.6 | 12 | 0 | 18 | 6 |
// 0.7 | 14 | 2 | 21 | 3 |
// 0.8 | 16 | 4 | 24 | 0 |
// 0.9 | 18 | 6 | 27 | 3 |
// 1.0 | 20 | 4 | 30 | 6 |
// 1.1 | 22 | 2 | 33 | 3 |
// 1.2 | 24 | 0 | 36 | 0 |
// 1.3 | 26 | 2 | 39 | 3 |
// 1.4 | 28 | 4 | 42 | 6 |
// 1.5 | 30 | 6 | 45 | 3 |
// 1.6 | 32 | 4 | 48 | 0 |
// 1.7 | 34 | 2 | 51 | 3 |
// 1.8 | 36 | 0 | 54 | 6 |
// 1.9 | 38 | 2 | 57 | 3 |
// 2.0 | 40 | 4 | 60 | 0 |
Of course Time.time increases smoothly so the output is smooth as well. However when you suddenly change your multiplication factor you immediately jump to a different value. For example at time "0.61" the input for ping pong is "12.2" and the result after the ping pong is "0.2". However if we change the multiplicator from 20 to 30 we suddenly jump to "18.3" and we get a final result of "5.7". So your output jumps from 0.2 to 5.7
Using Time.time this way is generally not a good idea. First of all the longer the game runs the more you loose floating point precision. Since you multiply the time by 20 or 30 you actually amplify this effect
I would recommend you use something like that:
private float timer = 0;
// [ ... ]
timer += speed * Time.deltaTime;
if (timer > range*2)
timer -= range*2;
transform.localEulerAngles = new Vector3(0, -Mathf.PingPong(timer, range), 0);
Of course this assumes that your "range" stay fix after the start. Note that instead of using PingPong it would be better to use something like a sine wave. Linear motion probably looks unrealistic. Using Mathf.Cos also would help to seperate the frequency from the amplitude
private float timer = 0;
// [ ... ]
timer += speed * Mathf.PI * 2 * Time.deltaTime;
if (timer > Mathf.PI * 2)
timer -= Mathf.PI * 2;
float a = 0.5f - Mathf.Cos(timer)*0.5f;
transform.localEulerAngles = new Vector3(0, -a * range, 0);
In this case speed specifies how many times per second the leaf should bounce back and forth while "range" specifies the max angle you want to rotate at. Range is now independent of the speed. So "a" will simply be a value that oscilates between 0 and 1 but will ease in / out at the extremes.
Once the timer gets larger than one period we can savely subtract the length of one period and still get the same result. That way the timer value doesn't get too large.
thank you so much .I just see your answer. I will try.
Your answer
Follow this Question
Related Questions
Mathf function on GetKey 1 Answer
Mathf.Pingpong without the repetition!? 1 Answer
Mathf.PingPong strange behaviour 1 Answer
Platforms Oscillating with Mathf.PingPong not working properly 0 Answers