Freigeben über


Gamepad und Vibration

Auf dieser Seite werden die Grundlagen der Programmierung für Gamepads mit [Windows.Gaming.Input.Gamepad][Gamepad] und verwandten APIs für die universelle Windows-Plattform (UWP) beschrieben.

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

  • So sammeln Sie eine Liste der verbundenen Gamepads und von deren Benutzern
  • So erkennen Sie, dass ein Gamepad hinzugefügt oder entfernt wurde
  • So lesen Sie Eingaben aus einem oder mehreren Gamepads
  • So senden Sie Vibrations- und Impulsbefehle
  • So verhalten sich Gamepads als Benutzeroberflächen-Navigationsgeräte

Übersicht zu Gamepads

Gamepads wie der Xbox Wireless Controller und der Xbox Wireless Controller S sind allgemeine Spieleingabegeräte. Sie sind das Standardeingabegerät auf Xbox One und eine häufige Wahl für Windows-Spieler, wenn sie keine Tastatur und Maus bevorzugen. Gamepads werden in Windows 10- oder Windows 11- und Xbox-UWP-Apps über den Windows.Gaming.Input-Namespace unterstützt.

Xbox One-Gamepads verfügen über ein Steuerkreuz (auch Steuerkreuz genannt), über die Tasten A, B, X, Y, Ansicht und Menü, über einen linken und einen rechten Ministick, Bumper und Trigger sowie über insgesamt vier Vibrationsmotoren. Beide Ministicks bieten doppelte analoge Lesewerte in den X- und Y-Achsen und dienen auch als Taste, wenn sie nach innen gedrückt werden. Jeder Trigger stellt einen analogen Lesewert bereit, der angibt, wie weit er zurückgezogen wird.

Hinweis

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

Vibrations- und Impulstrigger

Xbox One-Gamepads bieten zwei unabhängige Motoren für starke und subtile Gamepadvibrationen sowie zwei dedizierte Motoren für die Bereitstellung von scharfen Vibrationen für jeden Trigger (dieses einzigartige Feature ist der Grund, warum Xbox One-Gamepadtrigger als Impulstrigger bezeichnet werden).

Hinweis

Xbox 360-Gamepads sind nicht mit Impulstriggern ausgestattet.

Weitere Informationen finden Sie unter Übersicht über Vibrations- und Impulstrigger.

Inaktive Ministick-Zonen

Ein ruhender Ministick in der Mittelposition würde idealerweise jedes Mal den gleichen, neutralen Lesewert in den X- und Y-Achsen erzeugen. Aufgrund mechanischer Kräfte und der Empfindlichkeit des Ministicks sind die tatsächlichen Werte in der Mittelposition jedoch nur dem idealen neutralen Wert anzunähern und können zwischen nachfolgenden Auslesungen variieren. Aus diesem Grund müssen Sie stets einen kleinen inaktiven Bereich (also einen Bereich von zu ignorierenden Werten in der Nähe der idealen Mittelposition) verwenden, um herstellungsbedingte Abweichungen, mechanische Abnutzung und andere Gamepadeffekte zu kompensieren.

Größere inaktive Zonen bieten eine einfache Strategie zum Trennen beabsichtigter Eingaben von unbeabsichtigten Eingaben.

Weitere Informationen finden Sie unter Auslesen der Ministicks.

Navigation in der Benutzeroberfläche

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 Navigationscontroller für die Benutzeroberflächen bietet ein gängiges Vokabular für Benutzeroberflächen-Navigationsbefehle auf allen Eingabegeräten.

Als Benutzeroberflächen-Navigationscontroller ordnen Gamepads den erforderlichen Satz von Navigationsbefehlen dem linken Ministick und dem Steuerkreuz sowie den Tasten Ansicht, Menü, A und B zu.

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

Darüber hinaus ordnen Gamepads alle optionalen Navigationsbefehle den verbleibenden Eingaben zu.

