Jak dodać niemal interakcyjność

Prawie interakcje mają postać dotknień i chwycić. Zdarzenia dotykowe i chwytują są wywoływane jako zdarzenia wskaźnika odpowiednio przez pokePointer i SpherePointer.

Aby nasłuchiwać zdarzeń dotykowych i/lub pobierać zdarzenia wejściowe określonego gameObject, wymagane są trzy kluczowe kroki.

  1. Upewnij się, że odpowiedni wskaźnik jest zarejestrowany w głównym profilu konfiguracji mrtk.
  2. Upewnij się, że żądany element GameObject ma odpowiedni składnik skryptu do chwycić lub dotykać i Unity Collider .
  3. Zaimportuj interfejs obsługi danych wejściowych w dołączonym skrypcie do żądanego modułu GameObject, aby nasłuchiwać zdarzeń chwytnych lub dotykowych.

Dodawanie interakcji chwytnych

  1. Upewnij się, że wskaźnik SpherePointer jest zarejestrowany w profilu wskaźnika MRTK.

    Domyślny profil MRTK i domyślny profil HoloLens 2 zawierają już punkt sfery. Można potwierdzić, że zostanie utworzony program SpherePointer, wybierając profil konfiguracji MRTK i przechodząc do opcji > wskaźników > wejściowych. Domyślny GrabPointer prefabrykcję (Assets/MRTK/SDK/Features/UX/Prefabs/Pointers) powinien być wymieniony jako Typ kontrolera o typie wyrażanej ręki. Niestandardowego prefabrykatu można używać tak długo, jak implementuje SpherePointer klasę .

    Przykład profilu chwyć wskaźnik

    Domyślny wskaźnik chwytuje obiekty znajdujące się w pobliżu w pobliżu punktu chwytnego, aby dopasować go do domyślnego interfejsu urządzenia Hololens 2.

    Conical Grab Pointer

  2. W zadaniu GameObject, który powinien być chwytywalny, dodaj , a NearInteractionGrabbable także collider.

    Upewnij się, że warstwa gameObject znajduje się na warstwie, która można pobrać. Domyślnie wszystkie warstwy z wyjątkiem spatial awareness i ignore Raycasts są dostępne do przechwytowania. Sprawdź, które warstwy można pobrać, sprawdzając maski chwytujące warstwy w prefabrykcie programu GrabPointer.

  3. W obiekcie GameObject lub jednym z jego elementów nadrzędnych dodaj składnik skryptu, który implementuje IMixedRealityPointerHandler interfejs. Każdy element nadrzędny obiektu z obiektem będzie NearInteractionGrabbable również mógł odbierać zdarzenia wskaźnika.

Przykład chwyć kod

Poniżej znajduje się skrypt, który będzie drukować, jeśli zdarzenie jest dotknięcie lub chwycić. W odpowiedniej funkcji interfejsu IMixedRealityPointerHandler można przyjrzeć się typowi wskaźnika, który wyzwala to zdarzenie za pośrednictwem obiektu MixedRealityPointerEventData . Jeśli wskaźnik jest wskaźnikiem SpherePointer, interakcja jest chwytąc.

public class PrintPointerEvents : MonoBehaviour, IMixedRealityPointerHandler
{
    public void OnPointerDown(MixedRealityPointerEventData eventData)
    {
        if (eventData.Pointer is SpherePointer)
        {
            Debug.Log($"Grab start from {eventData.Pointer.PointerName}");
        }
        if (eventData.Pointer is PokePointer)
        {
            Debug.Log($"Touch start from {eventData.Pointer.PointerName}");
        }
    }

    public void OnPointerClicked(MixedRealityPointerEventData eventData) {}
    public void OnPointerDragged(MixedRealityPointerEventData eventData) {}
    public void OnPointerUp(MixedRealityPointerEventData eventData) {}
}

Dodawanie interakcji dotykowych

Proces dodawania interakcji dotykowych w elementach aparatu UnityUI jest inny niż w przypadku vanilla 3D GameObjects. Możesz przejść do następującej sekcji, Unity UI, w celu włączenia składników interfejsu użytkownika aparatu Unity.

Jednak w przypadku obu typów elementów środowiska użytkownika upewnij się, że element PokePointer jest zarejestrowany w profilu wskaźnika MRTK.

