convert this unity class into a c# visual studio class.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;

[Serializable]
public class ACEStepInput
{
    public string checkpoint_path;
    public bool bf16 = true;
    public bool torch_compile = false;
    public int device_id = 0;
    public string output_path;
    public float audio_duration;
    public string prompt;
    public string lyrics;
    public int infer_step;
    public float guidance_scale;
    public string scheduler_type;
    public string cfg_type;
    public float omega_scale;
    public List<int> actual_seeds;
    public float guidance_interval;
    public float guidance_interval_decay;
    public float min_guidance_scale;
    public bool use_erg_tag;
    public bool use_erg_lyric;
    public bool use_erg_diffusion;
    public List<int> oss_steps;
    public float guidance_scale_text = 0.0f;
    public float guidance_scale_lyric = 0.0f;
}

[Serializable]
public class ACEStepOutput
{
    public string status;
    public string output_path;  // filename returned by server
    public string message;
}

public class ACEStepClient : MonoBehaviour
{
    // Server base URL (no trailing slash)
    public string serverBaseUrl = "http://localhost:8000";

    /// <summary>
    /// Start generation request.
    /// </summary>
    public void GenerateAudio(ACEStepInput input, Action<ACEStepOutput> onSuccess, Action<string> onError)
    {
        StartCoroutine(GenerateAudioRoutine(input, onSuccess, onError));
    }

    public IEnumerator GenerateAudioRoutine(ACEStepInput input, Action<ACEStepOutput> onSuccess, Action<string> onError)
    {
        string url = serverBaseUrl + "/generate";
        string jsonData = JsonUtility.ToJson(input);
        byte[] bodyRaw = Encoding.UTF8.GetBytes(jsonData);

        using (UnityWebRequest request = new UnityWebRequest(url, "POST"))
        {
            request.uploadHandler = new UploadHandlerRaw(bodyRaw);
            request.downloadHandler = new DownloadHandlerBuffer();
            request.SetRequestHeader("Content-Type", "application/json");

            yield return request.SendWebRequest();

#if UNITY_2020_1_OR_NEWER
            bool isError = request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError;
#else
            bool isError = request.isNetworkError || request.isHttpError;
#endif

            if (isError)
            {
                Debug.LogError($"Error sending request: {request.error}");
                onError?.Invoke(request.error);
            }
            else
            {
                try
                {
                    ACEStepOutput output = JsonUtility.FromJson<ACEStepOutput>(request.downloadHandler.text);
                    if (output.status == "success")
                    {
                        onSuccess?.Invoke(output);
                    }
                    else
                    {
                        onError?.Invoke($"Server returned error: {output.message}");
                    }
                }
                catch (Exception e)
                {
                    Debug.LogError($"Error parsing response: {e.Message}");
                    onError?.Invoke($"Error parsing response: {e.Message}");
                }
            }
        }
    }

    /// <summary>
    /// Downloads audio file by filename returned from server
    /// and saves it inside the selected Unity output folder.
    /// </summary>
    public IEnumerator DownloadAndSaveAudio(string filename, string unityOutputFolder, Action<string> onComplete, Action<string> onError)
    {
        if (string.IsNullOrEmpty(filename))
        {
            onError?.Invoke("Empty filename specified");
            yield break;
        }

        string downloadUrl = $"{serverBaseUrl}/{filename}";

        using (UnityWebRequest www = UnityWebRequest.Get(downloadUrl))
        {
            yield return www.SendWebRequest();

#if UNITY_2020_1_OR_NEWER
            bool isError = www.result == UnityWebRequest.Result.ConnectionError || www.result == UnityWebRequest.Result.ProtocolError;
#else
            bool isError = www.isNetworkError || www.isHttpError;
#endif

            if (isError)
            {
                Debug.LogError($"Error downloading audio file: {www.error}");
                onError?.Invoke(www.error);
                yield break;
            }

            byte[] audioData = www.downloadHandler.data;

            // Check if directory exists, else create it
            if (!Directory.Exists(unityOutputFolder))
            {
                Directory.CreateDirectory(unityOutputFolder);
            }

            string localPath = Path.Combine(unityOutputFolder, filename);

            try
            {
                File.WriteAllBytes(localPath, audioData);
                Debug.Log($"Audio file saved to {localPath}");
                onComplete?.Invoke(localPath);
            }
            catch (Exception e)
            {
                Debug.LogError($"Failed to save audio file: {e.Message}");
                onError?.Invoke(e.Message);
            }
        }
    }
}