0
\$\begingroup\$
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public class MoveObjects : MonoBehaviour
{
    public GameObject[] objectsToMove;
    public float stepsPerSecond = 1f;
    public float speed = 3f;

    private Vector3 trackStart;
    private Vector3 trackEnd;
    private float phase = 0f;

    // Use this for initialization
    public void Init()
    {
        objectsToMove = GameObject.FindGameObjectsWithTag("Stair");
        // Infer the start & end positions of the track 
        // from the position of the first & last steps
        trackStart = objectsToMove[0].transform.position;
        int count = objectsToMove.Length;
        var span = objectsToMove[count - 1].transform.position - trackStart;
        // The track ends one more step distance after the last step.
        // (So the last step has some distance to travel before it wraps)
        trackEnd = trackStart + (count + 1) * span / count;
    }

    // Update is called once per frame
    void Update()
    {
        if (objectsToMove != null && objectsToMove.Length > 0)
        {
            MoveRealistic();
            //MoveRegular();
        }
    }

    private void MoveRealistic()
    {
        float n = (float)objectsToMove.Length;

        foreach (GameObject step in objectsToMove)
        {
            float step_x = step.transform.position.x;
            float max_x = (n - 1f) * 24f; // The javascript has this "24", which is based on the width of the step + the outline.
            step_x = Mathf.Repeat(step_x + speed * Time.time, max_x);

            float r = 5f;
            float x_for_atan = step_x * r / max_x - r / 2f;
            if (step_x < 3f * 24f)
            {
                x_for_atan = -r / 2f + .5f;
            }
            if (step_x >= max_x - 3f * 24f)
            {
                x_for_atan = r / 2f - .5f;
            }

            float step_y = 180f + 120f * (float)Math.Atan(x_for_atan);

            step.transform.position = new Vector3(step_x, -step_y, 0);
            // negative y because the javascript uses top, which starts at 0
            // at the top, and positive goes down. Unity goes the other direction.
        }
    }

    private void MoveRegular()
    {
        float divisor = 1f / objectsToMove.Length;

        // Compute the current phase of the escalator, 
        // from 0 (1st step at track start) to 1 (1st step at track end)
        phase = Mathf.Repeat(phase + stepsPerSecond * divisor * Time.deltaTime, 1f);


        // Place each step a proportional distance along the track.
        for (int i = 0; i < objectsToMove.Length; i++)
        {
            float t = Mathf.Repeat(phase + i * divisor, 1f);
            objectsToMove[i].transform.position = Vector3.Lerp(trackStart, trackEnd, t);
        }
    }
}

Whne I'm using the MoveRealistic I'm using a break point on the line:

step_x = Mathf.Repeat(step_x + speed * Time.time, max_x);

I see that speed value is 3 and max_x value is 216. The only value that change is the step_x what make the speed to change to very very high. And I want a static speed(3).

Another problem is that each time one object(step) is moving when he finished moving the next one move. But I want to create a escalator stairs effect using this method and the objects should move all the same time like it is in this jsfiddle: And this is where I have take the code from and converted it to unity csharp:

jsfiddle

Last problem is that the objects the step's(stairs) moving in other position/s and not on their original position/s.

This is the steps/stairs original position. And where they should move.

steps

And this is where they are moving when using the MoveRealistic method:

steps

When using the MoveRegular method they are moving fine but I want to be able to use also the MoveRealistic method like in the jsfiddle.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ You might find asking about your actual goal "how can I animate an escalator?" is clearer than "How can I keep the same speed to be static speed and how to move the objects all at the same time?" \$\endgroup\$
    – DMGregory
    Nov 18, 2018 at 15:50

1 Answer 1

1
\$\begingroup\$

As I mentioned in my previous answer, if you want to get a curve at the top and bottom of your escalator, I'd recommend using an AnimationCurve. That way you can precisely control the shape you want.

Here's a modified example using an animation curve instead of a Lerp to space out the steps.

Animated gif of alternating white & red cubes descending like steps of an escalatorSame animation, from a 3/4 view instead of side-on

public class Escalator : MonoBehaviour {

    public Transform[] steps;
    public AnimationCurve curve;
    public float stepsPerSecond = 1f;

    Vector3 trackStart;
    Vector3 horizontalTravel;
    float verticalTravel;
    float divisor;

    float phase = 0f;      

    void Start() {
        trackStart = steps[0].position;
        int count = steps.Length;
        var span = steps[count - 1].position - trackStart;

        divisor = 1f / count;
        horizontalTravel = (count + 1) * span * divisor;
        horizontalTravel.y = 0f;

        verticalTravel = span.y;
    }

    void Update() {
        phase = Mathf.Repeat(phase + stepsPerSecond * divisor * Time.deltaTime, 1f);

        for (int i = 0; i < steps.Length; i++) {
            float t = Mathf.Repeat(phase + i * divisor, 1f);
            // Get the height of the curve at this step.
            float curveHeight = curve.Evaluate(t) * verticalTravel;

            steps[i].position = trackStart                // First step
                              + horizontalTravel * t      // evenly spaced horizontal
                              + curveHeight * Vector3.up; // curving vertical
        }
    }
}

This assumes your animation curve runs from 0 to 1 on the horizontal, and 0 to 1 on the vertical. (It works for "down" escalators too - it takes its direction from the offset between the first and the last step, so you don't need to change the curve itself)

Here's an example of how I set up my curve:

Screenshot of curve editor in Unity

\$\endgroup\$
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .