Moving platform - can't quite get it right
« on: February 03, 2016, 05:42:44 AM »
I'm trying to tween a series of moving platforms.  Each platform moves either up/down between 2 points or left/right between two points continuously. For sake of discussion, let's consider a horizontally moving platform. Really, I just want to move it continuously back and forth on a known line segment, easing in/out of the endpoints.  On the surface, that's easy enough. However, the complication seems to be that when the platform is instantiated, it's already (randomly) somewhere within it's motion segment. 

So, I need to create a tween that moves from the platform's initial, random position on the line to one end of the line and then back to the other end - all while easing in/out of  the line end points.

I've tried this using transform.DoPath (with a closed, 2-point path) and with a Sequence, using 2 separate transform.DoMoveX tweens. While both generally work, I can't figure out an appropriate way to deal with the random starting location of the platform.  It seems that the path always gets an extra point inserted in it (where the transform starts out) and then the easing happens around that point - which doesn't feel right.  The Sequence method also seems to suffer from similar problems with getting the easing to happen at the endpoints.

I've even tried to move the platform's transform to one end of the segment and then doing a random "goto" to advance the tween to some random position along the line prior to playing it.  However, I always seem to end up with results that are close to what I want, but not quite right.

This seems like a simple problem on the surface, but I haven't quite figured out the secret sauce.

Advice appreciated.

Re: Moving platform - can't quite get it right
« Reply #1 on: February 04, 2016, 01:02:14 AM »
OK, I finally have something that's working satisfactorily.  Here's what I'm currently using:

Code: [Select]
        float duration;
        if (Random.value < 0.5)
        {
            // Horizontal motion
            duration = Random.Range(2.5f, 4);
            transform.position = new Vector3(ScreenManager.ScreenLeftWorld, transform.position.y);
            _tween = transform.DOMoveX(ScreenManager.ScreenRightWorld, duration);
        }
        else
        {
            // Vertical motion
            duration = Random.Range(1, 2);
            float vertDist = Random.Range(.5f, 1f);
            transform.position = new Vector3(transform.position.x, transform.position.y - vertDist);
            _tween = transform.DOMoveY(transform.position.y + vertDist, duration);
        }

        _tween.SetAutoKill(false)
            .SetEase(Ease.InOutSine)
            .SetLoops(-1, LoopType.Yoyo);

        _tween.Goto(Random.Range(0, duration));
        _tween.Play();
    }

Essentially, I physically move my platform to one end of the linear motion just prior to creating a tween to the other end of the motion. Then, I set the tween to loop infinitely with an appropriate ease-type.

Next, I attempt to randomize the starting location by calling _tween.Goto(0, duration).  Which, I think, should push the start timeline to somewhere between the defined start and end.  Finally, I start the tween.

I was trying to do this with a Sequence of 2 DoMove tweens (one for both passes until I realized I could just use a loop).  Initially, I left the Sequence, but eliminated one of the 2 tweens - in favor of setting up looping.  So, basically, I had the same code as above, but with a Sequence containing only a single tween.  However, the easing did not work the same at both ends of the motion.  I'm not sure if that's expected or a bug, but it seems like it should have worked the same way.

Anyway, problem solved.