Freigeben über


Gamepad und Vibration

Auf dieser Seite werden die Grundlagen der Programmierung für Xbox One-Gamepads mit Windows.Gaming.Input.Gamepad und zugehörigen APIs für die Universelle Windows-Plattform (UWP) beschrieben.

Auf dieser Seite erhalten Sie Informationen zu folgenden Vorgängen:

  • Wie Sie eine Liste mit verbundenen Gamepads und deren Benutzern erstellen
  • Wie Sie ermitteln, ob ein Gamepad hinzugefügt oder entfernt wurde
  • Wie Sie Eingaben von Gamepads lesen
  • Wie Sie Vibrations- und Impulsbefehle senden
  • Verhalten von Gamepads als Benutzeroberflächennavigationsgeräte

Gamepadübersicht

Gamepads wie der Xbox Wireless Controller und der Xbox Wireless Controller S sind allgemeine Eingabegeräte für Spiele. Sie sind die Standardeingabegeräte für Xbox One und werden auch häufig von Windows-Spielern als Alternative zur Tastatur und Maus genutzt. Gamepads werden in Windows 10- und UWP-Apps für Xbox durch den Windows.Gaming.Input-Namespace unterstützt.

Xbox One-Gamepads sind mit einem Richtungspad (oder D-Pad) ausgestattet; Schaltflächen A, B, X, Y, Ansicht und Menü ; linke und rechte Daumensticks, Stoßfänger und Trigger; und insgesamt vier Vibrationsmotoren. Beide Ministicks liefern jeweils zwei analoge Werte für die X- und die Y-Achse und können auch gedrückt und somit als Taste verwendet werden. Jeder Trigger bietet einen analogen Wert, der angibt, wie weit er zurückgezogen wird.

Hinweis

Windows.Gaming.Input.Gamepad unterstützt auch Xbox 360-Gamepads, die das gleiche Steuerungslayout wie standardmäßige Xbox One-Gamepads haben.

Vibration und Impulse Triggers

Xbox One-Gamepads verfügen über zwei unabhängige Motoren für starke und dezente Gamepadvibrationen sowie über zwei dedizierte Motoren für kurze intensive Vibrationen an den einzelnen Triggern. (Aufgrund dieses einzigartigen Features werden die Trigger des Xbox One-Gamepads als Impulse Triggers bezeichnet.)

Hinweis

Xbox 360 Gamepads sind nicht mit Impulstriggern ausgestattet.

Weitere Informationen finden Sie in der Übersicht über Vibration und Impulse Triggers.

Inaktive Ministick-Bereiche

Ein Ministick, der sich in der Mittelstellung (und damit im Ruhezustand) befindet, liefert im Idealfall immer den gleichen neutralen Wert für die X- und die Y-Achse. Aufgrund von mechanischen Kräften und der Empfindlichkeit des Ministicks handelt es sich bei den tatsächlichen Werten in der Mittelposition jedoch lediglich um (ggf. schwankende) Näherungswerte für den idealen neutralen Wert. Aus diesem Grund müssen Sie immer eine kleine Deadzone verwenden – einen Bereich von Werten in der Nähe der idealen Mittelposition, die ignoriert werden –, um Fertigungsunterschiede, mechanischen Verschleiß oder andere Gamepadprobleme auszugleichen.

Durch größere inaktive Bereiche lassen sich ganz einfach beabsichtigte Eingaben von unbeabsichtigten Eingaben unterscheiden.

Weitere Informationen finden Sie unter Lesen der Ministicks.

Benutzeroberflächennavigation

Um den Aufwand für die Unterstützung unterschiedlicher Eingabegeräte für die Benutzeroberflächennavigation zu verringern und die Konsistenz zwischen Spielen und Geräten zu fördern, dienen die meisten physischen Eingabegeräte gleichzeitig als getrennte logische Eingabegeräte, die als Benutzeroberflächen-Navigationscontroller bezeichnet werden. Der Benutzeroberflächen-Navigationscontroller stellt ein gemeinsames Vokabular für Benutzeroberflächen-Navigationsbefehle über verschiedene Eingabegeräte hinweg bereit.

