在Unity3D中使用單個SendMessage送出多重參數

不久前買了一套第三方的Unity Asset,當我專案中的遊戲物件要獲取第三方的數據時,遇到了困難。 因為該套件以C#開發,個人比較習慣使用JavaScript開發,兩個不同語言的程式之間要互通參數本身就有困難,最簡單的解決方案就是透過SendMessage傳遞參數。 但是當你要傳送的參數很多時,真的只能一行一行把每個參數Send出去嗎?

在Unity Answers爬的結果是否定的,當你仔細看SendMessage的程式屬性時,傳遞參數那欄是object屬性,這代表著這裡可以是任何東西,可以是字元、向量、浮點數、布林、單一數據類型的陣列或者是混和數據的物件等等… 因此我再繼續爬下去,最後我實作了JavaScript的接收方,與JavaScript和C#的發送方(因為我個人用JavaScript開發,因此目前還不打算做C#的接受方)。 

接收方 | Receiver
?
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!!" );
  }
}
原理很簡單,我先宣告我預定要接收的變數與數據類型(本範例分別使用:字元、布林、浮點數、三維向量,來當作示範),然後設置兩個函數分別用來接收JavaScript或C#傳來的參數(不一定要分成兩個函數,其實也可以在同個函數內解決,但為了方便辨識,我分成了兩個函數處理),傳來的參數可以用讀取陣列的方式解開參數內容。

Notes:
a. 函數不需要特別宣告傳值的數據類型也可以處裡,例:msgArr:Array,只打msgArr也是可以使用的;但是切記請勿以無法紀錄傳值的數據類型去宣告,例:Vector2,因為傳值內還有字元和布林,會出現錯誤。
b. 別忘了陣列總是從0開始。
c. 接收函數內部(例:Unpackage)不需要特別宣告變數(例:unpkg1),但是如果這個變數要在別的函數內使用時(例:在Update內使用unpkg1去改變gameObject位置),就需要事先宣告,不然別的函數會認不得。

發送方(JavaScript) | Sender(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);
}
在開頭宣告我要發送的變數,之後宣告一個新陣列(new Array()),在底下將變數加入到陣列內(Array.push),請記住變數在陣列中的順序依你加入的順序而定(上到下)。 然後SendMessage把此陣列給送出去就好了! JavaScript簡單多囉~

發送方(C#) | Sender(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
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);
  }
}
大致原理同JavaScript,不過C#中同一陣列只能單一數據類型,因此沒辦法用陣列傳值(如果是混和數據類型的話),所以改用Object傳值。 然後C#的陣列一定要有數組大小或者初始值,也就是範例中的valueLength位置,一定要放數值或者動態數值,沒辦法像JavaScript那樣,可以空陣列然後塞變數進去。

Notes:
a. 如果不想用Object存值的話,其實C#還是有使用陣列的解決方案 - 使用「List」,不過太複雜、太麻煩了… 我沒有實作出來,但我還是會在教學最後附上相關連結。

教學在這裡結束,至於以上程式碼我會放到我的GitHub上,GitHub的版本還會附上註解,有興趣的人可以去下載。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值