How to make a 2D object move smoothly in a random direction for a set amount of time.

Hello! I am currently mucking about with a 2D, top down scene trying to get some very basic AI behaviour going.

The aim is to make this pig wait for a short time, then perform one of two behaviours (move or oink), then repeat.

The waiting and the oinking I’ve figured out already. The trouble I’m having is with getting it to move smoothly in a random direction. I can only make it teleport from one point to the next instantly!
{

// Used to make the pig play a variety of oinking sound effects.
private AudioSource pigAudioSource;
public List<AudioClip> oinks;

// The minimum and maximum amounts of time that the pig can stand still between behaviours.
public float idleMin;
public float idleMax;

// The speed at which the pig will move. (Not yet used.)
public float moveSpeed;


// Get the necessary component(s) and start the pig's behaviour coroutine.
void Start()
{
    pigAudioSource = GetComponent<AudioSource>();
    
    StartCoroutine(IdleBehaviour());
}

IEnumerator IdleBehaviour()
{
    while (true)
    {
        // Waits a random number of seconds within the range of idleMin and idleMax.
        float seconds = Random.Range(idleMin, idleMax);
        yield return new WaitForSeconds(seconds);

        // Generates another random number used to decide between moving and oinking.
        int behaviour = Random.Range(0, 2);
        switch (behaviour)
        {
            case 0: // Pauses this coroutine while processing the pig's movement.
                yield return IdleMovement();
                break;
            case 1: // Selects then plays a random oink sound effect.
                Debug.Log("Oink!");
                int oink = Random.Range(0, oinks.Count);
                pigAudioSource.PlayOneShot(oinks[oink]);
                break;
        }
    }
}

// To do: Make the pig move in a random direction for a short amount of time, then stop.
IEnumerator IdleMovement()
{
    Debug.Log("If I could move, I'd be doing it right now!");
    yield return null;
}

I tried using a for loop inside the IdleMovement coroutine to run transform.Translate until a set amount of time had been reached, but I couldn’t get that to work. I also tried getting the pig’s RigidBody and using AddForce on it but I didn’t know how to then stop that force after an amount of time had passed.

Any suggestions about how I might do this? I also wonder if I need to be using two coroutines.

You can try something like this

 IEnumerator IdleMovement()
 {
    float moveTime = 2f;
    float speed = 1f;
    Vector3 moveDirection = Random.insideUnitCircle.normalized;

    while(moveTime > 0){
        moveTime -= Time.deltaTime;
        rigidbody.MovePosition(transform.position + speed * moveDirection * Time.deltaTime);
        yield return null;
    }
 }

You can change the move time and direction however you want

For anyone curious, I figured out an alternate way to approach this problem using several Booleans and no coroutines.

private string behaviour;
private bool needsNewBehaviour = true;
private bool currentlyMoving = false;
private bool currentlyIdling = false;

// Used to make the pig play a variety of oinking sound effects.
private AudioSource pigAudioSource;
public List<AudioClip> oinks;

// Floats used to process the pig's move behaviour.
public float moveSpeed;
private float moveLength;
public float moveLengthMin;
public float moveLengthMax;
private float moveTime;
public float moveDist;
private Vector2 moveDirection;


// Floats used to process the pig's idle behaviour.
public float idleMin;
public float idleMax;
private float idleLength;
private float idleTime;

// Sprite Renderer
public SpriteRenderer pigSpriteRenderer;

// Animator
public Animator pigAnimator;

private void Start()
{
    pigAudioSource = gameObject.GetComponent<AudioSource>();
}

void Update()
{
    if (needsNewBehaviour)
    {
        behaviour = ChooseBehaviour();
        needsNewBehaviour = false;
    }

    switch (behaviour)
    {
        case "oink":
            if (!pigAudioSource.isPlaying)
            {
                int oink = Random.Range(0, oinks.Count);
                pigAudioSource.PlayOneShot(oinks[oink]);
                Debug.Log("The pig oinked at " + Time.time);
            }
            needsNewBehaviour = true;
            
            break;
        
        case "move":
            if (!currentlyMoving)
            {
                moveTime = 0;
                moveLength = Random.Range(moveLengthMin, moveLengthMax);
                moveDirection = new Vector2(Random.Range(-moveDist, moveDist), Random.Range(-moveDist, moveDist));
                Debug.Log("The pig started moving at " + Time.time);
                currentlyMoving = true;
            }

            if (moveTime < moveLength)
            {
                if (moveDirection.x < 0)
                { pigSpriteRenderer.flipX = true; }
                else if (moveDirection.x > 0)
                { pigSpriteRenderer.flipX = false; }
                transform.Translate(moveDirection * moveSpeed * Time.deltaTime);
                moveTime += Time.deltaTime;
                pigAnimator.SetFloat("Speed_f", 1);
            }
            else
            {
                Debug.Log("The pig finished moving at " + Time.time);
                currentlyMoving = false;
                needsNewBehaviour = true;
                pigAnimator.SetFloat("Speed_f", 0);
            }

            break;
        
        case "idle":
            
            if (!currentlyIdling)
            {
                idleTime = 0;
                idleLength = Random.Range(idleMin, idleMax);
                Debug.Log($"The pig is going to start idling at {Time.time} for {idleLength} seconds.");
                currentlyIdling = true;
            }
            
            if (idleTime < idleLength)
            {
                idleTime += Time.deltaTime;
            }
            else
            {
                Debug.Log("The pig finished idling at" + Time.time);
                currentlyIdling = false;
                needsNewBehaviour = true;
            }

            break;
    }
}

// Randomly returns one of several strings describing a possible piggy behaviour.
string ChooseBehaviour()
{
    int behaviour = Random.Range(0, 3);
    switch (behaviour)
    {
        case 0:
            return "oink";
        case 1:
            return "move";
        default:
            return "idle";
    }
}