How to record moves and then play them frame by frame after a button is clicked?

I’m trying to record the functions that have been called, and play them frame by frame after a button is clicked.

For example, I have four buttons here (the triangles) to control my player’s movements.

alt text

public void MoveRight() {

    float x = playerRb.transform.position.x;
    float y = playerRb.transform.position.y;
    playerRb.transform.position = new Vector3(x + 1, y, playerRb.transform.position.z);
}

public void MoveLeft() {

    float x = playerRb.transform.position.x;
    float y = playerRb.transform.position.y;
    playerRb.transform.position = new Vector3(x - 1, y, playerRb.transform.position.z);
}

public void MoveUp() {

    float x = playerRb.transform.position.x;
    float y = playerRb.transform.position.y;
    playerRb.transform.position = new Vector3(x, y + 1, playerRb.transform.position.z);
}

public void MoveDown() {

    float x = playerRb.transform.position.x;
    float y = playerRb.transform.position.y;
    playerRb.transform.position = new Vector3(x, y - 1, playerRb.transform.position.z);
}

Is there a way to record the order of buttons that I have clicked, and then call those functions after the confirm button is clicked?

Simple way is probably just to keep a list of all the past moves that gets added to each time the player moves, then read that list out (here I’m using a list of strings, but no reason it couldn’t be a number or Enum)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MoveScript : MonoBehaviour
{
	public Rigidbody playerRb;
	
	public List<string> moves = new List<string>(){};
	
	
	public void MoveRight() 
	{
		float x = playerRb.transform.position.x;
		float y = playerRb.transform.position.y;
		playerRb.transform.position = new Vector3(x + 1, y, playerRb.transform.position.z);
		moves.Add("R");
	}
	
	public void MoveLeft() 
	{
		float x = playerRb.transform.position.x;
		float y = playerRb.transform.position.y;
		playerRb.transform.position = new Vector3(x - 1, y, playerRb.transform.position.z);
		moves.Add("L");
	}
	public void MoveUp() 
	{
		float x = playerRb.transform.position.x;
		float y = playerRb.transform.position.y;
		playerRb.transform.position = new Vector3(x, y + 1, playerRb.transform.position.z);
		moves.Add("U");
	}
	
	public void MoveDown() 
	{
		float x = playerRb.transform.position.x;
		float y = playerRb.transform.position.y;
		playerRb.transform.position = new Vector3(x, y - 1, playerRb.transform.position.z);
		moves.Add("D");
	}
}

Then once the player hits Play, just go through each item in the list and play it back, probably using a Coroutine so that you can wait between moves. (Here I’ve also added a boolean that makes sure the moves aren’t added in “Playback mode”). In theory you’d just need the button to run “PlayButton” on press, though that will depend on your implementation.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MoveScript : MonoBehaviour
{
	public Rigidbody playerRb;
	
	public List<string> moves = new List<string>(){};
	public bool playbackMode = false;
	
	
	public void MoveRight() 
	{
		float x = playerRb.transform.position.x;
		float y = playerRb.transform.position.y;
		playerRb.transform.position = new Vector3(x + 1, y, playerRb.transform.position.z);
		if(!playbackMode) moves.Add("R");
	}
	
	public void MoveLeft() 
	{
		float x = playerRb.transform.position.x;
		float y = playerRb.transform.position.y;
		playerRb.transform.position = new Vector3(x - 1, y, playerRb.transform.position.z);
		if(!playbackMode) moves.Add("L");
	}
	public void MoveUp() 
	{
		float x = playerRb.transform.position.x;
		float y = playerRb.transform.position.y;
		playerRb.transform.position = new Vector3(x, y + 1, playerRb.transform.position.z);
		if(!playbackMode) moves.Add("U");
	}
	
	public void MoveDown() 
	{
		float x = playerRb.transform.position.x;
		float y = playerRb.transform.position.y;
		playerRb.transform.position = new Vector3(x, y - 1, playerRb.transform.position.z);
		if(!playbackMode) moves.Add("D");
	}
	
	public void PlayButton()
	{
		StartCoroutine(PlayMoves());
	}
	
	IEnumerator PlayMoves()
	{
		playbackMode = true;
		foreach (string moveItem in moves)
		{
			if(moveItem == "L") MoveLeft();
			else if(moveItem == "R") MoveRight();
			else if(moveItem == "U") MoveUp();
			else if(moveItem == "D") MoveDown();
			
			yield return new WaitForSeconds(0.5f);
		}
		playbackMode = false;
	}
	
}