Search code examples
c#unity-game-enginegameobjectlerp

Unity - Move (Shuffle) multiple GameObject from their current position to a new destination position


I am trying to do a shuffle functionality so I can change the order of multiple GameObjects.

I have multiple "letters" (GameObjects) in a circle and when I click "Shuffle" I just need to reorder their position but showing the letter moving to it's new position.

enter image description here

I tried: Vector3.Lerp(startPosition, targetPosition, Time.time/2)

or

Vector3.MoveTowards(startPosition, targetPosition, Time.time/2)

but it doesn't move correctly.

I manage to do the movement using this:

Vector3 tempPosition = object1.transform.position; object1.transform.position = object2.transform.position; object2.transform.position = tempPosition;

but I can only move 2 GameObjects without showing any movement.


Solution

  • Get a list of all letters, use a coroutine to move the letters, and at the beginning of the coroutine, figure out where each letter is moving from and moving to, then use lerp in each frame to set the position:

    public float letterMoveTime = 1f; // duration of shuffle movement (in seconds)
    List<GameObject> letters;
    IEnumerator shuffleCoroutine;
    
    void Awake()
    {
        letters = new List<GameOobject>();
        letters.AddRange(GameObject.FindGameObjectsWithTag("Letter"));
    
        shuffleCoroutine = null;
    }
    
    public void StartShuffle() // call this on button click
    {
        if (shuffleCoroutine != null) return;
    
        shuffleCoroutine = DoShuffle();
        StartCoroutine(shuffleCoroutine);
    }
    
    IEnumerator DoShuffle()
    {
        List<Vector3> startPos = new List<Vector3>();
        List<Vector3> endPos = new List<Vector3>();
        foreach (GameObject letter in letters)
        {
            startPos.Add(letter.transform.position);
            endPos.Add(letter.transform.position);
        }
    
        // shuffle endPos
        for (int i = 0 ; i < endPos.Count ; i++) {
             Vector3 temp = endPos[i];
             int swapIndex = Random.Range(i, endPos.Count);
             endPos[i] = endPos[swapIndex];
             endPos[swapIndex] = temp;
         }
    
         float elapsedTime = 0f;
    
         while (elapsedTime < letterMoveTime)
         {
             // wait for next frame
             yield return null;
    
             // move each letter
             elapsedTime  = Mathf.Min(letterMoveTime, elapsedTime+Time.deltaTime);
             float t = elapsedTime / letterMoveTime;
    
             for (int i = 0 ; i < startPos.Count ; i++) {
                 letter[i].transform.position = Vector3.lerp(startPos[i],endPos[i],t);
             }
         }
    
         // allow shuffling to occur again
         shuffleCoroutine = null;
    }