Sdílet prostřednictvím


Osvědčené postupy skriptování vizuálů mesh pro sítě

Přehled

Ve službě Mesh se většina vlastností scény ve výchozím nastavení automaticky sdílí mezi všemi klienty připojenými ke stejné místnosti. Například umístění a otočení objektu scény, povolený stav komponenty nebo text TextMeshPro.

Vlastnosti komponent a proměnné object, které mají následující typy hodnot, se v pravidlech standardně sdílejí automaticky:

Typy kolekcí (seznamy a sady) a odkazy na objekty scény se nesdílí.

Uzly vizuálních skriptů, které přistupují k vlastnostem ve službě Mesh nebo upravují je, jsou označené popiskem, který označuje, jestli jsou sdílené všemi klienty nebo Místní pro tohoto klienta:

______________

Proměnné objektů se ve výchozím nastavení sdílejí i v případě, že jste je deklarovali pomocí jednoho z výše uvedených typů hodnot:

______________

Mesh nepodporuje proměnné scény, ale pomocí samostatných komponent proměnných v prostředí můžete ukládat proměnné, které je možné sdílet nezávisle na jakékoli konkrétní komponentě script machine .

Pokud nechcete automaticky sdílet vlastnosti nebo proměnné objektu, můžete do scény přidat komponentu Oboru místního skriptu. To způsobí, že všechny vlastnosti scény a proměnné skriptu na tomto herním objektu a všech jeho potomcích budou místní.

______________

Tip: V kapitole 3 našeho kurzu Mesh 101, který se zaměřuje na vizuální skriptování, se můžete podívat na několik příkladů použití komponenty Rozsah místního skriptu.

Pro proměnné místního skriptu, které používáte jenom v jednom počítači skriptů, je nejlepší použít proměnné Graphu, které se nikdy nesdílejí mezi klienty službou Mesh.

Sdílení prostřednictvím vizuálního skriptování mesh poskytuje následující záruky:

  • Zaručená konečná konzistence: Všichni klienti nakonec přijdou do stejného sdíleného stavu.

  • Zaručená atomicita jednotlivých komponent: Všechny aktualizace vlastností stejné komponenty scény (nebo stejné komponenty Proměnných ) ve stejné aktualizaci se na každého klienta použijí atomicky.

Mějte však na paměti následující:

  • Žádná záruka objednávání: Aktualizace použité jedním klientem na několik různých komponent scény můžou přijít v různých objednávkách na různých klientech.

  • Žádná záruka včasnosti: Mesh se pokusí co nejrychleji replikovat změny stavu mezi klienty, ale síťové podmínky můžou zpozdit příchod jakékoli dané aktualizace stavu na některých nebo všech klientech.

  • Žádná záruka členitosti: Všichni klienti nemusí vidět všechny jednotlivé přírůstkové aktualizace do sdíleného stavu. K tomu může dojít, když síťové podmínky vynutí server Mesh aktualizace s omezením rychlosti. Stává se také, když se klient později připojí k místnosti.

Stav je sdílený – ne události

Pomocí skriptování vizuálu Mesh nemůžete odesílat ani přijímat explicitní síťové zprávy. To může být zpočátku překvapivý, ale pomáhá vytvořit síťové paradigma, které usnadňuje jednotné zpracování změn modulu runtime a pozdního připojení. Místo zpráv existuje sdílený stav ve vlastnostech scény a proměnných skriptu.

Vaše skripty můžou reagovat na aktualizace sdíleného stavu jednotným způsobem bez ohledu na to, jestli byly tyto aktualizace místním skriptem nebo uživatelem, jiným klientem, který sdílí prostředí ve stejné místnosti, nebo jinými klienty, kteří už byli v místnosti předtím, než jste se k ní dokonce připojili sami.

Nemožnost explicitně odesílat síťové zprávy znamená, že budete muset začít přemýšlet o sdíleném stavu, který získává aktualizace místo sdílených událostí, které způsobují aktualizace stavu. Sdílené události jsou důsledkem aktualizace sdíleného stavu, nikoli opaku.

Skriptování vizuálů Mesh naštěstí usnadňuje vašim vizuálním skriptům reakce na aktualizace stavu. Použijte uzel události On State Changed a propojte jeho vstupy na levé straně s libovolnou proměnnou skriptu nebo vlastností komponenty, kterou chcete sledovat u změn, a uzel události aktivuje váš skript (připojený k pravé straně) pokaždé, když některé z proměnných nebo vlastností připojených k ní změní jejich hodnotu.

______________

