Interaktion*

I VR-sammanhang Àr "interaktion" specifikt nÀr VR-utrustningen interagerar med den virtuella miljön. Till exempel Àr en VR-handkontroll anvÀnds för att plocka upp nÄgot eller trycka pÄ en knapp.

(Om man vill köra kod sjĂ€lv nĂ€r spelaren trycker pĂ„ en knapp – se controllers)

XR Interaction Manager

Om du tÀnkt ha nÄgon form av interaktion i din scen sÄ behöver ocksÄ nÄgot objekt ha en XR Interaction Manager-komponent. LÀgg till den i XR Origin eller skapa ett helt nytt objekt som bara innehÄller komponenten genom att högerklicka i Hierarchy och vÀlja XR och Interaction Manager.

Interactors och interactibles

Interaktion i XR Toolkit sker mellan interactors och interactibles.

Objekt som har en interactible-komponent kan man göra nĂ„got med – plocka upp, kasta, trycka pĂ„, dra i, öppna.

Objekt som har en interactor-komponent kan sedan pÄverka dessa interactible-objekt.

Exempel: Man vill kunna trycka pÄ en knapp med sin VR-handkontroll. Knappen behöver dÄ en interactible-komponent och VR-handkontrollen behöver en interactor-komponent.

Interaction layer mask

Oavsett om det gÀller ray interaction eller direct interaction kan interaction layers anvÀndas för att bestÀmma vilka objekt som ska kunna interageras med. Interaction layers fungrar ungefÀr som vanliga lager.

BĂ„de XR Ray Interactor och XR Direct Interactor-komponenterna har en Layer Interaction Mask-variabel.

Precis som med vanliga lager anvÀnds Add Layer för att skapa nya lager. Se till sÄ att bara de lager just denna interactor ska kunna interagera med Àr förkryssade. Detta blir extra viktigt om du vill ha olika sorters interactors för teleportation och att plocka upp föremÄl. Om du anvÀnder prefab-versionen av XR-riggen sÄ utgÄr den frÄn att lager 31 Àr "teleportationslagret".

Interactors*

Det finns tre huvudsakliga interactors:

  • XR Ray Interactor – En strĂ„le som normalt utgĂ„r frĂ„n VR-handkontrollen och gör att man kan interagera med det strĂ„len trĂ€ffar.

  • XR Direct Interactor – AnvĂ€nder en collider och gör att man kan interagera med det collidern rör vid.

  • XR Poke Interactor – Gör att man kan interagera med objekt, och med UI-element, genom att "peta" pĂ„ dem.

Man kan bara ha en av dem pĂ„ varje XR-controller, sĂ„ om man vill anvĂ€nda flera – se teleportation till exempel – fĂ„r man hitta en workaround av nĂ„got slag. Oftast sker det genom att man har flera under-objekt som var och ett har en egen interactor. SĂ„ Ă€r det t.ex. löst i XR Origin (XR Rig)-prefaben.

Objekten som motsvarar dina VR-handkontroller finns i din XR Origin, under Camera Offset.

Ray interaction

Vid ray interaction sÄ skjuter lÄnga "strÄlar" ut frÄn VR-handkontrollerna och föremÄl som trÀffas av strÄlarna kan handkontrollerna interagera med. Till exempel kan man dÄ plocka upp föremÄl pÄ distans genom att sikta pÄ dem med strÄlarna och trycka pÄ en knapp pÄ controllern.

Som minst behöver VR-handkontrolls-objektet som ska anvÀnda ray interaction en XR Ray Interactor-komponent. Normalt lÀgger man ocksÄ till en XR Interactor Line Visual-komponent som för att strÄlen som skjuter ut syns. DÄ lÀggs ocksÄ en Line Renderer-komponent till automatiskt.

NÀr XR Origin-objektet skapas sÄ ges bÄda VR-handkontrollerna de komponenter som behövs för ray interaction.

Direct interaction

Vid direct interaction mÄste VR-handkontrollen (eller den collider som Àr pÄ samma objekt som Direct Interactor-scriptet) fysiskt röra vid mÄlobjektet för att interaktion ska kunna se. DÄ kan man inte interagera med saker pÄ distans utan mÄste vara nÀra dem.

LÀgg till en XR Direct Interactor-komponent till det VR-handkontroll-objektet som ska anvÀnda direct interaction. LÀgg ocksÄ till en Sphere Collider (Trigger); den kommer att anvÀndas för att kÀnna av kollisionen mellan interactorn och objekten.

Poke interaction*

Interactors och kod

För att komma Ät XR Toolkits klasser etc, lÀgg till detta bland dina using statements:

using UnityEngine.XR.Interaction.Toolkit;

Komponentdatatyper

Basklassen för alla interactors Ă€r XRBaseInteractor. De andra heter liknande saker – XRDirectInteractor, XRRayInteractor och XRPokeInteractor.

XRBaseInteractor interactor = GetComponentInChildren<XRRayInteractor>();

interactablesHovered