Als Benutzeroberflächennavigationscontroller ordnen Gamepads den erforderlichen Satz von Navigationsbefehlen den linken Fingerabdruck-, D-Pad-, Ansicht-, Menü-, A- und B-Schaltflächen zu.

Navigationsbefehl Gamepad-Eingabe
Nach oben Linker Ministick nach oben/Steuerkreuz nach oben
Nach unten Linker Ministick nach unten/Steuerkreuz nach unten
Left Linker Ministick nach links/Steuerkreuz nach links
Right Linker Ministick nach rechts/Steuerkreuz nach rechts
Sicht Ansicht-Taste
Menü Menü-Taste
Akzeptieren A-Taste
Abbrechen B-Taste

Darüber hinaus ordnen Gamepads den gesamten optionalen Satz der Navigationsbefehle den restlichen Eingaben zu.

Navigationsbefehl Gamepad-Eingabe
BILD-AUF Linker Trigger
BILD-AB Rechter Trigger
Seite nach links Linker Bumper
Seite nach rechts Rechter Bumper
Bildlauf nach oben Rechter Ministick nach oben
Bildlauf nach unten Rechter Ministick nach unten
Bildlauf nach links Rechter Ministick nach links
Bildlauf nach rechts Rechter Ministick nach rechts
Kontext 1 X-Taste
Kontext 2 Y-Taste
Kontext 3 Linken Ministick drücken
Kontext 4 Rechten Ministick drücken

Erkennen und Nachverfolgen von Gamepads

Gamepads werden vom System verwaltet. Daher müssen Sie diese nicht erstellen oder initialisieren. Das System stellt eine Liste mit verbundenen Gamepads sowie Ereignisse bereit, um Sie zu benachrichtigen, wenn ein Gamepad hinzugefügt oder entfernt wird.

Die Gamepadliste

Die Gamepad-Klasse stellt die statische Eigenschaft Gamepads bereit. Hierbei handelt es sich um eine schreibgeschützte Liste mit derzeit verbundenen Gamepads. Da Sie möglicherweise nur an einigen der verbundenen Gamepads interessiert sind, wird empfohlen, Ihre eigene Sammlung zu verwalten, anstatt über die Gamepads -Eigenschaft darauf zuzugreifen.

Im folgenden Beispiel werden alle verbundenen Gamepads in eine neue Sammlung kopiert. Beachten Sie, dass Sie eine Sperre um jeden Code platzieren müssen, der die Sammlung liest oder aktualisiert, da andere Threads im Hintergrund auf diese Sammlung zugreifen (in den Ereignissen GamepadAdded und GamepadRemoved ).

auto myGamepads = ref new Vector<Gamepad^>();
critical_section myLock{};

for (auto gamepad : Gamepad::Gamepads)
{
    // Check if the gamepad is already in myGamepads; if it isn't, add it.
    critical_section::scoped_lock lock{ myLock };
    auto it = std::find(begin(myGamepads), end(myGamepads), gamepad);

    if (it == end(myGamepads))
    {
        // This code assumes that you're interested in all gamepads.
        myGamepads->Append(gamepad);
    }
}
private readonly object myLock = new object();
private List<Gamepad> myGamepads = new List<Gamepad>();
private Gamepad mainGamepad;

private void GetGamepads()
{
    lock (myLock)
    {
        foreach (var gamepad in Gamepad.Gamepads)
        {
            // Check if the gamepad is already in myGamepads; if it isn't, add it.
            bool gamepadInList = myGamepads.Contains(gamepad);

            if (!gamepadInList)
            {
                // This code assumes that you're interested in all gamepads.
                myGamepads.Add(gamepad);
            }
        }
    }   
}

Hinzufügen und Entfernen von Gamepads

