I'm currently trying to write a chess GUI in Unity. I have a chess engine as an exe-file which communicates via UCI (console). The program is in a very early stage and I just want to communicate with the chess engine (console application) as a proof of concept.
At the moment I'm using the Process class with a redirected output and input. Everything that the chess engine outputs is currently being printed in the unity console. Unfortunately nothing I try works like expected.
How the Chess Engine (Console Program) works:
- User can write a command in the console e.g. "uci" or "go dept 1"
- The engine will respond with "uciok" or "bestmove e2e4"
These responses can also have multiple lines.
What I want:
- Press play in Unity
- My script instantly sends the message "uci" to the chess engine
- The output (muliple lines) gets printed to the unity console
- Everytime I press 'c' step 2 and 3 get repeated
What currently happens:
- Press play in Unity
- Console (chess engine) opens
- I manually have to close the console window
- The message "uci" gets sent to the chess engine
- Multiple lines get outputted to the unity console
- When I press 'c' I'm getting an IOException
What I've also tried:
- startInfo.CreateNoWindow = true; --> I have to close unity with the task manager as it waits until the process finishes
- engineProcess.WaitForExit(); --> Does not work, as the process is not supposed to exit
- engineProcess.BeginOutputReadLine(); --> I'm getting spammed by unity with exceptions because I'm mixing synchronus and asynchronous operations
- Many other solutions already suggested on StackOverflow. Nothing worked so far :(
I'm pretty new to Unity and C#, so I hope that this question does not make me look stupid. I posted my code below.
public string pathToExe = "PathToExe";
private Process engineProcess;
//gets automatically called once when I press start in Unity
private void Start() {
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardInput = true;
startInfo.FileName = pathToExe;
//Start process and write "uci" to chess engine
try {
engineProcess = Process.Start(startInfo);
engineProcess.StandardInput.WriteLine("uci");
}
catch {
UnityEngine.Debug.Log("Error when starting Engine");
}
}
//gets called every tick when Unity is running
private void Update() {
//write uci to chess engine when c is pressed
if (Input.GetKeyDown(KeyCode.C)) {
engineProcess.StandardInput.WriteLine("uci");
}
//read engine output if it exists
while (!engineProcess.StandardOutput.EndOfStream) {
string line = engineProcess.StandardOutput.ReadLine();
UnityEngine.Debug.Log(line);
}
}