IronPython 在Py有import第三方庫的時候會非常不方便,很多都無法使用。如果你打算要在Unity內使用IronPython的話,你需要先安裝IronPython,然後找到以下
的dll檔放入Unity的 Assets/Plugins/Resources資料夾內,沒有資料夾時就自己建立一個。
不建議使用IronPython,因為他對於第三方庫的支援性實在太差,加上無法搭配Anaconda的python使用。
成功使用IronPython在Unity內使用的Code如下,包含python import 資源包,但受限於第三方資源包的問題,要自己安裝太麻煩了,
最後回歸使用C#本身的Process來做Python的啟動與關閉。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using IronPython.Hosting;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;
using System.Threading;
using System.Reflection;
using Microsoft.CSharp.RuntimeBinder;
using System.IO;
using UnityEngine.UI;
using System;
using IronPython.Modules.Bz2;
public class C2Py :MonoBehaviour{
private static string path;
public static float ans;
private C2Py(string path)
{
}
private static C2Py me;
public void Start()
{
me = this;
}
public static void execute(string path)
{
C2Py.path = path; ==>要執行的py檔的路徑
Thread thread = new Thread(executePyFile);
thread.Start();
}
public InputField input1;
public InputField input2;
private static void executePyFile()
{
ScriptEngine engine = Python.CreateEngine();
//var scope = engine.CreateScope();
engine.Runtime.LoadAssembly(typeof(GameObject).Assembly);
engine.Runtime.LoadAssembly(typeof(int).Assembly);
engine.Runtime.LoadAssembly(typeof(string).Assembly);
//C:\Program Files\IronPython 2.7\Lib
var paths = engine.GetSearchPaths();
paths.Add(@"C:\Program Files\IronPython 2.7\Lib"); ==>這行必須添加,這代表引入已經在IronPython安裝好的地方方庫
//paths.Add(@"C:\Users\USER\Anaconda3\Lib"); 失敗了,沒辦法直接指定其他Python安裝的庫
//paths.Add(@"C:\Users\USER\AppData\Local\Programs\Python\Python37-32\Lib"); 失敗了
engine.SetSearchPaths(paths);
ScriptScope scope = engine.CreateScope();
object p1 = Int32.Parse(me.input1.text);
object p2 = Int32.Parse(me.input2.text);
scope.SetVariable("p1", p1); ==>自己定義Python內的變數p1和p2,py檔內不要再定義相同名稱的變數,避免被py檔的覆蓋
scope.SetVariable("p2", p2);
Debug.Log("p1:" + scope.GetVariable<int>("p1") + " p2:" + scope.GetVariable<int>("p2"));
//ScriptSource data = engine.CreateScriptSourceFromFile(path); 可以產生程式碼的文字
ScriptScope scope2 = engine.ExecuteFile(path, scope); ==>執行路徑的py檔,並使用自己建立的scope
float ans = scope2.GetVariable<float>("ans"); ==>這個ans是Py檔內建立的變數,可以取到C#內
Debug.Log("python回傳值:>>>" + ans);
C2Py.ans = ans;
}
}
public enum C2PySituation
{
stop,
excuting,
complete
}
---------------Py檔的部分----------------
import os
def calculate(v1,v2):
return v1+v2
ans=calculate(p1, p2)
print(ans)
----------------在單純的C#測試時的部分,可以直接呼叫Python內的某個方法,其實也是挺酷的----------------
using System;
using IronPython.Hosting;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;
//要安裝IronPython
//用reference新增IronPython,然後用Visual Studio去修正錯誤。
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
//D:\PyTest\Pythontest1.py
new Program().executePyFile();
}
private void executePyFile()
{
ScriptRuntime pyRunTime = Python.CreateRuntime();
dynamic obj = pyRunTime.UseFile("D:/PyTest/Test.py");//py檔放置的位置
int a = obj.calculate(20, 50); //使用該py檔內的calculate方法,收到回傳值 ==>無法在Unity環境內使用Runtime的method。
Console.WriteLine(a); //印出來結果
Console.ReadKey(); //停住console
}
}
}
/*
-----------------Python的部分-------------------
def calculate(v1,v2):
return v1+v2
calculate(10,20)
def welcome(name):
return "hello" + name
------------------------------------
__init__ 等同是建構子
不需要class的設定就可以用了,python內可以建立一些方法直接呼叫
-------------------------------------
-------------------------------------
python可以用Visual Studio來寫就OK了
-------------------------------------
*/