這不是一個Unity問題,而是一個C#問題。 ThinkGear文檔提到用戶應該實現端口掃描,但我不記得提供了任何實現,但提供了存儲以前端口的建議。
不幸的是,沒有真正優雅的方法來實現這一點,但有一些方法。
你可以做的最好的事情是循環通過端口,直到你得到一個不超時,但這意味着每個檢查需要至少2秒。更糟糕的是,您必須從Unity的.NET中獲取連接串行端口的唯一方法並不保證是最新的。這意味着您可能會以非常緩慢的方式列舉大量串行端口。
爲了減少搜索時間,你應該按以下順序進行搜索:
末端口使用的是(在PlayerPrefs存儲這個)
通過SerialPort.GetPortNames返回的所有端口。不會有太多,但不幸的是,並不能保證它們全都存在,因爲正如文檔所說,SerialPort.GetPortNames會檢查並非總是最新的註冊表值。
端口0-10如果您還沒有檢查過它們。
端口10 - 256,但見下文。此時,您至少必須讓用戶有機會自己進入港口,或者向他們發出警告,告知下一步需要多長時間。
我不會推薦走這麼遠(最長8分鐘的搜索聲音是否合理?)。你已經花了20秒鐘掃描前10個端口。這可能是值得
- 顯示用戶如何找到合適的端口自己
- 寫一個小的外部程序使用lower level方法來顯示正確的端口供用戶輸入每個平臺。
- 從特定於操作系統的庫訪問這些較低級別的方法,並從Unity訪問它以將您的搜索限制爲有效端口。這是我的選擇。
檢查端口是這樣的(因爲使用協同程序的需要拉姆達):
IEnumerable AttemptHeadsetConnection(int portNumber,Action<int,int> headsetConnectedCallback, Action attemptCompletedCallback)
{
var connectionString = string.Format("\\\\.\\COM{0}",portNumber);//That string literal should be elsewhere
return AttemptHeadsetConnection(connectionString, headsetConnectedCallback, attemptCompletedCallback);
}
IEnumerable AttemptHeadsetConnection(string connectionString,Action<int,int> headsetConnectedCallback,Action attemptCompletedCallback)
{
connectionID = ThinkGear.TG_GetNewConnectionId();
connectionStatus = ThinkGear.TG_Connect(connectionID ,
connectionString,
ThinkGear.BAUD_9600,
ThinkGear.STREAM_PACKETS);
if(connectStatus >= 0)
{
yield return new WaitForSeconds(2f); //Give the headset at least 2 seconds to respond with valid data
int receivedPackets = ThinkGear.TG_ReadPackets(handleID, -1);//Read all the packets with -1
if(receivedPackets > 0)
{
headsetConnectedCallback(connectionID,connectionStatus);
}
else
{
ThinkGear.TG_FreeConnection(handleID);
}
}
attemptCompletedCallback();
}
並使用的東西,如:
foreach(var serialPort in SerialPort.GetPortNames())
{
var connectionCoroutine = AttemptHeadsetConnection(serialPort,onFoundHeadset,onAttemptCompleted);
StartCoroutine(connectionCoroutine);
}
關於代碼的注意事項:這並不優雅,它甚至可能不會編譯(雖然它不會執行任何操作)不可能)。把它作爲非常有說服力的僞代碼,並用它作爲你的基礎。
讀什麼標籤是使用它之前。 – Mephy 2014-09-13 03:41:47