Wenn ein Gamepad hinzugefügt oder entfernt wird, werden die Ereignisse GamepadAdded und GamepadRemoved ausgelöst. Sie können Handler für diese Ereignisse registrieren, um die derzeit verbundenen Gamepads nachzuverfolgen.

Im folgenden Beispiel wird mit der Nachverfolgung eines hinzugefügten Gamepads begonnen.

Gamepad::GamepadAdded += ref new EventHandler<Gamepad^>(Platform::Object^, Gamepad^ args)
{
    // Check if the just-added gamepad is already in myGamepads; if it isn't, add
    // it.
    critical_section::scoped_lock lock{ myLock };
    auto it = std::find(begin(myGamepads), end(myGamepads), args);

    if (it == end(myGamepads))
    {
        // This code assumes that you're interested in all new gamepads.
        myGamepads->Append(args);
    }
}
Gamepad.GamepadAdded += (object sender, Gamepad e) =>
{
    // Check if the just-added gamepad is already in myGamepads; if it isn't, add
    // it.
    lock (myLock)
    {
        bool gamepadInList = myGamepads.Contains(e);

        if (!gamepadInList)
        {
            myGamepads.Add(e);
        }
    }
};

Im folgenden Beispiel wird die Nachverfolgung eines entfernten Gamepads beendet. Sie müssen auch die Vorgänge mit den Gamepads verarbeiten, die Sie nachverfolgen, wenn sie entfernt werden. Beispielsweise verfolgt dieser Code nur Eingaben von einem Gamepad nach und legt sie einfach auf nullptr fest, wenn sie entfernt wird. Sie müssen jeden Frame überprüfen, ob Ihr Gamepad aktiv ist, und aktualisieren, von welchem Gamepad Sie Eingaben sammeln, wenn Controller verbunden und getrennt sind.

Gamepad::GamepadRemoved += ref new EventHandler<Gamepad^>(Platform::Object^, Gamepad^ args)
{
    unsigned int indexRemoved;
    critical_section::scoped_lock lock{ myLock };

    if(myGamepads->IndexOf(args, &indexRemoved))
    {
        if (m_gamepad == myGamepads->GetAt(indexRemoved))
        {
            m_gamepad = nullptr;
        }

        myGamepads->RemoveAt(indexRemoved);
    }
}
Gamepad.GamepadRemoved += (object sender, Gamepad e) =>
{
    lock (myLock)
    {
        int indexRemoved = myGamepads.IndexOf(e);

        if (indexRemoved > -1)
        {
            if (mainGamepad == myGamepads[indexRemoved])
            {
                mainGamepad = null;
            }

            myGamepads.RemoveAt(indexRemoved);
        }
    }
};

Weitere Informationen finden Sie unter Eingabemethoden für Spiele .

Benutzer und Headsets

Jedes Gamepad kann mit einem Benutzerkonto verknüpft werden, um die Identität des Benutzers mit dem Spiel zu verknüpfen, und mit einem Headset verbunden werden, um Sprachchats oder Features im Spiel zu unterstützen. Weitere Informationen zu Benutzern und Headsets finden Sie unter Nachverfolgen von Benutzern und ihren Geräten und Headsets.

Lesen des Gamepads

Nachdem Sie das Gamepad identifiziert haben, für das Sie sich interessieren, können Sie Eingaben davon erfassen. Anders als im Fall anderer Eingaben, die Sie möglicherweise kennen, teilen Gamepads Zustandsänderungen jedoch nicht durch das Auslösen von Ereignissen mit. Stattdessen müssen Sie den aktuellen Status regelmäßig lesen, indem Sie ihn abrufen.

Abfragen des Gamepads

Beim Abruf wird eine Momentaufnahme des Navigationsgeräts an einem bestimmten Zeitpunkt erfasst. Dieser Ansatz zum Sammeln von Eingaben eignet sich gut für die meisten Spiele, da ihre Logik in der Regel in einer deterministischen Schleife ausgeführt wird, anstatt ereignisgesteuert zu sein. Es ist in der Regel auch einfacher, Spielbefehle aus Eingaben zu interpretieren, die auf einmal gesammelt wurden, als aus vielen einzelnen Eingaben, die im Laufe der Zeit gesammelt wurden.