Navigationsbefehl Gamepad-Eingabe
Seite nach oben Linker Trigger
Seite nach unten Rechter Trigger
Seite links Linker Bumper
Seite rechts Rechter Bumper
Nach oben scrollen Rechter Ministick nach oben
Nach unten scrollen Rechter Ministick nach unten
Nach links scrollen Rechter Ministick nach links
Nach rechts scrollen 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 sie nicht erstellen oder initialisieren. Das System stellt eine Liste der verbundenen Gamepads und Ereignisse bereit, um Sie zu benachrichtigen, wenn ein Gamepad hinzugefügt oder entfernt wird.

Die Liste der Gamepads

Die Gamepad-Klasse bietet eine statische Eigenschaft, Gamepads, die eine schreibgeschützte Liste von Gamepads ist, die derzeit verbunden sind. Da Sie möglicherweise nur an einigen der verbundenen Gamepads interessiert sind, empfiehlt es sich, 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, da andere Threads im Hintergrund auf diese Sammlung zugreifen (in den GamepadAdded- und GamepadRemoved-Ereignissen), eine Sperre um jeglichen Code platzieren müssen, der die Sammlung liest oder aktualisiert.

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, wird das Ereignis GamepadAdded bzw. GamepadRemoved ausgelöst. Sie können Handler für diese Ereignisse registrieren, um die derzeit verbundenen Gamepads nachzuverfolgen.

Im folgenden Beispiel wird das Nachverfolgen eines Gamepads gestartet, das hinzugefügt wurde.

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 das Nachverfolgen eines Gamepads beendet, das entfernt wurde. Sie müssen auch handhaben, was mit den Gamepads passiert, die Sie nachverfolgen, wenn sie entfernt werden. Dieser Code verfolgt beispielsweise nur Eingaben von einem einzigen Gamepad und setzt es auf nullptr, wenn es entfernt wird. Sie müssen jeden Frame überprüfen, ob Ihr Gamepad aktiv ist, und aktualisieren, von welchem Gamepad Sie Eingaben sammeln, wenn Controller angeschlossen und getrennt werden.

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 einem Benutzerkonto zugeordnet werden, um seine Identität mit dessen Spielaktivität zu verknüpfen, und ein Headset kann verbunden werden, um Sprachchats oder In-Game-Features zu ermöglichen. Weitere Informationen zum Arbeiten mit Benutzern und Headsets finden Sie unter Nachverfolgen von Benutzern und ihren Geräten und Headset.

Auslesen des Gamepads

Nachdem Sie das Gamepad identifiziert haben, an dem Sie interessiert sind, können Sie Eingaben davon sammeln. 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 auslesen, indem Sie ihn abrufen.

Abrufen vom Gamepad

Durch das Abrufen wird eine Momentaufnahme des Navigationsgeräts zu einem genauen Zeitpunkt erfasst. Dieser Ansatz zum Erfassen von Eingaben ist für die meisten Spiele geeignet, da deren Logik in der Regel in einer deterministischen Schleife ausgeführt wird und nicht ereignisgesteuert ist. Es ist in der Regel auch einfacher, Befehle in Spielen anhand von Eingaben zu interpretieren, die zusammen erfasst werden, als anhand zahlreicher Eingaben, die über die Zeit erfasst werden.

Sie rufen den Status eines Gamepads ab, indem Sie GetCurrentReading aufrufen. Diese Funktion gibt ein GamepadReading zurück, das den Zustand des Gamepads enthält.

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 sich auf die Anzeigedauer früherer Messwerte oder auf die Anzeigedauer der Spielsimulation zu beziehen.

Auslesen der Ministicks

