Home > OS >  How can I ensure that an object using a cosine equation to determine speed meets its lowest valley a
How can I ensure that an object using a cosine equation to determine speed meets its lowest valley a

Time:01-30

I'm working on a game for game jam and part of it is to make platforms that move smoothly. They slow down at the ends of their movement before turning around. The platforms simply move side to side or up and down between two waypoints(which are just empty transforms). I have code that uses cosine to determine the speed which works well except it doesn't align with the waypoints, the platforms tend to slow and change direction before ever reaching the waypoints. I need a way to use the distance between the waypoints as a variable in determining how the cosine equation changes speed so that the platforms slow and reverse direction exactly at the waypoints.

Here is what I have so far:

void Side_to_side()
    {
        if (waypointIndex < horWaypoints.Length)
        {
            platformSpeed = (1f * (float)Mathf.Cos(2f * (float)Mathf.PI * 1f * totalTime));
            Vector3 targetPosition = horWaypoints[waypointIndex].position;
            float delta = platformSpeed * Time.deltaTime;
            transform.position = Vector2.MoveTowards(transform.position, targetPosition, delta);
            if (transform.position.x == targetPosition.x && transform.position.y == targetPosition.y)
            {
                if (waypointIndex   1 == horWaypoints.Length)
                    waypointIndex = 0;
                else
                    waypointIndex  ;

            }
        }
        else
        {
            waypointIndex = 0;
        }
        //Translate platform back and forth between two waypoints
    }

As I have said this code moves the platforms in the motions i want but they don't use the waypoints as turn around points. I understand I could do away with the waypoints and just calculate how far I would like each platform to go before turning around individually but that would take time to do it for each platform whereas I'd like to quickly put down waypoint pairs for them to use and the script calculates what the perfect values would be to match the waypoint locations.

CodePudding user response:

If I understand you correctly you want to move an object forth and back between exactly two positions and apply some smoothing to the movement.

I would rather use a combination of Vector2.Lerp with a Mathf.PingPong as factor and you can then apply ease in and out using additionally Mathf.SmoothStep.

This could look like e.g.

public Transform startPoint;
public Transform endPoint;
// Desired duration in seconds to go exactly one loop startPoint -> endPoint -> startPoint
public float duration = 1f;

private void Update ()
{
    // This will move forth and back between 0 and 1 within "duration" seconds
    var factor = Mathf.PingPong(Time.time / (2f * duration), 1f);
    // This adds additional ease-in and -out near to 0 and 1
    factor = Mathf.SmoothStep(0, 1, factor);
    // This interpolates between the given positions according to the given factor
    transform.position = Vector2.Lerp(startPoint, endPoint, factor);
}

you could of course still use cosine if necessary, basically any function that returns a value between 0 and 1. You just have to use the correct multiplier in order to achieve the desired duration in seconds.


Note: Typed on the phone and not 100% sure on the math but I hope the idea gets clear

  •  Tags:  
  • Related