Domyślny profil MRTK i domyślny profil HoloLens 2 zawierają już punkt pokePointer. Można potwierdzić, że zostanie utworzony pokePointer, wybierając profil konfiguracji MRTK i wybierając pozycję Opcje > wskaźnika > wskaźników wejściowych. Domyślna PokePointer przedfabryka (Assets/MRTK/SDK/Features/UX/Prefabs/Pointers) powinna być wymieniona z typem kontrolera o typie wyrażanej ręki. Niestandardowego prefabrykatu można używać tak długo, jak implementuje PokePointer klasę .

Przykład profilu wskaźnika poke

3D GameObjects

Istnieją dwa różne sposoby dodawania interakcji dotykowych do obiektów GameObject 3D, w zależności od tego, czy obiekt 3D powinien mieć tylko jedną płaszczyznę dotykową, czy też powinien być dotykowy w oparciu o cały kolider. Pierwszy sposób jest zwykle w przypadku obiektów z boxcolliders, gdzie pożądane jest, aby tylko jedna twarz sortidera reagowała na zdarzenia dotykowe. Drugi jest dla obiektów, które muszą być dotknięcie z dowolnego kierunku na podstawie ich kolidu.

Dotyk z pojedynczą twarzą

Jest to przydatne w sytuacjach, w których tylko jedna twarz musi być dotkliwalna. Ta opcja zakłada, że obiekt gry ma boxcollider. Można jej używać z obiektami innymi niż BoxCollider. W takim przypadku właściwości "Bounds" i "Local Center" można ustawić ręcznie, aby skonfigurować płaszczyznę dotykową (tj. granice powinny być ustawione na wartość niezerową).

  1. W pliku GameObject, który powinien być dotykowy, dodaj składnik BoxCollider i [ NearInteractionTouchable (xref:Microsoft.MixedReality.Toolkit.Input.NearInteractionTouchable).

    1. Ustaw ustawienie Events to Receive to Touch (Odbieranie na dotyk), jeśli w poniższym skrypcie składnika używasz interfejsu [ IMixedRealityTouchHandler ] (xref:Microsoft.MixedReality.Toolkit.Input.IMixedRealityTouchHandler) w skrypcie składników.

    2. Kliknij pozycję Fix bounds (Rozwiąż granice) i Fix Center (Napraw centrum)

    NearInteractionTouchable Setup

  2. Na tym obiekcie lub jednym z jego elementów nadrzędnych dodaj składnik skryptu, który implementuje element IMixedRealityTouchHandler Interfejs. Każdy element nadrzędny obiektu z elementem [ NearInteractionTouchable ] (xref:Microsoft.MixedReality.Toolkit.Input.NearInteractionTouchable) będzie mógł również odbierać zdarzenia wskaźnika.

Uwaga

W widoku sceny edytora z wybranym elementem NearInteractionTouchable GameObject zwróć uwagę na biały kwadrat i strzałkę konturu. Strzałka wskazuje "przód" kierunkowego. Możliwe do kolizji będzie można dotykać tylko z tego kierunku. Aby można było dotykać kolidu we wszystkich kierunkach, zobacz sekcję na dowolnym dotyku kolidu. NearInteractionTouchable Gizmos

Dowolny dotyk z kolidem

Jest to przydatne w sytuacjach, w których obiekt gry musi być dotykalny wzdłuż całej twarzy kolidu. Na przykład może to służyć do włączania interakcji dotykowych dla obiektu z elementem SphereCollider, gdzie cały collider musi być dotykowy.

  1. W zestawie GameObject, który powinien być dotykowy, dodaj element collider i składnik NearInteractionTouchableVolume [] (xref:Microsoft.MixedReality.Toolkit.Input.NearInteractionTouchableVolume).

    1. Ustaw ustawienie Events to Receive to Touch (Odbieranie na dotyk), jeśli w poniższym skrypcie składnika używasz interfejsu [ IMixedRealityTouchHandler ] (xref:Microsoft.MixedReality.Toolkit.Input.IMixedRealityTouchHandler) w skrypcie składników.
  2. Na tym obiekcie lub jednym z jego elementów nadrzędnych dodaj składnik skryptu, który implementuje element IMixedRealityTouchHandler Interfejs. Każdy element nadrzędny obiektu z elementem [ NearInteractionTouchable ] (xref:Microsoft.MixedReality.Toolkit.Input.NearInteractionTouchable) będzie mógł również odbierać zdarzenia wskaźnika.

Interfejs użytkownika aparatu Unity

  1. Dodaj/upewnij się, że w scenie znajduje się kanwa aparatu UnityUI.

  2. W zadaniu GameObject, który powinien być dotykowy, dodaj NearInteractionTouchableUnityUI składnik.

    1. Ustaw wartość Zdarzenia na Odbierz na Dotyk, jeśli korzystasz z IMixedRealityTouchHandler interfejsu w poniższym skrypcie składnika.
  3. Na tym obiekcie lub jednym z jego elementów nadrzędnych dodaj składnik skryptu, który implementuje IMixedRealityTouchHandler interfejs. Każdy element nadrzędny obiektu z obiektem będzie NearInteractionTouchableUnityUI mógł również odbierać zdarzenia wskaźnika.

Ważne

Obiekty mogą nie zachowywać się zgodnie z oczekiwaniami, jeśli znajdują się na nakładających się obiektach kanwy. Aby zapewnić spójne zachowanie, nigdy nie nakładaj się obiektów kanwy w scenie.

Ważne

W NearInteractionTouchable składniku skryptu dla właściwości Zdarzenia do odbierania są dostępne dwie opcje: Wskaźnik i Dotyk. Ustaw wartość Zdarzenia na Odbieranie na wskaźnik, jeśli jest on ustawiony na interfejs, i ustaw wartość Touch, jeśli używasz interfejsu w skrypcie składnika, który IMixedRealityPointerHandler IMixedRealityTouchHandler odpowiada/obsługuje zdarzenia wejściowe.

Przykład kodu dotykowego

Poniższy kod przedstawia element MonoBehaviour, który można dołączyć do elementu GameObject za pomocą składnika wariantu i reagować na NearInteractionTouchable dotknięcie zdarzeń wejściowych.

public class TouchEventsExample : MonoBehaviour, IMixedRealityTouchHandler
{
    public void OnTouchStarted(HandTrackingInputEventData eventData)
    {
        string ptrName = eventData.Pointer.PointerName;
        Debug.Log($"Touch started from {ptrName}");
    }
    public void OnTouchCompleted(HandTrackingInputEventData eventData) {}
    public void OnTouchUpdated(HandTrackingInputEventData eventData) { }
}

Przykłady skryptów prawie interakcji

Zdarzenia dotknięcia

Ten przykład tworzy sześcian, sprawia, że jest on dotykowy i zmienia kolor w dotyku.

public static void MakeChangeColorOnTouch(GameObject target)
{
    // Add and configure the touchable
    var touchable = target.AddComponent<NearInteractionTouchableVolume>();
    touchable.EventsToReceive = TouchableEventType.Pointer;

    var material = target.GetComponent<Renderer>().material;
    // Change color on pointer down and up
    var pointerHandler = target.AddComponent<PointerHandler>();
    pointerHandler.OnPointerDown.AddListener((e) => material.color = Color.green);
    pointerHandler.OnPointerUp.AddListener((e) => material.color = Color.magenta);
}

Chwyć zdarzenia

W poniższym przykładzie pokazano, jak można przeciągać projekt GameObject. Zakłada, że obiekt gry zawiera zderzacz.

public static void MakeNearDraggable(GameObject target)
{
    // Instantiate and add grabbable
    target.AddComponent<NearInteractionGrabbable>();

    // Add ability to drag by re-parenting to pointer object on pointer down
    var pointerHandler = target.AddComponent<PointerHandler>();
    pointerHandler.OnPointerDown.AddListener((e) =>
    {
        if (e.Pointer is SpherePointer)
        {
            target.transform.parent = ((SpherePointer)(e.Pointer)).transform;
        }
    });
    pointerHandler.OnPointerUp.AddListener((e) =>
    {
        if (e.Pointer is SpherePointer)
        {
            target.transform.parent = null;
        }
    });
}

Przydatne interfejsy API

Zobacz też