Jeder Ministick stellt einen analogen Lesewert zwischen -1,0 und +1,0 in den X- und Y-Achsen bereit. Auf der X-Achse entspricht ein Wert von -1,0 der am weitesten links befindlichen Ministickposition; ein Wert von +1,0 entspricht der am weitesten rechts befindlichen Position. Auf der Y-Achse entspricht der Wert -1,0 der niedrigsten Ministickposition und der Wert +1,0 der höchsten Position. Bei beiden Achsen beträgt der Wert etwa 0,0, wenn sich der Stick in der Mittelposition befindet, aber es ist normal, dass der genaue Wert variieren kann, auch zwischen aufeinander folgenden Lesewerten; Strategien zur Abmilderung dieser Variation werden weiter unten in diesem Abschnitt erläutert.

Der Wert der X-Achse des linken Ministicks wird aus der LeftThumbstickX-Eigenschaft der GamepadReading-Struktur ausgelesen. Der Wert der Y-Achse wird aus der LeftThumbstickY-Eigenschaft ausgelesen. Der Wert der X-Achse des rechten Ministicks wird aus der RightThumbstickX-Eigenschaft ausgelesen. Der Wert der Y-Achse wird aus der RightThumbstickY-Eigenschaft ausgelesen.

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 ausgelesenen 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 Abmilderung dieser Variationen können Sie einen kleinen inaktiven Bereich implementieren, bei dem es sich um einen Wertebereich in der Nähe der idealen Mittelposition handelt, der ignoriert wird. 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. Die grobe Entfernung kann mit dem Satz des Pythagoras berechnet werden. (Die Berechnung ist nicht exakt, da die Ministickwerte im Grunde polarer und nicht planarer Natur sind.) Dies erzeugt einen radialen inaktiven 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 fungiert auch als Taste, wenn er nach innen gedrückt wird; Weitere Informationen zum Auslesen dieser Eingabe finden Sie unter Auslesen der Tasten.

Auslesen 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 wird aus der RightTrigger-Eigenschaft gelesen.

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

Auslesen der Tasten

Jede der Gamepadtasten – die vier Richtungen des Steuerkreuzes, der linke und rechte Bumper, der linke und rechte (gedrückte) Ministick sowie die Tasten A, B, X, Y, Ansicht und Menü – liefert einen digitalen Wert, der angibt, ob die Taste gedrückt (unten) oder nicht gedrückt (oben) ist. Aus Effizienzgründen werden die Werte der Tasten nicht als einzelne boolesche Werte dargestellt, sondern in einem einzelnen Bitfeld zusammengefasst, das durch die Enumeration GamepadButtons dargestellt wird.

Die Schaltflächenwerte werden aus der Buttons-Eigenschaft der GamepadReading-Struktur ausgelesen. Da diese Eigenschaft ein Bitfeld ist, wird die bitweise Maskierung verwendet, um den Wert der Schaltfläche zu isolieren, an der Sie interessiert sind. Die Taste wird gedrückt (nach unten), wenn das entsprechende Bit festgelegt ist; andernfalls wird sie freigegeben (nach oben).

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 Taste von gedrückter Taste in losgelassen übergeht oder losgelassen wird, ob mehrere Tasten gedrückt oder losgelassen werden, oder ob eine Reihe von Tasten auf eine bestimmte Weise angeordnet sind, einige gedrückt und andere nicht. Informationen zum Erkennen jeder dieser Bedingungen finden Sie unter Erkennen von Schaltflächenübergängen und Erkennen komplexer Tastenanordnungen.

Ausführen des Gamepadeingabebeispiels

Das GamepadUWP-Beispiel (Github) veranschaulicht, wie eine Verbindung mit einem Gamepad hergestellt und der Zustand ausgelesen wird.

Übersicht zu Vibrations- und Impulstriggern

Die Vibrationsmotoren innerhalb eines Gamepads bieten dem Benutzer taktiles Feedback. Spiele verwenden diese Fähigkeit, ein größeres Gefühl der Immersion zu schaffen, um Statusinformationen (z. B. erlittenen Schaden), die Nähe zu wichtigen Objekten oder für andere kreative Zwecke zu signalisieren.

