Home > Blockchain >  How to start a process in Unity3D but not stuck Unity?
How to start a process in Unity3D but not stuck Unity?

Time:12-22

I'm trying to start a process to excute a shell script with C# in Unity3D on MacOS, and I write the code below.

    [MenuItem("Test/Shell")]
    public static void TestShell()
    {
        Process proc = new Process();
        proc.StartInfo.FileName = "/bin/bash";
        proc.StartInfo.WorkingDirectory = Application.dataPath;
        proc.StartInfo.Arguments = "t.sh";
        proc.StartInfo.CreateNoWindow = false;
        proc.StartInfo.UseShellExecute = false;
        proc.StartInfo.RedirectStandardOutput = true;
        proc.OutputDataReceived  = new DataReceivedEventHandler((sender, e) =>
        {
            if (!string.IsNullOrEmpty(e.Data))
            {
                Debug.Log(e.Data);
            }
        });
        proc.Start();
        proc.BeginOutputReadLine();
        proc.WaitForExit();
        proc.Close();
    }

Shell script::

echo "1"
sleep 2s
open ./
echo "4"

When I run this code, Unity3D get stuck until the shell script excute complete. I tried to uncommit "proc.WaitForExit();", it did open the finder and not stuck anymore, but output nothing.

So how can I start a process in Unity3D and get the output of the shell script immediately?

CodePudding user response:

As said simply run the entire thing in a separate thread:

[MenuItem("Test/Shell")]
public static void TestShell()
{
    var thread = new Thread(TestShellThread);
    thread.Start();
}

private static void TestShellThread ()
{
    Process proc = new Process();
    proc.StartInfo.FileName = "/bin/bash";
    proc.StartInfo.WorkingDirectory = Application.dataPath;
    proc.StartInfo.Arguments = "t.sh";
    proc.StartInfo.CreateNoWindow = false;
    proc.StartInfo.UseShellExecute = false;
    proc.StartInfo.RedirectStandardOutput = true;
    proc.OutputDataReceived  = new DataReceivedEventHandler((sender, e) =>
    {
        if (!string.IsNullOrEmpty(e.Data))
        {
            Debug.Log(e.Data);
        }
    });
    proc.Start();
    proc.BeginOutputReadLine();
    proc.WaitForExit();
    proc.Close();
}

Note though in general: If you want to use the result in any Unity API related things besides logging you will need to dispatch them back into the main thread!

  • Related