Gamepads werden durch Aufrufen von GetCurrentReading abgefragt. Diese Funktion gibt einen GamepadReading-Wert mit dem Zustand des Gamepads zurück.

Im folgenden Beispiel wird der aktuelle Zustand eines Gamepads abgefragt.

auto gamepad = myGamepads[0];

GamepadReading reading = gamepad->GetCurrentReading();
Gamepad gamepad = myGamepads[0];

GamepadReading reading = gamepad.GetCurrentReading();

Zusätzlich zum Zustand des Gamepads enthält jeder Wert einen Zeitstempel, der den genauen Zeitpunkt angibt, zu dem der Zustand abgerufen wurde. Der Zeitstempel ist nützlich, um einen Bezug zu den Zeitpunkten vorheriger Ablesungen oder zum Zeitpunkt der Spielsimulation herzustellen.

Lesen der Ministicks

Jeder Ministick liefert einen analogen Wert zwischen -1,0 und +1,0 auf der X- und der Y-Achse. Auf der X-Achse entspricht der Wert -1,0 der äußerst linken Ministickposition und der Wert +1,0 der äußerst rechten Position. Auf der Y-Achse entspricht der Wert -1,0 der niedrigsten Ministickposition und der Wert +1,0 der höchsten Position. In beiden Achsen beträgt der Wert ungefähr 0,0, wenn sich der Stick in der Mitte befindet, aber es ist normal, dass der genaue Wert variiert, auch zwischen nachfolgenden Messwerten. Strategien zur Minderung dieser Variation werden weiter unten in diesem Abschnitt erläutert.

Der X-Achsenwert des linken Ministicks wird aus der LeftThumbstickX-Eigenschaft der GamepadReading-Struktur gelesen. Der Y-Achsenwert stammt aus der LeftThumbstickY-Eigenschaft. Der X-Achsenwert des rechten Ministicks wird aus der RightThumbstickX-Eigenschaft gelesen. Der Y-Achsenwert stammt aus der RightThumbstickY-Eigenschaft.

float leftStickX = reading.LeftThumbstickX;   // returns a value between -1.0 and +1.0
float leftStickY = reading.LeftThumbstickY;   // returns a value between -1.0 and +1.0
float rightStickX = reading.RightThumbstickX; // returns a value between -1.0 and +1.0
float rightStickY = reading.RightThumbstickY; // returns a value between -1.0 and +1.0
double leftStickX = reading.LeftThumbstickX;   // returns a value between -1.0 and +1.0
double leftStickY = reading.LeftThumbstickY;   // returns a value between -1.0 and +1.0
double rightStickX = reading.RightThumbstickX; // returns a value between -1.0 and +1.0
double rightStickY = reading.RightThumbstickY; // returns a value between -1.0 and +1.0

Sie werden feststellen, dass die gelesenen Ministickwerte nicht zuverlässig einen neutralen 0,0-Wert liefern, wenn sich der Ministick in der Mittelstellung (und damit im Ruhezustand) befindet. Stattdessen erhalten Sie verschiedene Näherungswerte für 0,0, wann immer der Ministicks bewegt wurde und wieder in die Mittelstellung zurückkehrt. Zur Kompensierung dieser Abweichungen können Sie einen kleinen inaktiven Bereich implementieren (also einen zu ignorierenden Wertebereich nahe der idealen Mittelposition). Zur Implementierung eines inaktiven Bereichs können Sie beispielsweise ermitteln, wie weit sich der Ministick von der Mittelposition entfernt hat, und dabei die Werte ignorieren, die eine bestimmte, von Ihnen gewählte Entfernung unterschreiten. Sie können die Entfernung ungefähr berechnen – dies ist nicht genau, da die Messdaten des Ziehpunkts im Wesentlichen polar und nicht planar sind –, indem Sie das Pythagore-Theorem verwenden. Dadurch entsteht ein radialer inaktiver Bereich.