Funguje to se sdíleným stavem i s místním stavem. Událost On State Changed se aktivuje bez ohledu na to, jestli proměnné nebo vlastnosti, ke které dochází, byly změněny místním klientem, vzdáleným klientem nebo dokonce vzdáleným klientem před tím, než se místní klient dokonce připojil k místnosti.

Použití funkce Při změně stavu k reakci na změny stavu je efektivní: Není k dispozici žádná nečinná šířka pásma ani náklady na výkon. Tímto způsobem můžete mít libovolný počet vizuálních skriptů, které pasivním způsobem naslouchají aktualizacím stavu, aniž by to mělo negativní vliv na frekvenci snímků nebo využití šířky pásma vašeho prostředí.

Pozdní spojení

Pozdní připojení nastane, když se klient připojí k místnosti, která už k ní má připojené další klienty.

Při pozdním připojení získá Mesh aktuální stav místnosti ze serveru – například od toho, kdo je už v místnosti a kde jsou jejich avatary aktuálně umístěné – a rychle připraví místní verzi sdíleného prostředí klienta pro připojení tak, aby odpovídala stavu sdílenému všemi uživateli v místnosti.

Ve velké části funguje skriptování vizuálů Mesh stejně. Všechny vlastnosti sdílené komponenty a proměnné vizuálního skriptu, které byly změněny v místnosti před tím, než se klient právě připojí, se aktualizují místně tak, aby odpovídaly sdílenému stavu, a pak se aktivují všechny uzly událostí Při změně stavu, které pozorují tyto vlastnosti nebo proměnné.

Pozdní joinery nepřehrávají sdílené události – získají sdílený stav.

Z pohledu místního klienta se prostředí vždy vyvíjí z počátečního stavu, které mělo hned po načtení scény, kterou jste nahráli do Mesh. V případě pozdního připojení může být první změna stavu větší než to, co se stane, když místní uživatel komunikuje s místností v probíhající relaci, ale je to úplně totéž v zásadě.

To vše se děje, když se prostředí načte, než se dokonce zčerná. Jakmile uživatel skutečně uvidí prostředí a interaguje s ním, je už pozdní připojení hotové.

Nastavení místního stavu podle sdíleného stavu

Velmi často může uživatel v prostředí sledovat "sdílený stav" je ve skutečnosti kombinací stavu sdíleného přímo službou Mesh a místním stavem vytvořeným vizuálními skripty v reakci na událost, ke které došlo v místnosti. Když například uživatel překlopí přepínač v prostředí (sdílený stav), může vizuální skript změnit barvu skyboxu (místní stav). Možná budete chtít použít místní změnu (aktualizovat barvu skyboxu) přímo v reakci na uživatele, který s přepínačem pracuje. I když se však událost interakce vyskytuje na všech klientech aktuálně v místnosti, žádný klient, který se připojí k místnosti později, tuto událost nedostane jednoduše proto, že tam nebyli, když k ní došlo. Místo toho byste měli nastavit, aby místní stav sledoval sdílený stav takto:

  1. Když uživatel komunikuje (například překlopí přepínač), aktivujte tuto aktivační událost místní událost, která aktualizuje sdílenou proměnnou (například stav zapnuto/vypnuto přepínače).
  2. Pomocí funkce Při změně stavu můžete sledovat sdílenou proměnnou.
  3. Když se událost On State Changed aktivuje (protože sdílená proměnná změnila její hodnotu), použijte libovolnou místní změnu (například aktualizujte barvu skyboxu).

Tímto způsobem je místní stav (barva skyboxu) následující sdílený stav (stav přepínače). To je hezké, že to funguje beze změny pro místního klienta, který překlopil přepínač, pro všechny ostatní vzdálené klienty, kteří jsou přítomni v místnosti najednou, a pro všechny budoucí klienty, kteří se připojí k místnosti později.

Nastavení místního stavu podle sdíleného stavu: Osvědčené postupy

Místní události: Například uzel události On State Changed pozorující vlastnost Is Selected Místně komponenty Mesh Interactable Body:

  • 🆗 Může změnit místní stav, který je soukromý na klienta. Tyto změny stavu zůstanou výhradně na místním klientovi a při opuštění relace zmizí.
  • 🆗 Může změnit sdílený stav.
  • Místní stav nelze změnit tak, aby byl konzistentní mezi klienty. Místní událost se spustí jenom na jednom klientovi, takže aktualizace potřebné k zachování konzistentního místního stavu napříč klienty se prostě nestane u žádného jiného klienta.

