using UnityEngine;
using UnityEngine.UI;

public class PlayerGrindController : MonoBehaviour
{
    [Header("Grind Settings")]
    public float grindSpeed = 0.1f;
    public bool isGrinding;

    public Transform grindPosition; // The target position on the grindable object
    public Transform localGrindDirection; // The direction of grinding (if needed)

    [Header("Grind UI")]
    public Slider grindBalanceSlider; // Assign this in the inspector

    private float grindBalance; // Represents the current balance while grinding
    private float grindBalanceTime = 4f; // Time after which the grind balance changes direction
    private bool continueGrinding; // Indicates if grinding should continue forward
    private bool intermediateMode; // Determines if the intermediate position is active
    private Transform intermediatePoint; // Optional intermediate grinding point

    private float balanceValue; // Randomly set value used to simulate balance change

    private void Update()
    {
        if (isGrinding)
        {
            GrindBalanceManager();
            GrindMovement();
        }
    }

    private void GrindBalanceManager()
    {
        // Modify the slider value over time and check if the player keeps their balance
        grindBalance += Time.deltaTime;
        if (grindBalance >= grindBalanceTime)
        {
            grindBalance = 0f;
            balanceValue = Random.Range(-30, 30); // Simulate a balance value change
        }

        // Example logic to move the grind balance slider towards the balanceValue
        grindBalanceSlider.value = Mathf.MoveTowards(grindBalanceSlider.value, balanceValue, 10f * Time.deltaTime);
    }

    private void GrindMovement()
    {
        if (continueGrinding)
        {
            // If in intermediate mode, move towards the intermediate point first
            if (intermediateMode)
            {
                if (Vector3.Distance(transform.position, intermediatePoint.position) <= 1.5f)
                {
                    intermediateMode = false;
                }
                else
                {
                    transform.position = Vector3.MoveTowards(transform.position, intermediatePoint.position, grindSpeed * Time.deltaTime);
                }
            }
            // Otherwise, move towards the main grind direction
            else
            {
                transform.position = Vector3.MoveTowards(transform.position, localGrindDirection.position, grindSpeed * Time.deltaTime);
            }
        }
    }

    public void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("GrindableSurface"))
        {
            StartGrinding(other.transform);
        }
    }

    public void OnTriggerExit(Collider other)
    {
        if (other.CompareTag("GrindableSurface"))
        {
            EndGrinding();
        }
    }

    public void StartGrinding(Transform grindSurface)
    {
        isGrinding = true;
        continueGrinding = true;
        // Assign references or find child objects on the grindSurface to set up grinding
        grindPosition = grindSurface.GetChild(0); // Set this according to your grind object setup
        intermediatePoint = null; // Set this according to your grind object setup
        intermediateMode = false; // Set this according to your grind object setup
        localGrindDirection = grindSurface; // Example value, replace with actual alignment logic

        grindBalanceSlider.gameObject.SetActive(true); // Show the slider when grinding starts
    }

    public void EndGrinding()
    {
        isGrinding = false;
        continueGrinding = false;
        intermediateMode = false;

        grindBalanceSlider.gameObject.SetActive(false); // Hide the slider when grinding ends
    }
}

How do I initiate the grind

Script 2
using UnityEngine;

public class Grind : MonoBehaviour
{
	public enum Direcao
	{
		ZY = 0,
		XY = 1
	}

	[Header("Info")]
	[SerializeField]
	private GameObject player;

	private Vector3 playerTr;

	[SerializeField]
	private GameObject pos;

	private Vector3 posMax;

	private Vector3 posMin;

	public Direcao direcao;

	[SerializeField]
	private float angleMax = 65f;

	[SerializeField]
	private bool lado;

	public bool dir;

	[Space(10f)]
	[Header("Lado A")]
	[SerializeField]
	private GameObject a;

	[SerializeField]
	private float aDis;

	[SerializeField]
	private float aAngle;

	[SerializeField]
	private bool aVer;

	[Space(10f)]
	[Header("Lado B")]
	[SerializeField]
	private GameObject b;

	[SerializeField]
	private float bDis;

	[SerializeField]
	private float bAngle;

	[SerializeField]
	private bool bVer;

	private void Update()
	{
		LadoVer();
		dir = lado;
		if (Vector3.Distance(base.transform.position, player.transform.position) < 12f)
		{
			posQueda();
		}
		else
		{
			pos.transform.localPosition = new Vector3(0f, 0f, 0f);
		}
	}

	private void LadoVer()
	{
		aDis = Vector3.Distance(player.transform.position, a.transform.position);
		bDis = Vector3.Distance(player.transform.position, b.transform.position);
		aAngle = Vector3.Angle(player.transform.forward, a.transform.position - player.transform.position);
		bAngle = Vector3.Angle(player.transform.forward, b.transform.position - player.transform.position);
		if (aAngle < angleMax)
		{
			aVer = true;
		}
		else
		{
			aVer = false;
		}
		if (bAngle < angleMax)
		{
			bVer = true;
		}
		else
		{
			bVer = false;
		}
		if (aVer && bVer && aDis > bDis)
		{
			lado = true;
		}
		else if (aVer && !bVer)
		{
			lado = true;
		}
		else if (bVer && aVer && bDis > aDis)
		{
			lado = false;
		}
		else if (bVer && !aVer)
		{
			lado = false;
		}
		else if (bDis > aDis)
		{
			lado = false;
		}
		else if (aDis > bDis)
		{
			lado = true;
		}
	}

	private void posQueda()
	{
		playerTr = player.transform.position;
		posMax = a.transform.position;
		posMin = b.transform.position;
		if (direcao == Direcao.XY)
		{
			pos.transform.position = new Vector3(playerTr.x, pos.transform.position.y, pos.transform.position.z);
			pos.transform.localPosition = new Vector3(pos.transform.localPosition.x, 0f, pos.transform.localPosition.z);
		}
		else if (direcao == Direcao.ZY)
		{
			pos.transform.position = new Vector3(pos.transform.position.x, pos.transform.position.y, playerTr.z);
			pos.transform.localPosition = new Vector3(pos.transform.localPosition.x, 0f, pos.transform.localPosition.z);
		}
	}
}