Das folgende Beispiel veranschaulicht einen einfachen radialen inaktiven Bereich unter Verwendung des Satzes des Pythagoras.

float leftStickX = reading.LeftThumbstickX;   // returns a value between -1.0 and +1.0
float leftStickY = reading.LeftThumbstickY;   // returns a value between -1.0 and +1.0

// choose a deadzone -- readings inside this radius are ignored.
const float deadzoneRadius = 0.1;
const float deadzoneSquared = deadzoneRadius * deadzoneRadius;

// Pythagorean theorem -- for a right triangle, hypotenuse^2 = (opposite side)^2 + (adjacent side)^2
auto oppositeSquared = leftStickY * leftStickY;
auto adjacentSquared = leftStickX * leftStickX;

// accept and process input if true; otherwise, reject and ignore it.
if ((oppositeSquared + adjacentSquared) > deadzoneSquared)
{
    // input accepted, process it
}
double leftStickX = reading.LeftThumbstickX;   // returns a value between -1.0 and +1.0
double leftStickY = reading.LeftThumbstickY;   // returns a value between -1.0 and +1.0

// choose a deadzone -- readings inside this radius are ignored.
const double deadzoneRadius = 0.1;
const double deadzoneSquared = deadzoneRadius * deadzoneRadius;

// Pythagorean theorem -- for a right triangle, hypotenuse^2 = (opposite side)^2 + (adjacent side)^2
double oppositeSquared = leftStickY * leftStickY;
double adjacentSquared = leftStickX * leftStickX;

// accept and process input if true; otherwise, reject and ignore it.
if ((oppositeSquared + adjacentSquared) > deadzoneSquared)
{
    // input accepted, process it
}

Jeder Ministick kann auch gedrückt werden und somit als Taste fungieren. Weitere Informationen zum Lesen dieser Eingabe finden Sie unter Lesen der Tasten.

Lesen der Trigger

Die Trigger werden als Gleitkommawerte zwischen 0,0 (vollständig losgelassen) und 1,0 (vollständig gedrückt) dargestellt. Der Wert des linken Triggers wird aus der LeftTrigger-Eigenschaft der GamepadReading-Struktur gelesen. Der Wert des rechten Triggers stammt aus der RightTrigger-Eigenschaft.

float leftTrigger  = reading.LeftTrigger;  // returns a value between 0.0 and 1.0
float rightTrigger = reading.RightTrigger; // returns a value between 0.0 and 1.0
double leftTrigger = reading.LeftTrigger;  // returns a value between 0.0 and 1.0
double rightTrigger = reading.RightTrigger; // returns a value between 0.0 and 1.0

Lesen der Tastenwerte

Jede der Gamepad-Schaltflächen – die vier Richtungen des D-Pads, linke und rechte Stoßstangen, drücken den linken und rechten Fingerstick, A, B, X, Y, Ansicht und Menü – bietet eine digitale Leseanzeige, die angibt, ob sie gedrückt (nach unten) oder losgelassen (nach oben) ist. Aus Effizienzgründen werden Die Lesevorgänge von Schaltflächen nicht als einzelne boolesche Werte dargestellt. Stattdessen werden sie alle in ein einzelnes Bitfeld gepackt, das durch die GamepadButtons-Enumeration dargestellt wird.

Die Tastenwerte werden aus der Buttons-Eigenschaft der GamepadReading-Struktur gelesen. Da diese Eigenschaft ein Bitfeld ist, wird eine bitweise Maskierung verwendet, um den Wert der Taste zu isolieren, an der Sie interessiert sind, Die Schaltfläche wird gedrückt (nach unten), wenn das entsprechende Bit festgelegt ist. Andernfalls wird es freigegeben (up).

Im folgenden Beispiel wird ermittelt, ob die A-Taste gedrückt ist.

