Unity C#:与控制台计划不同步
我目前正在尝试用Unity 写国际象棋GUI。我有一个由UCI(控制台)通信的EXE文件的国际象棋引擎。该计划处于很早的阶段,我只想与国际象棋引擎(控制台应用程序)进行交流,作为概念证明。
目前,我使用 Process类与重定向的输出和输入。象棋发动机输出目前的所有内容都在Unity控制台中打印出来。不幸的是,我没有尝试的工作能像预期的那样。
国际象棋引擎(控制台程序)的工作方式:
- 用户可以在控制台“ uci”或“ go dept 1”中编写命令,
- 引擎将以“ uciok”或“ BestMove E2E4”
这些响应也可以具有多行。
我想要的:
- 按UNITY播放
- 我的脚本立即将消息“ UCI”发送到国际象棋引擎,
- 输出(Muliple Lines)都会将输出(Muliple Lines)打印到Unity Console
- 每次我按“ C'C'步骤2和3, 。重复重复
当前发生的事情:
- 按Unity
- Console(国际象棋引擎)打开
- 我手动关闭控制台窗口的
- 消息“ UCI”将发送到国际象棋发动机
- 多线将输出到Unity Console
- IOException
当我按“ C”时,我会得到我也尝试过的
- : startInfo.CreatEnowIndow = true; - >我必须与任务管理器保持团结,直到该过程完成
- Engine Process.waitforexit(); - >不起作用,因为该过程不应该退出
- Engine Process.beginOutputReadline(); - >我被Unity垃圾邮件和例外垃圾邮件,因为我正在混合同步操作,并且
- 在Stackoverflow上已经建议了许多其他解决方案。到目前为止,什么都没有用:(
我对Unity和C#的新手很新,所以我希望这个问题不会让我看起来很愚蠢。我在下面发布了我的代码。
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);
}
}
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);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
感谢@bugfinder指出,您可以将方法附加到某些事件。使用您的tipps和 process.beginOutputReadline 我能够解决问题。
我评论了与原始代码相比,我在哪里添加或删除了行。
Thanks to @BugFinder to pointing out that there are events that you can attach a method to. Using your tipps and the documentation of Process.BeginOutputReadLine I was able to solve the problem.
I commented where I added or removed line in comparison with the original code.