How can I slow down the process of automoving

I’m not a native English. Sorry for my poor expressions.

I’m making a HanoiTower Game now. And I want to have a Automove function(method?).
the following is the code.

//  function:   
    //  parameters:
    //      a:      current pole
    //      b:      
    //      c:      goal pole
    //      size:       the number of stones needed to be moved
public void AutoMove(int a, int b, int c, int size)
    {
        if (size == 1)  //      one object
        {
            TempStone = Poles[a].GetTopStone(); //  select the top stone in the Pole[a]
            TempStone.PickUp(); //      pick up it
            while (Mathf.Abs(TempStone.targetY - TempStone.transform.position.y) > 0.1f)
            {
                TempStone.UpdatePosition(); // this will update the position of the selected stone (operations above won't move the stone visibly, but this will)
                // Pause_In_a_Second();
            }
            TempStone.UpdatePosition(); //  update the position to make the stone located at the accurate position
            // Invoke("Pause_In_a_Second", 2f);
            if (c - a > 0)  //      goal position is in the right of the current position
            {
                for (int i = 0; i < c - a; i++)   //     times needed to move the stone
                {
                    TempStone.MoveRight();  //  move right
                    while (Mathf.Abs(TempStone.targetX - TempStone.transform.position.x) > 0.1f)
                    {
                        TempStone.UpdatePosition();     //  update the position
                        // Pause_In_a_Second();
                    }
                    TempStone.UpdatePosition();     // make the stone located at the accurate position
                    // Pause_In_a_Second();
                    // Invoke("Pause_In_a_Second", 2f);
                }
            }
            else    //    in the left
            {
                for (int i = 0; i < a - c; i++)   //      times needed to move the stone
                {
                    TempStone.MoveLeft();
                    while (Mathf.Abs(TempStone.targetX - TempStone.transform.position.x) > 0.1f)
                    {
                        TempStone.UpdatePosition();
                        Pause_In_a_Second();
                    }
                    TempStone.UpdatePosition();
                    // Pause_In_a_Second();
                    // Invoke("Pause_In_a_Second", 2f);
                }
            }
            Poles[a].RemoveTopStone();  //      remove the stone in the original pole
            Poles[c].AddStone(TempStone);   //      add the stone in the goal pole
            TempStone.Drop(Poles[c].GetPoleTopPosition());  //  now we can drop the stone
            while (Mathf.Abs(TempStone.targetY - TempStone.transform.position.y) > 0.1f)
            {
                TempStone.UpdatePosition(); //  make the stone move visibly
                // Pause_In_a_Second();
            }
            TempStone.UpdatePosition();
            // Pause_In_a_Second();
            // Invoke("Pause_In_a_Second", 2f);
        }
        else    // recursion
        {
            AutoMove(a, c, b, size - 1);
            // Invoke("Pause_In_a_Second", 2f);

            AutoMove(a, b, c, 1);          
            // Invoke("Pause_In_a_Second", 2f);

            AutoMove(b, a, c, size - 1);
            // Invoke("Pause_In_a_Second", 2f);
            // Pause_In_a_Second();
        }
    }

    public void Pause_In_a_Second()
    {
        while (Mathf.Abs(Time.time-last_time) < 0.1f)
            ;
        last_time = Time.time;
    }

my question is that when I click the button of play game in Unity, all of the stones will suddenly move from the original pole to the goal pole. I have no idea how to slow down the process to make it more clear for audience or players.

and I think that I need help about how to slow down the while loop for TempStone.UpdatePosition(), because this will move the stone visibly

while (Mathf.Abs(TempStone.targetX - TempStone.transform.position.x) > 0.1f)
                    {
                        TempStone.UpdatePosition();     //  update the position
                        // Pause_In_a_Second();
                    }

I have tried Pause_In_a_Second(), which should have been a time-consuming function and if I use it, I will have enough time for the stone moving and players will see the process clearly. but the reality is that I failed to start the game, or maybe the game is always in the loop. So terribly!

I have tried Thread.sleep(), but in vain. The game won’t work.

I have also tried Invoke(“a randomly function”, 1f); but it didn’t work.

It’s the first time I have tried to ask help from others in English and in a English forum. Too hard for me to think up expressions. :frowning:

I would appreciate it if someone could help me, a poor undergraduate.

three code files are attached.

(the language Chinese is banned. too bad)

5891420–628124–GameController.cs (5.94 KB)
5891420–628127–PoleControl.cs (1.55 KB)
5891420–628130–StoneControl.cs (3.43 KB)

Unity’s “magic functions” like Start, Update, etc. are all executed on the main Unity thread. If you pause that thread, it freezes the entire game. (Unity is waiting for your function to finish so that it can continue with the next thing.)

If you want, you can explicitly create your own threads, and then you can do things like Thread.sleep in them. However, most of the UnityEngine namespace is not threadsafe and shouldn’t be accessed from outside the main thread, so this is mostly useful for math-heavy threads that just do a bunch of calculations and then save their results somewhere for the main thread to read.

The easiest option to do something like you describe is to use coroutines. These execute on the main thread, but they can temporarily yield control back to the Unity engine and then resume execution at a later time.

Alternately, you can restructure your code so that instead of having one function that does the entire move, you have a function that just does one frame of the move and records how far it got, so that next frame you can call it again and do another tiny piece of movement. This is a more powerful approach because it can react to other things happening in your game while the move is in progress, but it’s a bit harder to wrap your head around.

thank you for your idea! it’s surprising that you replied to me just 12 minutes after I released the question. Your idea lightens my road(is the expression right?:face_with_spiral_eyes:)

I will search for coroutines and might try the last option. Thank you again!