if (GamepadButtons::A == (reading.Buttons & GamepadButtons::A))
{
    // button A is pressed
}
if (GamepadButtons.A == (reading.Buttons & GamepadButtons.A))
{
    // button A is pressed
}

Im folgenden Beispiel wird ermittelt, ob die A-Taste losgelassen wurde.

if (GamepadButtons::None == (reading.Buttons & GamepadButtons::A))
{
    // button A is released
}
if (GamepadButtons.None == (reading.Buttons & GamepadButtons.A))
{
    // button A is released
}

Manchmal möchten Sie vielleicht bestimmen, wann eine Schaltfläche von gedrückt zu losgelassen oder gedrückt wird, ob mehrere Schaltflächen gedrückt oder losgelassen werden oder ob eine Reihe von Schaltflächen auf eine bestimmte Weise angeordnet ist – einige gedrückt, andere nicht. Informationen zum Ermitteln dieser Bedingungen finden Sie unter Erkennen von Tastenübergängen sowie unter Erkennen von komplexen Tastenanordnungen.

Ausführen des Gamepad-Eingabebeispiels

Im GamepadUWP-Beispiel (GitHub) wird veranschaulicht, wie Sie eine Verbindung mit einem Gamepad herstellen und dessen Zustand lesen.

Übersicht über Vibration und Impulse Triggers

Die Vibrationsmotoren in einem Gamepad erzeugen fühlbares Feedback für den Benutzer. Dies wird in Spielen verwendet, um die Immersion zu verbessern, Statusinformationen (wie etwa eine Beschädigung) zu vermitteln, auf wichtige, in der Nähe befindliche Objekte hinzuweisen oder für andere kreative Zwecke.

Xbox One-Gamepads sind mit insgesamt vier unabhängigen Vibrationsmotoren ausgestattet. Zwei sind große Motoren, die sich im Gamepad-Körper befinden; der linke Motor sorgt für raue Vibrationen mit hoher Amplitude, während der rechte Motor sanftere, subtilere Vibrationen liefert. Die anderen beiden Motoren sind klein, befinden sich in den Triggern und erzeugen kurze, intensive Vibrationen direkt an den Triggerfingern des Benutzers. Aufgrund dieses einzigartigen Features des Xbox One-Gamepads werden die Trigger dieses Gamepads als Impulse Triggers bezeichnet. Gemeinsam lässt sich mithilfe dieser Motoren eine Vielzahl von Tastempfindungen erzeugen.

Verwenden von Vibrationen und Impulsen

Gamepadvibrationen werden über die Vibration-Eigenschaft der Gamepad-Klasse gesteuert. Vibrationist ein instance der GamepadVibration-Struktur, die aus vier Gleitkommawerten besteht; jeder Wert stellt die Intensität eines der Motoren dar.

Obwohl die Member der Gamepad.Vibration Eigenschaft direkt geändert werden können, empfiehlt es sich, eine separate GamepadVibration instance zu den gewünschten Werten zu initialisieren und dann in die Gamepad.Vibration -Eigenschaft zu kopieren, um die tatsächlichen Motor-Intensitäten auf einmal zu ändern.

Im folgenden Beispiel wird das gleichzeitige Ändern aller Motorintensitäten veranschaulicht.

// get the first gamepad
Gamepad^ gamepad = Gamepad::Gamepads->GetAt(0);

// create an instance of GamepadVibration
GamepadVibration vibration;

// ... set vibration levels on vibration struct here

// copy the GamepadVibration struct to the gamepad
gamepad.Vibration = vibration;
// get the first gamepad
Gamepad gamepad = Gamepad.Gamepads[0];

// create an instance of GamepadVibration
GamepadVibration vibration = new GamepadVibration();

// ... set vibration levels on vibration struct here

// copy the GamepadVibration struct to the gamepad
gamepad.Vibration = vibration;

Verwenden der Vibrationsmotoren