Sdílené události: Například uzel události On Trigger Enter připojený ke sdílené fyzice triggeru kolaci:

  • 🆗 Může změnit místní stav pro momentální efekty: Například částicový efekt nebo krátký zvukový efekt. Místní efekt uvidí jenom klienti, kteří jsou v místnosti, když dojde ke sdílené události; klienti, kteří se později připojují k místnosti, nebudou.
  • Místní stav nelze změnit tak, aby byl konzistentní mezi klienty. Sdílená událost se spustí jenom u klientů, kteří jsou přítomni v době, kdy k ní dochází, ale nebude se přehrávat pro klienty, kteří se k relaci připojují později.
  • Nesmí změnit sdílený stav. Vzhledem k tomu, že se sdílená událost spustí na všech klientech, vše, co dělá, provádí všichni klienti velmi blízko v čase. V závislosti na povaze změny se může několikrát opakovat (například čítač skóre se může zvýšit o více než jeden v reakci na jednu událost).

U událostí Změny stavu, které sledují sdílený stav ve sdílených proměnných nebo vlastnostech sdílené komponenty:

  • 🆗 Může změnit místní stav tak, aby byl konzistentní se sdíleným stavem napříč klienty. Aby to fungovalo dobře v opakovatelném a konzistentním způsobu pro všechny klienty, musíte přeložit všechny možné nové hodnoty pozorovaného sdíleného stavu do místního stavu, nejen několik přechodů stavu vybraných třešně (například Je vybráno se stává true).

Nastavení místního stavu podle sdíleného stavu: Příklad

V tomto příkladu jsou v tomto prostředí dvě interaktivní tlačítka: jedna označená hvězdičkou, druhá označená "Houbou". Výběr některého z tlačítek má udělat dvě věci:

  • Uložte odpovídající popisek do proměnné sdíleného řetězce s názvem ObjectKind.
  • Uložte odkaz na odpovídající objekt scény v místní referenční proměnné GameObject s názvem ObjectRef.

Tady jsou dva toky skriptu, jeden pro každé tlačítko. Každý naslouchá sdílené Is Selected vlastnost jednoho tlačítka Mesh Interagovatelné body komponenta a aktualizuje ObjectKind a ObjectRef v závislosti na tom, které tlačítko bylo vybráno:

______________

Zdá se, že všechno funguje správně, ale pouze pro uživatele, kteří jsou již v místnosti, když je vybrána některá z tlačítek. Každý uživatel, který se připojí k relaci později, najde nekonzistentní stav v místní verzi sdíleného prostředí: Pouze ObjectKind je správně nastaven podle naposledy vybraného tlačítka, ale ObjectRef zůstane null.

Co je s těmito dvěma toky skriptů špatně?

Nejprve si všimněte, že tyto toky skriptu se aktivují sdílenou událostí, protože oba naslouchají změně sdílené vlastnosti Je vybráno každé tlačítko. Zdá se, že to dává smysl, protože je to jediný způsob, jak získat místní proměnnou ObjectRef , která se má aktualizovat na všech klientech.

Mějte však na paměti následující:

  • Sdílené události nesmí měnit sdílený stav , ale tyto toky skriptu aktualizují sdílenou proměnnou ObjectKind .
  • Sdílené události nemohou změnit místní stav tak, aby byly konzistentní napříč klienty , ale tyto toky skriptů aktualizují místní proměnnou ObjectRef , kterou máme v úmyslu být konzistentní pro všechny klienty, stejně jako ObjectKind.

Takže způsob, jakým je to aktuálně nastavené, bychom ve skutečnosti neměli dělat nic z toho, co potřebujeme, abychom udělali tlačítka.

Jediným zjevným způsobem, jak se z tohoto problému dostat, je vytvořit události, které aktivují tyto toky, místní. Můžeme to udělat tak, že uzel události On State Changed sleduje vlastnost Je vybrána místně místo funkce Je vybrána.

S událostí, která je teď místní, to znamená...

  • Místní události můžou změnit sdílený stav , takže teď můžeme bezpečně aktualizovat sdílenou proměnnou ObjectKind a její hodnota se automaticky sdílí mezi klienty pomocí integrovaných sítí visual scriptingu mesh.
  • Místní události nemohou změnit místní stav tak, aby byly konzistentní napříč klienty , takže v těchto tocích skriptu nemůžeme aktualizovat místní proměnnou ObjectRef . Budeme muset najít jiný způsob.

Tyto dva toky skriptů vypadají po těchto změnách:

______________

Co můžeme udělat, abychom nastavili místní proměnnou ObjectRef , aby byla konzistentní s touto proměnnou? Tyto dva toky skriptů už naštěstí navazují nějaký sdílený stav, který můžeme sledovat: sdílenou proměnnou ObjectKind . Stačí použít událost On State Changed , která sleduje tuto proměnnou a aktualizuje místní proměnnou ObjectRef v závislosti na její hodnotě:

______________

Je to skvělý způsob, jak to udělat, protože události On State Changed , které pozorují sdílený stav, můžou změnit místní stav tak, aby byly konzistentní s ním. To bude fungovat pro klienta, který stiskl tlačítko, pro všechny ostatní klienty, kteří se nacházejí ve stejné místnosti současně, a pro všechny klienty, kteří se k relaci připojí později.

Nástrahy sítí

Sdílené aktualizace s vysokou frekvencí

Skriptování vizuálů mesh ve výchozím nastavení sdílí téměř celý stav scény. To je skvělé pro sdílení, ale může se také náhodou plížit a způsobit zbytečné zatížení sítě. Například následující tok skriptu zahltí síť redundantními aktualizacemi rotace transformace. Vzhledem k tomu, že ho všichni klienti spouští současně, žádná ze vzdálených aktualizací nikdy nebude mít skutečný dopad na všechny klienty místně:

______________

V tomto případě byste pravděpodobně měli použít obor místního skriptu k tomu, aby komponenta Transformace byla místní pro každého klienta. Také byste pravděpodobně měli použít komponentu Animatoru , a ne tok skriptu při aktualizaci , se kterým začnete.

V případě sady Mesh Toolkit 5.2411 se v Analyzátor výkonu okně Mesh Toolkit 5.2411 zobrazí upozornění "Vysokofrekvenční sdílená aktualizace" pro tento druh konstruktoru.

Při spuštění na každém klientovi

Můžete být lákaví představit si událost Při spuštění jako něco, co se spouští při spuštění relace, ale ve skutečnosti se aktivuje u každého klienta místně, když se připojí k relaci. Dokonale se hodí pro inicializaci místního stavu:

______________

Když se ale pokusíte použít při spuštění k inicializaci sdíleného stavu, zjistíte, že sdílený stav se neúmyslně znovu inicializuje pro všechny uživatele, kdykoli se někdo připojí k relaci:

______________

Panel Diagnostiky skriptování vizuálů mesh (od sady Mesh Toolkit 5.2410) a content Analyzátor výkonu (CPA) (od sady Mesh Toolkit 5.2411) zobrazí upozornění "Sdílená aktualizace při připojení k relaci", když to zjistí.

Sdílení je typu – ale přiřazení proměnné není

Z bezpečnostních a bezpečnostních důvodů jsou proměnné sdílených skriptů vizuálu silného typu. To znamená, že typ, který vyberete v komponentě Variables pro proměnné skriptu, které jste deklarovali, definuje, který přesný typ hodnoty bude synchronizován mezi klienty.

Skriptování vizuálu Unity bohužel při aktualizaci hodnoty úplně ignoruje deklarovaný typ proměnné. Například je snadné omylem uložit hodnotu typu Float do proměnné, která byla deklarována pro typ Integer. V rámci místního klienta si vaše vizuální skripty tuto chybu nevšimnou, protože skriptování vizuálů automaticky převede chybnou hodnotu Float na očekávané celé číslo , pokud je to potřeba. Pokud ale jde o synchronizaci této hodnoty mezi klienty, vizuální skriptování Mesh nemůže vzít stejné svobody: "Konečná konzistence" zaručuje, že jakýkoli převod hodnoty v letu a bezpečnostní a bezpečnostní aspekty znepřístupňují přijetí jiného typu hodnoty od vzdáleného klienta, než jaký byl deklarován pro proměnnou.

Představte si například tuto deklaraci sdílené proměnné s názvem MyIntegerVar:

______________

Toto je tok skriptu, který aktualizuje tuto proměnnou:

______________

Co by se mohlo pokazit? Uzel skriptu náhodného | rozsahu použitý v tomto příkladu má bohužel dvě varianty: jeden, který vytvoří náhodnou celočíselnou hodnotu a jeden, který vytvoří náhodnou hodnotu Float. Rozdíl mezi těmito dvěma uzly skriptu na panelu selektoru uzlů je malý:

______________

Pokud tedy omylem vyberete nesprávný uzel skriptu náhodného | rozsahu, může se stát, že váš skript neúmyslně uloží hodnotu Float do proměnné typu Integer, ale tato chybná hodnota Float se nebude replikovat do žádného jiného klienta.

Mějte na paměti, že se může zdát, že sdílená proměnná, kterou jste vytvořili, přestala být sdílená. Budoucí verze skriptování vizuálů mesh mohou upozornit na tento druh chyby skriptu, když ji mohou zjistit.

Další kroky