Xbox One-Gamepads sind mit insgesamt vier unabhängigen Vibrationsmotoren ausgestattet. Zwei dieser Motoren sind groß und befinden sich im Gehäuse des Gamepads. Der linke Motor erzeugt starke, intensive Vibrationen, während der rechte Motor für sanftere, dezentere Vibrationen zuständig ist. Die anderen beiden sind kleine Motoren, einer innerhalb jedes Triggers, die scharfe Vibrationen direkt an den Triggerfingern des Benutzers liefern; Diese einzigartige Fähigkeit des Xbox One-Gamepads ist der Grund, warum seine Trigger als Impulstrigger bezeichnet werden. Durch die gemeinsame Orchestrierung dieser Motoren lässt sich ein breites Spektrum an taktilen Empfindungen erzeugen.

Verwenden von Vibrationen und Impulsen

Gamepad-Vibrationen werden über die Vibration-Eigenschaft der Gamepad-Klasse gesteuert. Vibration ist eine Instanz der GamepadVibration-Struktur, die sich aus vier Gleitkommawerten zusammensetzt, welche jeweils für die Intensität eines der Motoren stehen.

Obwohl die Mitglieder der Gamepad.Vibration-Eigenschaft direkt geändert werden können, empfiehlt es sich, eine separate GamepadVibration-Instanz für die gewünschten Werte zu initialisieren und dann in die Gamepad.Vibration-Eigenschaft zu kopieren, um die tatsächlichen Motorintensitäten alle auf einmal zu ändern.

Im folgenden Beispiel wird veranschaulicht, wie die Motorintensitäten alle gleichzeitig geändert werden.

// 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

Die linken und rechten Vibrationsmotoren nehmen Gleitkommawerte zwischen 0,0 (keine Vibration) und 1,0 (intensivste Vibration) an. 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;

Denken Sie daran, dass diese beiden Motoren nicht identisch sind, sodass das Festlegen dieser Eigenschaften auf denselben Wert nicht dieselbe Vibration in einem Motor wie im anderen erzeugt. Der linke Motor erzeugt eine stärkere Vibration mit einer niedrigeren Frequenz, während der rechte Motor für den gleichen Wert eine sanftere Vibration mit höherer Frequenz erzeugt. Selbst beim Höchstwert kann der linke Motor nicht die hohen Frequenzen des rechten Motors erzeugen, und der rechte Motor kann nicht die hohen Kräfte des linken Motors erzeugen. Da die Motoren jedoch durch den Gamepadkörper starr miteinander verbunden sind, erleben die Spieler die Vibrationen nicht vollständig unabhängig, obwohl die Motoren unterschiedliche Eigenschaften haben und mit unterschiedlichen Intensitäten vibrieren können. Diese Anordnung ermöglicht es, ein breiteres, ausdrucksvolleres Spektrum von Empfindungen zu erzeugen, als wenn die Motoren identisch waren.

Verwenden der Impulstrigger

Jeder Impulstriggermotor nimmt einen Gleitkommawert zwischen 0,0 (keine Vibration) und 1,0 (intensivste Vibration) an. 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.

Im folgenden Beispiel wird die Intensität beider Impulstrigger festgelegt und sie werden aktiviert.

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 sind die beiden Vibrationsmotoren innerhalb der Trigger identisch, sodass sie dieselbe Vibration in beiden Motoren für denselben Wert erzeugen. Da diese Motoren jedoch nicht starr miteinander verbunden sind, erleben die Spieler die Vibrationen unabhängig voneinander. Diese Anordnung ermöglicht es, vollständig unabhängige Empfindungen gleichzeitig an beide Trigger zu richten und hilft ihnen, spezifischere Informationen zu vermitteln, als die Motoren im Gamepadkörper können.

Ausführen des Gamepad-Vibrationsbeispiels

Das GamepadVibrationUWP-Beispiel (Github) veranschaulicht, wie die Gamepad-Vibrationsmotoren und Impulstrigger verwendet werden, um eine Vielzahl von Effekten zu erzeugen.

Siehe auch