Der linke und der rechte Vibrationsmotor akzeptieren Gleitkommawerte zwischen 0,0 (keine Vibration) und 1,0 (stärkste Vibration). Die Intensität des linken Motors wird durch die LeftMotor-Eigenschaft der GamepadVibration-Struktur festgelegt. Die Intensität des rechten Motors wird durch die RightMotor-Eigenschaft festgelegt.

Im folgenden Beispiel wird die Intensität beider Vibrationsmotoren festgelegt und die Gamepadvibration aktiviert.

GamepadVibration vibration;
vibration.LeftMotor = 0.80;  // sets the intensity of the left motor to 80%
vibration.RightMotor = 0.25; // sets the intensity of the right motor to 25%
gamepad.Vibration = vibration;
GamepadVibration vibration = new GamepadVibration();
vibration.LeftMotor = 0.80;  // sets the intensity of the left motor to 80%
vibration.RightMotor = 0.25; // sets the intensity of the right motor to 25%
mainGamepad.Vibration = vibration;

Vergessen Sie nicht, dass diese beiden Motoren nicht identisch sind. Wenn Sie die Eigenschaften also auf den gleichen Wert festlegen, werden in den beiden Motoren nicht die gleichen Vibrationen erzeugt. Für jeden Wert erzeugt der linke Motor eine stärkere Schwingung bei einer niedrigeren Frequenz als der rechte Motor, was – für den gleichen Wert – eine sanftere Vibration bei einer höheren Frequenz erzeugt. Selbst bei Verwendung des Maximalwerts erreicht der linke Motor nicht die hohen Frequenzen des rechten Motors, und mit dem rechten Motor lassen sich nicht die gleichen hohen Kräfte erzeugen wie mit dem linken Motor. Da die Motoren allerdings fest mit dem Gamepadgehäuse verbunden sind, nehmen Spieler die Vibrationen nicht vollständig unabhängig voneinander wahr, obwohl die Motoren unterschiedliche Eigenschaften haben und mit unterschiedlicher Intensität vibrieren können. Dadurch lässt sich eine größere, ausdrucksstärkere Bandbreite von Empfindungen vermitteln als mit zwei identischen Motoren.

Verwenden der Impulse Triggers

Jeder Impulse Trigger-Motor akzeptiert einen Gleitkommawert zwischen 0,0 (keine Vibration) und 1,0 (stärkste Vibration). Die Intensität des linken Triggermotors wird durch die LeftTrigger-Eigenschaft der GamepadVibration-Struktur festgelegt. Die Intensität des rechten Triggers wird durch die RightTrigger-Eigenschaft festgelegt.

Das folgende Beispiel legt die Intensität der beiden Impulse Triggers fest und aktiviert sie.

GamepadVibration vibration;
vibration.LeftTrigger = 0.75;  // sets the intensity of the left trigger to 75%
vibration.RightTrigger = 0.50; // sets the intensity of the right trigger to 50%
gamepad.Vibration = vibration;
GamepadVibration vibration = new GamepadVibration();
vibration.LeftTrigger = 0.75;  // sets the intensity of the left trigger to 75%
vibration.RightTrigger = 0.50; // sets the intensity of the right trigger to 50%
mainGamepad.Vibration = vibration;

Im Gegensatz zu den anderen Motoren sind die beiden Vibrationsmotoren innerhalb der Trigger identisch und erzeugen bei Verwendung des gleichen Werts jeweils die gleiche Vibration. Da diese Motoren jedoch nicht fest verbunden sind, nehmen die Spieler die Vibrationen unabhängig voneinander wahr. Dank dieses Designs können über beide Trigger gleichzeitig vollständig unabhängige Empfindungen erzeugt werden, um spezifischere Informationen zu vermitteln als mit den Motoren im Gamepadgehäuse möglich wäre.

Ausführen des Gamepad-Vibrationsbeispiels

Das GamepadVibrationUWP-Beispiel (GitHub) veranschaulicht, wie mithilfe der Gamepad-Vibrationsmotoren und der Impulse Triggers eine Reihe von Effekten erzeugt wird.

Siehe auch