foreach (IXRHoverInteractable interactable in interactor.interactablesHovered)
{
  // skriver ut namnet pÄ objektet som hovras över
  Debug.Log(interactable.transform.name);
}

Interactables – föremĂ„l som kan interageras med

För att göra sÄ att ett objekt kan interageras med, behöver det en Interactable-komponent. Det finns flera olika.

KomponentBeskrivning

XR Grab Interactable

Objekt som kan plockas upp genom att man trycker pÄ Grab-knappen

XR Simple Interactable

Enklast möjliga: objektet kan interageras med men saknar inbyggd funktionalitet.

XR Socket Interactable

Objekt som andra objekt kan sÀttas fast pÄ. En mer detaljerad genomgÄng finns t.ex. hÀr.

Objektet behöver ocksÄ en collider av nÄgot slag, och antagligen en RigidBody. Fysik-systemet anvÀnds för att avgöra om objektet kolliderar med en VR-handkontroll eller med en strÄle frÄn ray interaction.

Reagera visuellt

En XR Tint Interactable Visual-komponent gör att objektet fÄr en tydlig visuell indikation pÄ att det Àr det nuvarande mÄlet för interaktionen.

Reagera med kod via Events

Objekt som har nĂ„gon form av Interactable-komponent kommer att ha ett antal Interactable Events som kan knytas till specifika metoder i kod – precis som events i det vanliga UI-systemet.

I listan Àr det mesta ganska sjÀlvförklarande, men det finns tre viktiga begrepp:

  • Hover betyder att spelaren markerat objektet med en strĂ„le (ray interactor) eller en VR-handkontroll (direct interactor).

  • Select betyder att spelaren tryckt pĂ„ grepp-knappen pĂ„ sin VR-handkontroll. Man kan Ă€ndra vilken knapp som gör "select" om man vill.

  • Activate betyder att spelaren tryckt pĂ„ trigger-knappen pĂ„ sin VR-handkontroll. Man kan Ă€ndra vilken knapp som gör "activate" om man vill. OBS: För att Activate ska ske mĂ„ste Grab ha skett först.

I exemplet nedan aktiveras metoden DoSomething i CapsuleController-scriptet som finns i objektet Capsule nÀr spelaren markerat objektet med antingen sin strÄle (ray interactor) eller sin VR-handkontroll (direct interactor)

Reagera med kod – bara kod

I scripts som ligger pĂ„ det interagerbara objektet kan man skriva kod för att lĂ€gga till metoder direkt – utan att gĂ„ via den visuella Events-listan. Man gör dĂ„ detta genom att anvĂ€nda AddListener-metoden pĂ„ Interactable-komponenten.

Exemplet nedan gÀller XR Grab Interactables, men motsvarande gÀller ocksÄ övriga.

CubeController.cs
using UnityEngine.XR;
using UnityEngine.XR.Interaction.Toolkit;

public class CubeController : MonoBehaviour
{
  XRBaseInteractable interactable;

  void Awake()
  {
    interactable = GetComponent<XRGrabInteractable>();
    interactable.activated.AddListener(ActivateEvent);
  }

  void ActivateEvent(ActivateEventArgs args)
  {
    // Det som ska hÀnda
  }
}

Exempel: Köra kod pÄ objekt man pekar pÄ, nÀr man trycker pÄ avtryckaren

Om man vill att nÄgot ska hÀnda direkt nÀr spelaren pekar sin controller, med ray interactor, mot ett föremÄl och trycker pÄ avtryckaren sÄ kan man kombinera tekniker sÄ hÀr:

EnemyController
public class EnemyController : MonoBehaviour
{
  public void Damage()
  {
    Debug.Log("Damaged!");
  }
}

EnemyController lĂ€ggs pĂ„ objektet som ska kunna pĂ„verkas – skadas, i det hĂ€r fallet.

GunController, nedan, lÀggs pÄ Left Controller och Right Controller.

Det GunController gör Àr att först hitta referenser till ActionBasedController (som sköter input-delen) och XRRayInteractor (som sköter kollen av vilka objekt man pekar pÄ).

NÀr spelaren sedan trycker pÄ Activate-knappen (avtryckaren) sÄ körs metoden Fire, som gÄr igenom alla objekt som XRRayInteractorn kÀnner av, och ifall de har en EnemyController-komponent sÄ körs dess Damage-metod.

GunController.cs
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.XR.Interaction.Toolkit;

public class GunController : MonoBehaviour
{
  ActionBasedController controller;
  XRBaseInteractor interactor;

  void Awake()
  {
    controller = GetComponent<ActionBasedController>();
    interactor = GetComponentInChildren<XRRayInteractor>();

    controller.activateAction.action.started += Fire;
  }

  void Fire(InputAction.CallbackContext ctx)
  {
    foreach (IXRHoverInteractable interactable in interactor.interactablesHovered)
    {
      if (interactable.transform.TryGetComponent<EnemyController>(out EnemyController controller))
      {
        controller.Damage();
      }
    }
  }
}

Last updated