不久前買了一套第三方的Unity Asset,當我專案中的遊戲物件要獲取第三方的數據時,遇到了困難。 因為該套件以C#開發,個人比較習慣使用JavaScript開發,兩個不同語言的程式之間要互通參數本身就有困難,最簡單的解決方案就是透過SendMessage傳遞參數。 但是當你要傳送的參數很多時,真的只能一行一行把每個參數Send出去嗎?
在Unity Answers爬的結果是否定的,當你仔細看SendMessage的程式屬性時,傳遞參數那欄是object屬性,這代表著這裡可以是任何東西,可以是字元、向量、浮點數、布林、單一數據類型的陣列或者是混和數據的物件等等… 因此我再繼續爬下去,最後我實作了JavaScript的接收方,與JavaScript和C#的發送方(因為我個人用JavaScript開發,因此目前還不打算做C#的接受方)。
Notes:
a. 函數不需要特別宣告傳值的數據類型也可以處裡,例:msgArr:Array,只打msgArr也是可以使用的;但是切記請勿以無法紀錄傳值的數據類型去宣告,例:Vector2,因為傳值內還有字元和布林,會出現錯誤。
b. 別忘了陣列總是從0開始。
c. 接收函數內部(例:Unpackage)不需要特別宣告變數(例:unpkg1),但是如果這個變數要在別的函數內使用時(例:在Update內使用unpkg1去改變gameObject位置),就需要事先宣告,不然別的函數會認不得。
Notes:
a. 如果不想用Object存值的話,其實C#還是有使用陣列的解決方案 - 使用「List」,不過太複雜、太麻煩了… 我沒有實作出來,但我還是會在教學最後附上相關連結。
教學在這裡結束,至於以上程式碼我會放到我的GitHub上,GitHub的版本還會附上註解,有興趣的人可以去下載。
在Unity Answers爬的結果是否定的,當你仔細看SendMessage的程式屬性時,傳遞參數那欄是object屬性,這代表著這裡可以是任何東西,可以是字元、向量、浮點數、布林、單一數據類型的陣列或者是混和數據的物件等等… 因此我再繼續爬下去,最後我實作了JavaScript的接收方,與JavaScript和C#的發送方(因為我個人用JavaScript開發,因此目前還不打算做C#的接受方)。
接收方 | Receiver
原理很簡單,我先宣告我預定要接收的變數與數據類型(本範例分別使用:字元、布林、浮點數、三維向量,來當作示範),然後設置兩個函數分別用來接收JavaScript或C#傳來的參數(不一定要分成兩個函數,其實也可以在同個函數內解決,但為了方便辨識,我分成了兩個函數處理),傳來的參數可以用讀取陣列的方式解開參數內容。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
var
unpkg1:String;
var
unpkg2:boolean;
var
unpkg3:Vector3;
var
unpkg4:float;
var
testMod:boolean=
true
;
var
supportCS:boolean=
false
;
function
Update()
{
if
(testMod)
gameObject.transform.position=unpkg3;
}
function
Unpackage(msgArr:Array)
{
unpkg1=msgArr[0];
unpkg2=msgArr[1];
unpkg3=msgArr[2];
unpkg4=msgArr[3];
if
(testMod)
{
Debug.Log(unpkg1);
Debug.Log(unpkg2);
Debug.Log(unpkg3);
Debug.Log(unpkg4);
Debug.Log(unpkg1+
", and this's the "
+unpkg2+
". My address is "
+unpkg3+
", my phone number is "
+unpkg4+
". Remember to call me!!"
);
}
}
function
UnpackageCS(msgArrCS:Object)
{
unpkgCS1=msgArrCS[0];
unpkgCS2=msgArrCS[1];
unpkgCS3=msgArrCS[2];
unpkgCS4=msgArrCS[3];
if
(supportCS && testMod)
{
Debug.Log(unpkgCS1);
Debug.Log(unpkgCS2);
Debug.Log(unpkgCS3);
Debug.Log(unpkgCS4);
Debug.Log(unpkgCS1+
", and this's the "
+unpkgCS2+
". My address is "
+unpkgCS3+
", my phone number is "
+unpkgCS4+
". Don't call me!!"
);
}
}
|
Notes:
a. 函數不需要特別宣告傳值的數據類型也可以處裡,例:msgArr:Array,只打msgArr也是可以使用的;但是切記請勿以無法紀錄傳值的數據類型去宣告,例:Vector2,因為傳值內還有字元和布林,會出現錯誤。
b. 別忘了陣列總是從0開始。
c. 接收函數內部(例:Unpackage)不需要特別宣告變數(例:unpkg1),但是如果這個變數要在別的函數內使用時(例:在Update內使用unpkg1去改變gameObject位置),就需要事先宣告,不然別的函數會認不得。
發送方(JavaScript) | Sender(JavaScript)
在開頭宣告我要發送的變數,之後宣告一個新陣列(new Array()),在底下將變數加入到陣列內(Array.push),請記住變數在陣列中的順序依你加入的順序而定(上到下)。 然後SendMessage把此陣列給送出去就好了! JavaScript簡單多囉~
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
var
msgValue1:String=
"I'm a man"
;
var
msgValue2:boolean=
true
;
var
msgValue3:Vector3=
new
Vector3(2,4,6);
var
msgValue4:float=1234.5678;
public
var
msgArr=
new
Array();
msgArr.push(msgValue1);
msgArr.push(msgValue2);
msgArr.push(msgValue3);
msgArr.push(msgValue4);
var
otherObj:boolean=
false
;
var
targetObj:GameObject;
function
Start()
{
if
(otherObj)
targetObj.SendMessage(
"Unpackage"
,msgArr);
else
gameObject.SendMessage(
"Unpackage"
,msgArr);
}
|
發送方(C#) | Sender(C#)
大致原理同JavaScript,不過C#中同一陣列只能單一數據類型,因此沒辦法用陣列傳值(如果是混和數據類型的話),所以改用Object傳值。 然後C#的陣列一定要有數組大小或者初始值,也就是範例中的valueLength位置,一定要放數值或者動態數值,沒辦法像JavaScript那樣,可以空陣列然後塞變數進去。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
using UnityEngine;
using System.Collections;
public class Sender : MonoBehaviour
{
public int valueLength=4;
public string msgValue1=
"I'm a man, from C#"
;
public bool msgValue2=
false
;
public Vector3 msgValue3=
new
Vector3(1,3,5);
public double msgValue4=8765.4321;
public bool otherObj=
false
;
public GameObject targetObj;
void Start ()
{
object[] msgArrCS=
new
object[valueLength];
msgArrCS[0]=msgValue1;
msgArrCS[1]=msgValue2;
msgArrCS[2]=msgValue3;
msgArrCS[3]=msgValue4;
if
(otherObj)
targetObj.SendMessage(
"UnpackageCS"
,msgArrCS);
else
SendMessage(
"UnpackageCS"
,msgArrCS);
}
}
|
Notes:
a. 如果不想用Object存值的話,其實C#還是有使用陣列的解決方案 - 使用「List」,不過太複雜、太麻煩了… 我沒有實作出來,但我還是會在教學最後附上相關連結。
教學在這裡結束,至於以上程式碼我會放到我的GitHub上,GitHub的版本還會附上註解,有興趣的人可以去下載。