Хорошо, поэтому, если я правильно вас понимаю, в данный момент вы делаете
privte void FixedUpdate()
{
var factor = (Mathf.Sin(speed * Time.time) + 1.0f) / 2.0f;
object1.MovePosition(Vector3.Lerp(object2.position, object3.position, factor));
}
, который перемещает пинг-понг шара между позициями object1
и object2
, но только в плоскости.
Предполагая, что на данный момент объекты будут перемещаться только в плоскости XZ и никогда не будут иметь различную позицию Y , чтобы получить кривую с высотой, которую можно рассматривать отдельно: - интерполировать между обеими позициями, как и раньше - отдельно вычислять позицию Yс синусом или любой другой функцией математической кривой - для реалистичной физики, вероятно, скорее парабола на самом деле
Может выглядеть так
public class Example : MonoBehaviour
{
public Rigidbody object1;
public Transform object2;
public Transform object3;
// adjust in the Inspector
public float speed = 1;
public float Amplitude = 0;
// Just for debug
[Range(0, 1)] [SerializeField] private float linearFactor;
[SerializeField] private float yPosition;
private void FixedUpdate()
{
// This always returns a value between 0 and 1
// and linearly pingpongs forth and back
linearFactor = Mathf.PingPong(Time.time * speed, 1);
// * Mathf.PI => gives now a value 0 - PI
// so sinus returns correctly 0 - 1 (no need for +1 and /2 anymore)
// then simply multiply by the desired amplitude
var sinus = Mathf.Sin(linearFactor * Mathf.PI);
yPosition = sinus * Amplitude;
// As before interpolate between the positions
// later we will ignore/replace the Y component
var position = Vector3.Lerp(object2.position, object3.position, linearFactor);
object1.MovePosition(new Vector3(position.x, yPosition, position.z));
}
}
![enter image description here](https://i.stack.imgur.com/on4g4.gif)
При желании вы также можете попробовать добавить некоторый сброс в направлении Y, чтобы сделать вертикальное движение более реалистичным (замедление при достижении пика).Я попробовал немного, используя инвертированный SmoothStep
как
// just for debug
[Range(0, 1)] [SerializeField] private float dampedSinusFactor;
[Range(0, 1)] [SerializeField] private float linearFactor;
[SerializeField] private float yPosition;
private void FixedUpdate()
{
// Use two different factros:
// - a linear one for movement in XZ
// - a smoothed one for movement in Y (in order to slow down when reaching the peak ;) )
linearFactor = Mathf.PingPong(Time.time * speed, 1);
dampedSinusFactor = InvertSmoothStep(linearFactor);
// * Mathf.PI => gives now a value 0 - PI
// so sinus returns correctly 0 - 1 ()
// then simply multiply by the desired amplitude
var sinus = Mathf.Sin(dampedSinusFactor * Mathf.PI);
yPosition = sinus * Amplitude;
// later we will ignore/replace the Y component
var position = Vector3.Lerp(object2.position, object3.position, linearFactor);
object1.position = new Vector3(position.x, yPosition, position.z);
}
// source: https://stackoverflow.com/a/34576808/7111561
private float InvertSmoothStep(float x)
{
return x + (x - (x * x * (3.0f - 2.0f * x)));
}
Однако для медленных движений это выглядит немного странно.Но вы можете придумать любую другую математическую кривую, которая приводит к ожидаемому поведению для x=[0,1]
;)
![enter image description here](https://i.stack.imgur.com/Dq6SW.gif)