Malování pomocí štětce ve VR
Úvod
V tomto tutoriálu společně vytvoříme ve virtuální realitě nástroj Štětec, pomocí kterého bude možné v prostoru malovat. Pro ovládání VR hardware použijeme XR Interaction Toolkit, který je součástí Unity jako balíček.
Prerekvizity
- Unity Engine 3D verze 2019.4
- XR Interaction Toolkit balíček - Stáhne se skrze Unity přes
Window → Package Manager → XR Interaction Toolkit
. Pokud ho v seznamu balíčků nemůžete najít, klikněte naAdvanced → Show preview packages
. Balíček nainstalujte kliknutím na tlačítkoInstall
. - Po instalaci balíčku zkontrolujte, že potřebné SDKs jsou také nainstalované. Bežte do
Edit → Project Settings → Player
a úplně dole klikněte naVirtual Reality Supported
. Níže by se po chvíli měli objevit SDK pro Oculus a OpenVR, které je i pro HTC Vive headset.
Připravení scény a XR Rigu
Do scény umístíme jednoduchou plochu, která bude sloužit jako zem pomocí kliknutí pravého tlačítka do projektové hierarchie a 3D Object → Plane
a následně vytvoříme také XR → Device-based → Room-Scale XR Rig
, což je objekt, který bude řídit a sledovat náš VR hardware. Tento objekt je právě součástí XR Interaction Toolkitu, pokud ho v nabídce nemáte, ujistěte se, že jste balíček nainstalovali.
Komponenta XR Rig
se skládá z hlavní kamery a levé a pravé ruky s předem připnutými skripty. Pro účely tohoto návodu nebude potřeba skriptů XR Ray Interactor
a Line Visual
, které jsou připnuté na obou rukách. Můžeme je tedy bez problému smazat. Na každém kontroleru tedy ve výsledku zůstane pouze základní skript XR Controller
. Pro interakce a sebrání štetce naopak ještě jeden skript z XR Interaction toolkitu přidáme a tím je XR Direct Interactor
. Tomuto skriptu nemusíme nastavovat žádné specifické hodnoty. V neposlední řadě přídáme na obě ruce Sphere Collider
, kterému nastavíme Radius
na 0.2
a zaškrtneme ho jako Is Trigger
.
Obě ruce mají ve skriptu místo na model, který je bude ve VR reprezentovat. Momentálně pokud spustíme hru, naše controllery totiž neuvidíme. Vytvořme v projektové hierarchii prázdný objekt s názvem Hand
a přetáhněme pod něj model ovladače pro HTC Vive, který si můžete stáhnout společně s texturami níže. V projektu si vytvořte složku Models
, Textures
, Materials
a Prefabs
pro lepší přehlednost.
Jak zmiňuji výše, stažený model ovladače vložíme jako dítě pod prazdný objekt Hand
a pootočíme ho okolo osy Y o 180 stupňů, aby měl správnou orientaci. Vytvoříme nový materiál pomocí kliku pravého tlačítka, přiřadíme staženou texturu do Albedo
políčka a přetáhnutím nastavíme materiál na model ovladače. Celý objekt Hand
poté vezmeme a přetáhneme do složky Prefabs
, uděláme z něj tím instanciovatelný objekt, sloužící jako šablona.
Levé i pravé ruce v XR Rigu
nastavíme Model Prefab
právě tuto námi vytvořenou šablonu. Poté můžeme ze scény objekt Hand
smazat, stačí, že žije ve složce Prefabs
.
Model štětce
Pro usnadnění práce jsem pro vás připravil model štětce společně s texturama, které jsou stažené z odsud. Níže uvedené soubory umístěte do patřičných složek.
Po stažení a importu výše uvedených assetů vytvoříme 3 nové materiály. Brush_bottom
materiálu namapujeme stažené textury dřeva a přetahneme ho na spodní část modelu štětce. Brush_top
bude sestávat ze stažených textur pro ocel a přetáhneme ho na násadu v horní části. Brush_head
materiál přetáhneme na úplnou špičku štětce, využijeme ho až později, až budeme potřebovat dynamicky změnit jeho barvu. Jeho barvu prozatím necháme defaultní bílou.
Uchopení štetce
Předtím než budeme se štětcem kreslit, nejdříve ho uděláme uchopitelným. Na kořenový objekt tak připneme skript XR Grab Interactable
(tento skript je také součástí XR Interaction Toolkitu). Všimněme si, že se automaticky na objekt přidalo i Rigidbody
komponenta, která udává jak na předmět působí ve virtuálním světě fyzika. Vzhledem k tomu, že nechceme, aby nám štětec pořád padal na zem, zaklikněme Is Kinematic
checkbox a odškrtněme Use Gravity
.
V inspektoru přidáme objektu nový komponent a tím bude Box Collider
, který slouží XR Grab Interactable
skriptu k detekci kolize s naším ovladačem. Tlačítkem Edit Collider
nastavíme přímo ve scéně odpovídající velikost tak, aby kopírovala štětec. Je důležité, tento nově vytvořený collider ručně přetáhnout do proměnné Colliders
v XR Grab Interactable
skriptu (znázorněno na obrázku). Níže ve skriptu si můžeme všimnout rozbalovacího panelu, který skrývá interaktivní eventy, na které můžeme nějak reagovat a volat jiné funkce. Tuto funkcionalitu za chvíli použijeme.
Zkuste teď zapnout hru a měli byste být schopni uchopit štětec do ruky. Předtím nezapomeňte korektně naškálovat štětec, aby nebyl moc veliký nebo malý a zároveň byl v dosahu XR Rigu. Nemáme implementován totiž pohyb ve VR. Na ovladači stáčí zmáčknout boční Grip
tlačítko a držet ho. Štětec tak uchopíme do ruky. Je však špatně napozicován, což spravíme vytvořením takzvaného pivota (prázdný GameObject umístěn jako dítě pod hlavní objekt štětce), kterého libovolně natočíme a jeho Transform
přetáhneme do Attach Transform
proměnné v XR Grab Interactable
skriptu. V mém případě jsem m udal rotaci X: -90, Y: 0, Z: -45
Kreslící skript
XR Rig, model štětce a interakci uchopení už máme připravenou. Teď už jen stačí implementovat funkcionalitu kreslení. Začněme tím, že vytvoříme nový skript Draw.cs
, který připneme na kořenový objekt štětce. Jeho první proměnnou bude pozice, odkud se má začít kreslit. Dále pak šířka čáry, její barva a parametrizovatelná vzdálenost mezi jednotlivými body křivky. Ostatní privátní proměnné slouží k uchovávání aktuálně kreslené čáry pomocí komponenty Line Renderer
.
Pomocí dvou Public
metod pak budeme moci začít a přerušit vlastní kreslení. Tyto metody budou volány z XR Grab Interactable
skriptu po vyvolání příslušných Eventů. Tyto metody se jmenují StartDrawing
a StopDrawing
a vypadají nějak takto.
Na závěr máme metodu UpdateDrawing
, která kontroluje vzdálenost mezi hrotem štětce a naposledy vytvořeným bodem a pokud je větší jak zadaná vzdálenost, zavolá druhou privátní metodu UpdateLine
, která přidá křivce další bod a vykreslí mezi nimi čáru. Zároveň nastaví čáře danou šířku a barvu v podobě materiálu. Samozřejmostí je, že metoda UpdateDrawing
se musí volat každý snímek, protože uživatel bude se štětcem pořád hýbat. Celá podoba skriptu je tedy zde.
Po návratu do Editoru je nutné přetáhnout a inicializovat parametry dříve vytvořeného skriptu. Vytvořme prázdný objekt tip
, který bude reprezentovat hrot štětce a umístěme ho tam. Následně ho přetáhneme do Draw
skriptu do kolonky Draw Position Source
. Parametr Line Width
doporučuji nastavit na 0.005, Distance Threshold
na 0.01 a Line Material
můžeme nastavit jako Default-Line
(už přítomný v Assets od Unity). S těmito hodnotami si samozřejmě můžete hrát, záleží na tom, čeho chcete dosáhnout.
Posledním krokem je nastavení již zmiňovaných XR Grab Interactable
eventů. V kolonce On Activate
přidáme nový listener a přetáhneme do něj připnutý Draw
skript. Vpravo najdeme veřejnou metodu StartDrawing
. To samé provedeme s eventem On Deactivate
, zde akorát přiřadíme metodu StopDrawing
. Po stistknutí Trigger
tlačítka na ovladači se tak zavolají námi vytvořené metody v Draw
skriptu. Výsledné nastavení vypadá takto.
Můžete spustit scénu, uchopit štětec a začít v prostoru kreslit. Vlastní čára se skláda z bodů, mezi kterými se vykresluje křivka. Tento shluk bodů existuje ve scéně jako všechny ostatní GameObjecty.
Závěr
V tomto krátkém tutoriálu jsme společně zvládnuli importovat model štětce, připravit XR Rig za pomoci XR Interaction Toolkitu a implementovat funkcionalitu kreslení pomocí Draw.cs
skriptu. Zkuste jako domácí úkol přidat možnost výběru barvy. Výběr barvy můžete namapovat na touchpad, kde si zjistíte X a Y souřadnici doteku palce a po konverzi těchto souřadnic dostanete barvu v HSV prostoru. Dynamicky pak dokážete změnit materiál barvy