0

I am trying to loop a list of objects (Ads) in order to move them one after another to their target position (which is Vector3(0,0,0)). The issue is that they all move at the same time instead of individually. Not sure what I am doing wrong and its been a couple hours of searching forums and experimenting with foreach loops and IEnumerators. Any help is greatly appreciated.

Script 1 (AdStartBoard)

//////////////////// Script 1 (AdStartBoard) /////////////////////////////
// This first script works, I just posted it for background information
// Script#2 is below and is the one giving me issues
public List<GameObject> ads = new List<GameObject>();
public List<RectTransform> adRectTransforms = new List<RectTransform>();
public List<SpriteRenderer> adSpriteRenderers = new List<SpriteRenderer>();
public List<Vector3> adStartingPosition = new List<Vector3>();
public List<float> adStartingRotation = new List<float>();
private List<Vector2> adStartingSize = new List<Vector2>();

// At Start, 7 ads will be randmly placed across a canvas background 
private void Start()
        {
            
            DeterminePositionsRow();
            for (int i = 0; i < transform.childCount; i++)
            {
                LeanTween.move(adRectTransforms[i], adStartingPosition[i], timeToStart);
                LeanTween.rotateAround(ads[i], Vector3.forward, adStartingRotation[i], timeToStart);
                adSpriteRenderers[i].size = adStartingSize[i];
                LeanTween.alpha(ads[i], 1f, timeToStart);
            }       
        }

// This function will handle the random positions for the ads 
 public void DeterminePositionsRow()
        {
            int numAdsRowOne = (transform.childCount / 2);
            int numAdsRowTwo = transform.childCount - numAdsRowOne;
            float rowOneGap = (Screen.width * percentageScreenWidthToFill) / numAdsRowOne;
            float rowTwoGap = (Screen.width * percentageScreenWidthToFill) / numAdsRowTwo;

            for (int i = 0; i < transform.childCount; i++)
            {
                if (i < numAdsRowOne)
                {
                    adStartingPosition.Add(new Vector3((i + 1) * rowOneGap - ((rowOneGap * numAdsRowOne + averageAdWidth) / 2f) +       Random.Range(xMin, xMax), Random.Range(rowOneYMin, rowOneYMax), 0f));
                }
                else
                {
                    adStartingPosition.Add(new Vector3((i + 1 - numAdsRowOne) * rowTwoGap - ((rowTwoGap * numAdsRowTwo + averageAdWidth) / 2f) + Random.Range(xMin, xMax), Random.Range(rowTwoYMin, rowTwoYMax), 0f));
                }
                adStartingRotation.Add(Random.Range(rotateMin, rotateMax));
                float newSize = Random.Range(sizeMin, sizeMax);
                adStartingSize.Add(new Vector2(newSize, newSize));
            }
        }

Script 2 - Ad Tweener

//////////////////////// Script 2 ///////////////////////////////////
AdStartBoard adStartBoardScript;
private List<Vector3> adInitalLocations = new List<Vector3>();
private List<float> adInitalRotation = new List<float>();
private List<RectTransform> adRectTransforms = new List<RectTransform>();
private List<GameObject> adObjects = new List<GameObject>();
private RectTransform currentAd;
private RectTransform previousAd;

private void Awake()
        {
            adStartBoardScript = GetComponent<AdStartBoard>();
            adInitalLocations = adStartBoardScript.adStartingPosition;
            adInitalRotation = adStartBoardScript.adStartingRotation;
            adRectTransforms = adStartBoardScript.adRectTransforms;
            adObjects = adStartBoardScript.ads;
            
        }

private void Start()
        {
            //Debug Tools to see if Script 2 gets the correct values from Script 1
            foreach (Vector3 pos in adInitalLocations)
            {
                Debug.Log("Starting Ad Position is: " + pos);
            }
           
            // Here I want to loop thru the Ads List to move the ads to its target Position 
            // one by one, but they all move at the same time instead.
            for(int i = 0; i < adStartBoardScript.ads.Count; i++)
            {
                LeanTween.move(adObjects[i], targetPosition, moveTime);
                // For now there is only 7 ads and I can get them to work if I do it manually...
                // (ad[0], ad[1], etc) but over time I will have dozens of ads I want to 
                // loop thru individually and I am unable to create a proper for loop to do so.
                
                // The main idea is to get the starting position from Script#1 and move the 
                // ad to target position in Script#2
                
                // The target position is center of screen (Vector3(0,0,0))
                
                // Once an individal Ad has moved to its target position, the goal is to have 
                // it move back to its original place from Script#1 (adStartingPosition) 
                // creating an infinite loop of ads rotating to center and back one after another.
                
                // any help is appreciated 
                
            }
        }
ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86
Don Chico
  • 3
  • 1

1 Answers1

1

You trigger all movements at the same frame (in Start()). If your tweener allows a delay, you can use that one, otherwise you have to use a Coroutine to trigger them delayed:

private void Start()
{
    StartCoroutine(TriggerMovement(1));
}

private IEnumerator TriggerMovement(float delayPerObject)
{
    var wait = new WaitForSeconds(delayPerObject);
    for(int i = 0; i < adStartBoardScript.ads.Count; i++)
    {
        LeanTween.move(adObjects[i], targetPosition, moveTime);
        yield return wait;
    }
}

However if you want to move them in a ping pong manner you can take a look at Mathf.PingPong. Do not use a tweener, but simply add a custom script controling the movement of your ad to each ad and have them do something like transform.position = Vector3.Lerp(startPos, targetPos, Mathf.PingPong(Time.time + delay, 1)).

Thomas
  • 1,225
  • 7
  • 16
  • Thank you! This works and they center individually now. If I wanted to add a delay for the Ad to stay in the center, lets say for 5 seconds before moving to the next Ad. Would I add a bool if-statement after "yield return wait" with a new float delay object such as `if(targetPosition == true) {yield return waitNew};`? or would I need a separate coroutine – Don Chico Nov 20 '20 at 08:04
  • LeanTween library provides a LoopPingpong method that I can implement, but thank you for the suggestion! – Don Chico Nov 20 '20 at 08:07
  • Do you want to wait before triggering the next ad or do you want to wait before the ad moves back from the center? The first is true for delayPerObject > moveTime, the second one has to be done in the ping pong logic, not the trigger logic. – Thomas Nov 20 '20 at 08:14
  • The second one option is what I want to implement. I do not think LeanTween allows altering pingpong logic and i unfortunately need the leantween assets. unless I can use both Leantween to move and mathf.pingpong to handle the pingpong logic – Don Chico Nov 20 '20 at 08:20
  • I would suggest adding a custom script to each ad handling the movement. In there you can just: "leanTweenNoPingPong to center" => "wait" => "leanTweenNoPingPongBackToOriginalPos" – Thomas Nov 20 '20 at 08:26