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
}
}
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))
.