前提・実現したいこと
UnityでC#のProcessを用いて非同期でPythonを実行させたあとに"r.Rotate()"という処理をさせたいです。
Pythonを実行することはできたのですが、非同期処理が終了した後にUnityのコンポーネントを操作するプログラムを実行されることができません。該当スクリプトでは、OutputDataReceived及びp_Exited外ではr.Rotate()が実行できました。(ただその場合、Python()を実行させた直後に動作してしまいます。)わかりずらい文章で申し訳ありませんが解決方法を教えていただけると幸いです。
該当のソースコード
C#
1using System.Collections; 2using System.Collections.Generic; 3using System.Diagnostics; 4using System.IO; 5using System.Runtime.CompilerServices; 6using System.Text; 7using System; 8using System.ComponentModel; 9using UnityEngine; 10 11public class CsPy : MonoBehaviour 12{ 13 //pythonがある場所 14 private string pyExePath = @"~python.exe"; 15 16 //実行したいスクリプトがある場所 17 private string pyCodePath = @"C:(実行したいファイル).py"; 18 19 //非同期処理後に操作したいオブジェクト 20 GameObject gameObject; 21 22 public void Python() 23 { 24 //Hierarchy上のImageを取得し、アタッチされているスクリプトのクラスをrとする 25 gameObject = GameObject.Find("Image"); 26 RotateImage r = gameObject.GetComponent<RotateImage>(); 27 28 //外部プロセスの設定 29 ProcessStartInfo processStartInfo = new ProcessStartInfo() 30 { 31 FileName = pyExePath, //実行するファイル(python) 32 UseShellExecute = false,//シェルを使うかどうか 33 CreateNoWindow = true, //ウィンドウを開くかどうか 34 RedirectStandardOutput = true, //テキスト出力をStandardOutputストリームに書き込むかどうか 35 Arguments = pyCodePath, //実行するスクリプト 引数(複数可) 36 StandardOutputEncoding = Encoding.GetEncoding("shift_jis"), 37 }; 38 39 //外部プロセスの開始 40 Process process = Process.Start(processStartInfo); 41 42 process.OutputDataReceived += dataReceived; 43 process.BeginOutputReadLine(); // 非同期ストリーム読み取りの開始 44 45 46 // OutputDataReceivedイベントハンドラ.行が出力されるたびに呼び出される 47 void dataReceived(object sender, DataReceivedEventArgs e) 48 { 49 string str = e.Data; 50 51 if (str!=null && str.Length > 0) 52 { 53 UnityEngine.Debug.Log(str); 54 } 55 else 56 { 57 UnityEngine.Debug.Log("終了"); //このデバックはpythonスクリプト実行後に出力されました。 58 } 59 } 60 61 // プロセスが終了したときに Exited イベントを発生させる 62 process.EnableRaisingEvents = true; 63 // イベントハンドラがフォームを作成したスレッドで実行されるようにする 64 process.SynchronizingObject = (ISynchronizeInvoke)this; 65 //イベントハンドラの追加 66 process.Exited += p_Exited; //new EventHandler(p_Exited); 67 68 void p_Exited(object sender, EventArgs e) 69 { 70 UnityEngine.Debug.Log("終了"); //同様にこのデバックはpythonスクリプト実行後に出力されました。 71 //プロセスが終了したときに実行されてほしい 72 r.Rotate(); 73 } 74 75 //ここでr.Rotate()とするとこのプログラム実行直後に動作してしまいます。 76 } 77}
試したこと
process.Exit一連を削除して、dataReceived関数中のDebug.Log("終了")の後にr.Rotate()を入れるとエラーもなく無視されました。一方で、p_Exited()の中でr.Rotateとすると以下のエラーメッセージが出力され、r.Rotateが実行されないままpythonスクリプトは問題なく実行されました。
発生している問題・エラーメッセージ
InvalidCastException: Specified cast is not valid. CsPy.Python () (at Assets/Script/CsPy.cs:76) UnityEngine.Events.InvokableCall.Invoke () (at <2feaf16e80004e0cadae3f2e05f2a3fa>:0) UnityEngine.Events.UnityEvent.Invoke () (at <2feaf16e80004e0cadae3f2e05f2a3fa>:0) UnityEngine.UI.Button.Press () (at C:/GAMES/2019.4.8f1/Editor/Data/Resources/PackageManager/BuiltInPackages/com.unity.ugui/Runtime/UI/Core/Button.cs:68) UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at C:/GAMES/2019.4.8f1/Editor/Data/Resources/PackageManager/BuiltInPackages/com.unity.ugui/Runtime/UI/Core/Button.cs:110) UnityEngine.EventSystems.ExecuteEvents.Execute (UnityEngine.EventSystems.IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at C:/GAMES/2019.4.8f1/Editor/Data/Resources/PackageManager/BuiltInPackages/com.unity.ugui/Runtime/EventSystem/ExecuteEvents.cs:50) UnityEngine.EventSystems.ExecuteEvents.Execute[T] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.ExecuteEvents+EventFunction`1[T1] functor) (at C:/GAMES/2019.4.8f1/Editor/Data/Resources/PackageManager/BuiltInPackages/com.unity.ugui/Runtime/EventSystem/ExecuteEvents.cs:261) UnityEngine.EventSystems.EventSystem:Update() (at C:/GAMES/2019.4.8f1/Editor/Data/Resources/PackageManager/BuiltInPackages/com.unity.ugui/Runtime/EventSystem/EventSystem.cs:377)
補足情報(FW/ツールのバージョンなど)
Windows10
unityのバージョンは2019.4.8f1です。
回答1件
あなたの回答
tips
プレビュー