雲端腳本程序設計人員指南
本指南說明如何使用 Mesh 雲端腳本 API 和開發人員工具來建置環境(這些從 Unity 中的項目開始,然後上傳至 Mesh 集合)。 建議您先閱讀 在 Azure 中設定雲端腳本基礎結構,以熟悉 Mesh Cloud Scripting 的概念和基本架構。
本節描述 Mesh 雲端腳本 API 的功能和介面,其用來撰寫在環境中驅動行為的腳本。
基本 DOM 結構
DOM 結構會鏡像 Unity 場景的結構。 應用程式的「場景」成員會對應至您的 Mesh Cloud Scripting 元件所連結的遊戲物件。 下列 Mesh 雲端文稿 API 類別會對應一對一與編輯器中建立的 Unity 物件:
- GameObject (& Transform Component) -> TransformNode
- 淺色元件 -> PointLightNode、SpotLightNode、DirectionalLightNode
- 動畫工具元件 -> AnimationNode (和衍生類別,請參閱下方)
- Box Collider 元件 -> BoxGeometryNode
- Sphere Collider 元件 -> SphereGeometryNode
- Capsule Collider 元件 -> CapsuleGeometryNode
- Mesh Collider 元件 -> MeshGeometryNode
- Text Mesh Pro 元件 -> TextNode
- 硬體元件 -> RigidBodyNode
例如,如果您使用具有 Light 元件(設為點光)和附加球體碰撞器的遊戲物件建立場景,則場景會包含具有兩個子系的 TransformNode:PointLightNode 和 SphereGeometryNode。
此外,某些 Mesh 雲端腳本 API 對象沒有對應的內建 Unity 元件。 這些是您可以在 Unity 中建立屬於 Mesh 工具組套件一部分的其他元件。
- 網格雲端文稿元件 (如上所述)
- WebSlate 元件
將 Unity DOM 對應至 Mesh DOM
您可以使用 Mesh 雲端腳本 API 不知道的元件來建立場景。 這些只會存在於場景的Mesh雲端腳本 DOM 中。 不過,GameObjects 的完整場景結構會在 DOM API 中鏡像為 TransformNodes。
Unity 具有 GameObject/元件 API 圖形;不過,Mesh 雲端腳本 DOM 具有單一樹狀結構。 Mesh 雲端腳本 API 中的 TransformNode 具有子系,可能是其他 TransformNode,也可能是對應至元件的其他節點。 我們可以將此視為相關聯遊戲物件的元件及其轉換元件子系的合併清單。
矩形轉換
如果您新增使用 RectTransform 的元件,例如 Text Mesh Pro 元件,遊戲物件就不會顯示為 Mesh 雲端腳本場景圖形中的節點。 您仍然可以移動、啟用和停用這類元件,但若要這樣做,您必須使用一般 Transform 元件在另一個遊戲物件中使用 RectTransform 包裝遊戲物件。
屬性變更事件
您可以在階層中的任何節點上呼叫 AddPropertyChangedEventHandler
來訂閱屬性變更事件。 您必須以字串的形式傳入屬性的名稱。
您也可以訂閱 DomObjectPropertyChanged
事件來訂閱所有事件。 當 DOM 中的任何屬性變更時,就會呼叫這個值。
物件生命週期
建立時,節點會取消父節點。 這表示它們不會在場景中顯示,直到他們明確地新增為場景或其中一個子系。 同樣地,將節點的父代設定為 null 將會從場景中移除它及其子系。
有時候您想要暫時停用節點,但不保留其所在場景的記錄。 因此,每個節點都有「作用中」旗標。 當設定為 false 時,它會停用節點及其子系。
您可以在 Unity 中建立屬於場景但已停用的遊戲物件和元件。 這些會顯示為 Mesh 雲端腳本場景階層中的節點,但會將其作用中旗標設定為 false。 將使用中旗標設定為 true,將會在 Unity 場景中啟用它們。
複製和重新父母
節點可以在 Mesh Cloud Scripting API 中複製和重新父系;對應的 Unity 場景將會據以更新。 如果您複製節點,它會複製該節點及其所有子系(包括可能位於對應 Unity 物件中的子系,但無法看見 Mesh Cloud Scripting)。
可以複製或重新對應至 Unity 元件的節點。 這是藉由根據 Mesh 雲端腳本節點表示法重新建立這些 Unity 元件來實作。 只有可透過 Mesh 雲端腳本 API 建立的節點可以複製或重新父項。 如果您已在 Unity 中建立元件,並設定未反映在對應 Mesh 雲端腳本節點中的字段,則如果複製 Node 本身,這些字段將會重設為預設值。 基於這個理由,我們建議您複製或重新父系轉換節點,您可以在其中操作 Unity 中建立的物件。 這些設定一律會正確保留所有原始的 Unity 設定。
使用者
API 中有各種地方提供 User 屬性。 屬性 User.Identifier
是使用者永續性的標識符字串,即使用戶離開並重新加入也一樣。 用戶顯示名稱也可以透過存取 User.DisplayName
。 使用者從中聯機的事件標識碼可透過 User.ConnectedEventId
存取。
在開發期間,用戶顯示名稱、標識符和事件標識碼可以在「開發人員設定」中的 Mesh 雲端腳本元件編輯器中模擬,如下所示。
化身
虛擬人偶是場景中使用者的代表。 他們可以用來將用戶傳送到指定的位置、在場景之間移動,以及偵測與觸發程式磁碟區的碰撞。
資訊對話框
在 Mesh Cloud Scripting 中,可以透過自定義訊息在 Microsoft Mesh 應用程式中彈出螢幕空間對話方塊。 SceneNode 包含這個 函式。 ShowMessageToParticipants(string message, IReadOnlyCollection<Participant> participants)
RTF 標記 可用於訊息中來控制文字屬性(色彩、粗體等)。
輸入對話框
Mesh 雲端腳本可以使用自定義訊息,向 Mesh 事件中的出席者要求文字輸入。 CloudApplication
提供方法 Task<string> ShowInputDialogToParticipantAsync(string message, Participant participant, CancellationToken token)
。 RTF 標記 可用於訊息中來控制文字屬性(例如色彩或粗體)。
類別
CloudApplication
介面 ICloudApplication
是開發 Mesh 應用程式的起點。 「App.cs」中提供作為_app變數。 除了場景之外, ICloudApplication
還針對所有可用的類型建立函式。 它也有一些其他方法,但它們供內部使用。
InteractableNode
MeshInteractableSetup 是屬於 Mesh 工具組套件一部分的自定義 Unity 元件。 當您將它附加至 Unity 中的遊戲物件時,當使用者在該遊戲物件或其子系中按兩下任何作用中碰撞時,就會引發 Click 事件。
以下顯示一個簡單的範例,其中 MeshInteractableSetup 元件會新增至與方塊碰撞器相同的遊戲物件:
WebSlateNode
WebSlate 是 Mesh 工具元件的自訂 Unity 元件。 若要將 WebSlate 預製專案新增至您的場景,請從功能表欄選取 GameObject>Mesh Toolkit>WebSlate。 指派給 WebSlate 實例 URL 屬性的網站會在這個預製專案的四邊呈現。
以下顯示一個範例,其中 WebSlate 預製專案已新增至場景並指派 URL:
var webSlateNode = Root.FindFirstChild<WebSlateNode>(true);
webSlateNode.Url = new System.Uri("https://en.wikipedia.org/wiki/Color");
接聽點選
以下是每次按兩下 Cube 時旋轉 Cube 的簡單 Mesh 雲端腳本腳本。 以這個程式代碼取代 內部App.cs
的存根StartAsync
方法。
private float _angle = 0;
public Task StartAsync(CancellationToken token)
{
// First we find the TransformNode that corresponds to our Cube gameobject
var transform = _app.Scene.FindFirstChild<TransformNode>();
// Then we find the InteractableNode child of that TransformNode
var sensor = transform.FindFirstChild<InteractableNode>();
// Handle a button click
sensor.Selected += (_, _) =>
{
// Update the angle on each click
_angle += MathF.PI / 8;
transform.Rotation = new Rotation { X = 1, Y = 0, Z = 0, Angle = _angle };
};
return Task.CompletedTask;
}
點擊資訊
查看屬性變更事件自變數,即可找出哪個用戶按兩下碰撞器。 您也可以從事件自變數讀取點擊的聯繫人正常和位置。 這些座標會相對於 InteractableNode 的本機座標空間。
動畫 師
您可以建立 Unity Animator 並新增至場景,並透過 Mesh Cloud Scripting 來控制它。 Mesh 工具元件會查看 Unity 專案中的資產,而且針對找到的每個 Animator,它會在 Mesh Cloud Scripting 專案中的 “AnimationScripts” 資料夾中產生類別。 這個類別衍生自 AnimationNode,可用來從 Mesh Cloud Scripting 控制 Animator。 當您將 Animator 新增為 Unity 中的遊戲物件時,您會發現產生的類別對應實例做為對應 TransformNode 的子系。 您可以使用這個類別的 API 來控制 Animator。
Mesh 雲端腳本程序設計模型是伺服器授權,我們僅支援一小部分的 Animator 功能。 這是因為我們在伺服器上建立 Animator 模型,並預期所有客戶端都會正確地同步處理到伺服器模型。 基於這個理由,目前只支援下列 API:
- 狀態設定 (針對每個圖層,類別中有一個對應的屬性,可根據 Animator 中的可用狀態設定為列舉)。 狀態會立即設定,而不是透過轉換。
- 浮點數變數設定:只會公開 float 變數,而且只有在動畫工具中系結至 “Motion Time” 的目的。
- 層次速度設定
在狀態內,您可以建立動畫剪輯,但不會限制您可以在 Unity 場景中設定的值。 也支援迴圈動畫剪輯。 動畫工具的下列功能不支援透過 AnimationNodes:
- 轉換:如果您將轉換新增至 Animator,您將無法透過 Mesh Cloud Scripting API 觸發這些轉換(伺服器不會模型轉換)。
- 變數(除了浮動以驅動動作時間以外)。 不支援用來驅動轉換邏輯或速度乘數的變數。
- 鏡像狀態、迴圈位移和腳 IK。
晚期聯結和動畫
當用戶端加入 Mesh 事件時,它們會同步處理到所有執行中動畫節點的目前狀態和當地時間。 如果您有長時間執行的動畫處於播放狀態,播放時間將會設定為延遲聯結上動畫的正確目前時間。 不過,如果您的狀態引發事件,這些事件將不會在已加入的晚期用戶端中引發。 某些其他案例可能無法如預期般運作;例如,如果您在狀態開始時啟用 AudioSource 來觸發音效,則 AudioSource 仍會在晚期聯結用戶端中啟用,但會在音訊剪輯的開頭開始播放。
動畫工具初始狀態
建議您建立具有默認狀態的動畫工具,而該動畫工具不會執行任何動作。 當場景開始在 Unity 中播放時,它會啟動所有動畫製作工具,並開始播放其默認動畫。 這種情況可能發生在 Mesh 雲端腳本服務連線發生之前;因此,無法同步處理這些狀態和行為可能不如預期。
動畫工具重新父項和複製
AnimationNode 無法透過 Mesh 雲端腳本 API 建立。 建立 AnimationNode 的唯一方法是導出包含 Animator 元件的 Unity 場景。 如果您嘗試複製或重新父代 AnimationNode,您將會收到錯誤,因為無法支援此動作。 您仍然可以複製或重新父 代 AnimationNode 的父 代,因為這對應於可以複製和父系的包含 Unity Game 物件。
產生的程式代碼注意事項
產生的程式代碼會從動畫工具、圖層、狀態和變數的名稱中移除空格;例如,變數名稱 「my var」 會在程式代碼中變成 「myVar」。 因此,可以建立不會產生有效程序代碼的 Animators。 例如,如果您有兩個名為 「my var」 和 「myVar」 的變數,您會在產生期間收到錯誤,以及要求您重新命名變數的訊息。
LightNode
PointLightNode、DirectionalLightNode 和 SpotLightNode 全都會對應至 Unity Light 元件(其類型設定為對應的值)。 您可以透過 LightNode API 設定這些燈光的基本參數。 您也可以透過 API 手動建立 Lights。 透過 API 建立淺色節點會將無法透過 Mesh Cloud Scripting API 設定的參數保留為其預設值。
GeometryNode
BoxGeometryNode、SphereGeometryNode、CapsuleGeometryNode 和 MeshGeometryNode 對應至 Unity 的 Box Collider 元件、Sphere 碰撞器元件、膠囊碰撞器元件,以及 Mesh Collider 元件。 您也可以透過 Mesh 雲端腳本 API 來建立它們。 如果 MeshInteractableSetup 附加至其遊戲物件或其其中一個父系,則啟用和停用 Geometry Nodes 將會新增和移除點擊候選專案。
透過 API 建立幾何節點會將無法透過 Mesh API 設定的參數保留為其預設值(例如,物理材質會設定為 none,isTrigger 將會設定為 false)。
RigidBodyNode
將 Rigidbody 元件新增至物件時,會將其動作置於 Mesh Physics 的控制之下。 若未新增任何程序代碼,Rigidbody 物件將會由重力向下拉下,並且會回應與其他物件的碰撞。
注意: GeometryNode.Friction
會傳回 staticFriction
。 不過,如果在 Mesh Cloud Scripting 端設定,則會在用戶端上更新 staticFriction
和 dynamicFriction
。
觸發磁碟區
當幾何節點的 屬性設定為 true 時 IsTrigger
,可以當做觸發程式磁碟區。 此旗標會對應至 IsTrigger
Unity 中碰撞器上的 屬性,而且無法在運行時間變更。 當幾何是觸發程式時,它會針對任何開始/停止與其重疊的虛擬人偶產生 Entered
Exited
和 。
注意:Unity 對象必須新增至 TriggerVolume
圖層,才能讓傳送梁忽略它,因為圖層中的 Default
碰撞器會封鎖傳送梁。
TextNode
TextNode 會對應至 Unity 的 TextMeshPro 元件。 如果您將 TextMeshPro 元件新增至場景,您的 Mesh Cloud Scripting 場景階層中將會有對應的 TextNode。 這可讓您在執行時間設定元件的文字。 您也可以透過 TextNode API 變更基本文字屬性—粗體、斜體、底線、刪除線和色彩。 目前無法透過 API 建立 TextNode;您必須將它們新增至 Unity 中的場景,以建立它們。 此外,您無法直接複製 TextNode,您必須改為複製 TextNode 的父代 TranformNode。
網狀
網格目前是網格雲端腳本 API 的「隱藏」元件。 它們可以在 Unity 編輯器中建立,而且可以藉由操作其父遊戲物件/轉換元件來操作,但無法以程式設計方式建立它們,也無法透過 Mesh API 在運行時間編輯其屬性。
視覺腳本
您可以建立 Unity 腳本機器並新增至場景,並透過 Mesh Cloud Scripting 來控制它。 Mesh 工具元件會查看 Unity 專案中的資產,而且針對找到的每個腳本計算機,它會在 Mesh Cloud Scripting 專案中的 “VisualScripts” 資料夾中產生類別。 這個類別衍生自 VisualScriptNode,可用來從 Mesh Cloud Scripting 操作與腳本機器相關聯的 Unity 變數。 當您將腳本機器新增為 Unity 中的 GameObject 元件時,您會發現產生的類別對應實例做為對應 TransformNode 的子系。 使用這個類別的 API,您可以控制文稿電腦的變數。
狀態同步處理
根據預設,Mesh 會自動將一個用戶端上的視覺腳本所完成的場景變更複寫至所有其他用戶端。 若要讓 Mesh Cloud Scripting 知道透過可視化腳本所做的變更,必須符合下列先決條件:
- 腳本機器元件位於 GameObject 上,其為 Mesh 雲端腳本場景根目錄的子代。
- 網格雲端文稿元件的 [啟用可視化腳本] 選項已啟用。
如果不符合上述任一條件,Mesh Visual Scripting 運行時間會繼續復寫場景變更,但 Mesh 雲端腳本仍會遺忘這些變更。
初始狀態
我們建議您的視覺腳本不會在啟動時修改或依賴共享狀態。 On Start 事件通常會在 Mesh 雲端腳本服務連線發生之前發生;因此,無法同步處理該時間點的狀態,而且行為可能不符合您的需求。
延遲聯結
當用戶端加入 Mesh 事件時,它們會同步至所有 Visual Script 節點的目前狀態。 先前在其他用戶端上可能引發的任何 State Changed 事件,都不會在已加入的晚期用戶端上引發。 某些其他案例可能無法如預期般運作;例如,如果您藉由啟用 AudioSource 來回應 On State Changed 事件來觸發音效,該 AudioSource 仍會在晚期聯結用戶端中啟用,但會在音訊剪輯的開頭開始播放。
重新親生和複製
無法透過 Mesh 雲端腳本 API 建立 VisualScriptNode 。 建立 VisualScriptNode 的唯一方法是匯出包含腳本機器元件的 Unity 場景。 如果您嘗試複製或重新父代 VisualScriptNode,您將會收到錯誤,因為無法支援此動作。 您仍然可以複製或重新父代 VisualScriptNode 的父代,因為這對應於可以複製和父代的包含 Unity GameObject。
產生的程式代碼注意事項
產生的程式代碼會從腳本機器和變數的名稱中移除空格;例如,變數名稱 「my var」 會在程式代碼中變成 「MyVar」。 因此,可以建立不會產生有效程式代碼的腳本機器。 例如,如果您有兩個名為 「my var」 和 「myVar」 的變數,您會在產生期間收到錯誤,以及要求您重新命名變數的訊息。
其他 Mesh 雲端腳本主題
將資源新增至 Mesh 雲端腳本服務
如果您需要為 Mesh 雲端腳本服務新增要使用的資源,您必須將它新增為 C# 專案檔中的內嵌資源。 這可以透過Visual Studio中的專案 UI 來完成,或直接將下列這一行新增至 .csproj 檔案:
<EmbeddedResource Include="<my_resource_file>" CopyToOutputDirectory="PreserveNewest" />
請注意,這是將 scene.map 封裝的方式,您可以在 .csproj 檔案中看到此檔案以供參考。
使用網格物理
Mesh Physics
會小心同步處理客戶端之間僵硬主體的動作。 Mesh Cloud ScriptingTransformNode.Position
、 TransformNode.Rotation
RigidBody.Velocity
和 RigidBody.AngularVelocity
不會以最新的模擬狀態更新。 不過,如果在 Mesh 雲端腳本服務中設定這些變更,用戶端將會套用變更。 請注意,變更單一屬性會讓其他人保持不變。 例如,如果只設定位置,速度不會改變,而僵硬的主體會繼續運動,從新位置的舊速度移動。 假設 Mesh 雲端腳本服務未更新為剛性主體的最新動作狀態,建議只針對新的剛性主體設定這些動作。
RigidBodyNode
如果 TransformNode
已複製 ,則會註冊複製本文並移交給Mesh Physics
用戶端之間的同步處理。 注意:複製的剛性主體將有位置、旋轉和速度從原始殭化主體的場景開始。 如果這些應該不同,則必須在 Mesh Cloud Scripting 中明確設定它們。