Rennlenkräder und Kraftrückmeldung
Auf dieser Seite werden die Grundlagen der Programmierung für Xbox One-Renklenkräder mittels Windows.Gaming.Input.RacingWheel und verwandter APIs für die Universelle Windows-Plattform (UWP) beschrieben.
Auf dieser Seite erhalten Sie Informationen zu folgenden Vorgängen:
- Wie Sie eine Liste der verbundenen Rennlenkräder und ihrer Benutzer*innen erstellen
- Wie Sie feststellen, ob ein Rennlenkrad hinzugefügt oder entfernt wurde
- Wie Sie die Eingabe eines oder mehrerer Rennlenkräder lesen
- Wie Sie Kraftrückmeldungsbefehle senden
- Wie sich Rennlenkräder als Benutzeroberflächen-Navigationsgerät verhalten
Übersicht über Rennlenkräder
Rennlenkräder sind Eingabegeräte, die die Atmosphäre eines echten Rennwagen-Cockpits vermitteln. Rennlenkräder sind sowohl für Rennspiele im Arcade-Stil als auch für Rennspiele im Simulationsstil mit Autos oder Trucks das perfekte Eingabegerät. Rennlenkräder werden in Windows 10- oder Windows 11- und Xbox One-UWP-Apps durch den Namespace Windows.Gaming.Input unterstützt.
Rennlenkräder werden zu verschiedenen Preisen angeboten. In der Regel verfügen Rennlenkräder über mehr und bessere Eingabe- und Kraftrückmeldungsfunktionen, je teurer sie sind. Alle Rennlenkräder besitzen ein analoges Lenkrad, analoge Gas- und Bremsensteuerelemente sowie einige Lenkradtasten. Einige Rennlenkräder sind zusätzlich mit analogen Kupplungs- und Handbremsensteuerelementen, einer analogen Gangschaltung sowie Kraftrückmeldungsfunktionen ausgestattet. Nicht alle Rennlenkräder besitzen die gleichen Features. Darüber hinaus unterscheiden sie sich möglicherweise hinsichtlich der Unterstützung für bestimmte Features. Beispielsweise können Lenkräder unterschiedliche Drehbereiche unterstützen, und Gangschaltungen können eine unterschiedliche Zahl von Gängen unterstützen.
Gerätefunktionen
Die verschiedenen Rennlenkräder bieten unterschiedliche optionale Gerätefunktionen und einen unterschiedlichen Grad an Unterstützung dieser Funktionen. Dieser Grad an Abweichungen für ein einzelnes Eingabegerät ist unter den Geräten, die von den Windows.Gaming.Input-APIs unterstützt werden, einzigartig. Darüber hinaus unterstützen die meisten Geräte, die Sie antreffen, mindestens einige optionale Funktionen oder andere Variationen. Daher ist es wichtig, die Funktionen der verbundenen Rennlenkräder einzeln zu ermitteln und die gesamte Bandbreite der für Ihr Spiel sinnvollen Funktionen zu unterstützen.
Weitere Informationen finden Sie unter Ermitteln von Rennlenkradfunktionen.
Kraftrückmeldung
Einige Rennlenkräder stellen eine echte Kraftrückmeldung und nicht einfach nur Vibrationen bereit, d. h., sie können echte Kräfte auf eine Steuerungsachse wie das Lenkrad ausüben. Spiele verwenden diese Fähigkeit, um ein besseres Spielerlebnis zu vermitteln (simulierte Unfallschäden, „Gefühl für die Straße“) und die Anforderungen in Bezug auf gutes Fahren zu erhöhen.
Weitere Informationen finden Sie unter Übersicht zur Kraftrückmeldung.
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 Benutzeroberflächen-Navigationscontroller bietet ein allgemeines Vokabular für Benutzeroberflächen-Navigationsbefehle auf allen Eingabegeräten.
Aufgrund des spezifischen Schwerpunkts auf analogen Steuerungen und des Umfangs der Abweichungen zwischen den verschiedenen Rennlenkrädern verfügen diese in der Regel über ein Steuerkreuz, eine Ansicht, ein Menü und die Tasten A, B, X und Y, die den Tasten eines Gamepad ähnlich sind. Diese Tasten sind jedoch nicht für die Unterstützung von Befehlen im Spiel vorgesehen und können nicht direkt als Rennlenkradtasten verwendet werden.
Als Benutzeroberflächen-Navigationscontroller ordnen Rennlenkräder den erforderlichen Satz von Navigationsbefehlen dem linken Ministick, dem Steuerkreuz, der Ansicht, dem Menü sowie den Tasten A und B zu.
Navigationsbefehl | Rennlenkradeingabe |
---|---|
Up | Steuerkreuz nach oben |
Nach unten | Steuerkreuz nach unten |
Nach links | Steuerkreuz nach links |
Right | Steuerkreuz nach rechts |
Sicht | Ansicht-Taste |
Menü | Menü-Taste |
Annehmen | A-Taste |
Abbrechen | B-Taste |
Darüber hinaus können einige Rennlenkräder einige Befehle des optionalen Satzes von Navigationsbefehlen anderen unterstützten Eingaben zuordnen, aber Befehlszuordnungen können von Gerät zu Gerät variieren. Erwägen Sie auch die Unterstützung dieser Befehle, stellen Sie jedoch sicher, dass diese Befehle für die Navigation in der Benutzeroberfläche Ihres Spiels nicht unbedingt erforderlich sind.
Navigationsbefehl | Rennlenkradeingabe |
---|---|
Seite nach oben | variiert |
Seite nach unten | variiert |
Seite links | variiert |
Seite rechts | variiert |
Nach oben scrollen | variiert |
Nach unten scrollen | variiert |
Nach links scrollen | variiert |
Nach rechts scrollen | variiert |
Kontext 1 | X-Taste (in der Regel) |
Kontext 2 | Y-Taste (in der Regel) |
Kontext 3 | variiert |
Kontext 4 | variiert |
Erkennen und Nachverfolgen von Rennlenkrädern
Das Erkennen und Nachverfolgen von Rennlenkrädern funktioniert genauso wie bei Gamepads, mit Ausnahme der RacingWheel-Klasse anstelle der Gamepad-Klasse. Weitere Informationen finden Sie unter Gamepad und Vibration.
Lesen des Rennlenkrads
Nachdem Sie die Rennlenkräder identifiziert haben, für die Sie sich interessieren, können Sie Eingaben von ihnen erfassen. Anders als im Fall anderer Eingaben, die Sie möglicherweise kennen, teilen Rennlenkräder Zustandsänderungen jedoch nicht durch das Auslösen von Ereignissen mit. Stattdessen müssen Sie ihre aktuellen Status regelmäßig lesen, indem Sie sie abrufen.
Abrufen des Rennlenkrads
Beim Abrufen wird ein Snapshot des Rennlenkrads zu einem bestimmten Zeitpunkt erstellt. 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 ein Rennlenkrad durch Aufruf von GetCurrentReading ab. Diese Funktion gibt einen RacingWheelReading-Wert zurück, der den Zustand des Rennlenkrads enthält.
Im folgenden Beispiel wird der aktuelle Zustand eines Rennlenkrads abgefragt.
auto racingwheel = myRacingWheels[0];
RacingWheelReading reading = racingwheel->GetCurrentReading();
Zusätzlich zum Status des Rennlenkrads enthält jede Ablesung einen Zeitstempel, der den genauen Zeitpunkt angibt, zu dem der Zustand abgerufen wurde. Der Zeitstempel ist nützlich, um sich auf das Timing früherer Messwerte oder das Timing der Spielsimulation zu beziehen.
Ermitteln von Rennlenkradfunktionen
Viele der Steuerelemente der Rennlenkräder sind optional oder unterstützen unterschiedliche Variationen, sogar die erforderlichen Steuerelemente, sodass Sie die Funktionen jedes Rennlenkrads individuell bestimmen müssen, bevor Sie die Eingaben verarbeiten können, die in den Lesevorgängen des Rennlenkrads gesammelt werden.
Die optionalen Steuerelemente sind Handbremse, Kupplung und Gangschaltung; Sie können ermitteln, ob ein verbundenes Rennlenkrad diese Steuerelemente unterstützt, indem Sie die Eigenschaften HasHandbrake, HasClutch und HasPatternShifter des Rennlenkrads lesen. Das Steuerelement wird unterstützt, wenn der Wert der Eigenschaft true ist, andernfalls nicht.
if (racingwheel->HasHandbrake)
{
// the handbrake is supported
}
if (racingwheel->HasClutch)
{
// the clutch is supported
}
if (racingwheel->HasPatternShifter)
{
// the pattern shifter is supported
}
Darüber hinaus sind die Steuerelemente, die variieren können, das Lenkrad und die Gangschaltung. Das Lenkrad kann je nach Grad der physischen Drehung variieren, die das eigentliche Rad unterstützen kann, während die Gangschaltung nach der Anzahl unterschiedlicher Vorwärtsgänge variieren kann, die es unterstützt. Sie können den größten Drehwinkel bestimmen, den das eigentliche Rad unterstützt, indem Sie die Eigenschaft MaxWheelAngle
des Rennlenkrads lesen. Sein Wert ist der maximal unterstützte physische Winkel im Uhrzeigersinn in Grad (positiv), der ebenfalls gegen den Uhrzeigersinn (in negativer Gradzahl) unterstützt wird. Sie können den höchsten durch die Gangschaltung unterstützten Vorwärtsgang ermitteln, indem Sie die Eigenschaft MaxPatternShifterGear
des Rennlenkrads lesen. Dessen Wert entspricht dem höchsten unterstützten Vorwärtsgang (einschließlich): Wenn der Wert 4 ist, unterstützt die Gangschaltung einen Rückwärtsgang, einen Leerlaufgang sowie einen ersten, zweiten, dritten und vierten Gang.
auto maxWheelDegrees = racingwheel->MaxWheelAngle;
auto maxShifterGears = racingwheel->MaxPatternShifterGear;
Schließlich unterstützen einige Rennlenkräder Kraftrückmeldung durch das Lenkrad. Sie können ermitteln, ob ein verbundenes Rennlenkrad Kraftrückmeldung unterstützt, indem Sie die WheelMotor-Eigenschaft des Rennlenkrads lesen. Die Kraftrückmeldung wird unterstützt, wenn WheelMotor
nicht NULL ist. Andernfalls wird sie nicht unterstützt.
if (racingwheel->WheelMotor != nullptr)
{
// force feedback is supported
}
Informationen zur Verwendung der Kraftrückmeldungsfunktion von Rennlenkrädern, die sie unterstützen, finden Sie unter Übersicht zur Kraftrückmeldung.
Lesen der Tasten
Jede Rennlenkradtaste – die vier Richtungen des Steuerkreuzes, die Tasten Vorheriger Gang und Nächster Gang und 16 zusätzliche Tasten – stellt einen digitalen Ablesewert bereit, der angibt, ob sie gedrückt (unten) oder freigegeben (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 RacingWheelButtons dargestellt wird.
Hinweis
Rennlenkräder besitzen zusätzliche Tasten für die Benutzeroberflächennavigation, beispielsweise die Ansicht- und Menü-Taste. Diese Tasten sind nicht in der Enumeration RacingWheelButtons
enthalten und können nur gelesen werden, wenn auf das Rennlenkrad als Benutzeroberflächen-Navigationsgerät zugegriffen wird. Weitere Informationen finden Sie unter Benutzeroberflächen-Navigationsgerät.
Die Tastenwerte werden aus der Buttons
-Eigenschaft der RacingWheelReading-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 Taste ist gedrückt (unten), wenn das entsprechende Bit festgelegt ist. Andernfalls ist sie nicht gedrückt (oben).
Im folgenden Beispiel wird ermittelt, ob die Taste Nächster Gang gedrückt ist.
if (RacingWheelButtons::NextGear == (reading.Buttons & RacingWheelButtons::NextGear))
{
// Next Gear is pressed
}
Im folgenden Beispiel wird ermittelt, ob die Taste „Nächster Gang“ freigegeben ist.
if (RacingWheelButtons::None == (reading.Buttons & RacingWheelButtons::NextGear))
{
// Next Gear is released (not pressed)
}
In einigen Fällen möchten Sie möglicherweise ermitteln, ob eine Taste von „Gedrückt“ zu „Freigegeben“ oder von „Freigegeben“ zu „Gedrückt“ wechselt, ob mehrere Tasten gedrückt oder freigegeben werden, oder ob verschiedene Tasten in einer bestimmten Weise angeordnet sind – einige sind gedrückt, andere nicht. Informationen zum Erkennen dieser Bedingungen finden Sie unter Erkennen von Tastenübergängen und Erkennen komplexer Tastenanordnungen.
Lesen des Rads
Das Lenkrad ist ein erforderliches Steuerelement, das einen analogen Lesewert zwischen -1,0 und +1,0 bereitstellt. Der Wert -1,0 entspricht der äußersten linken Lenkradposition. Der Wert +1,0 entspricht der äußersten rechten Lenkradposition. Der Wert des Lenkrads wird aus der Wheel
-Eigenschaft der RacingWheelReading-Struktur gelesen.
float wheel = reading.Wheel; // returns a value between -1.0 and +1.0.
Obwohl Lenkradlesewerte unterschiedlichen Graden der physischen Drehung im tatsächlichen Rad entsprechen, je nach dem vom physischen Rennlenkrad unterstützten Drehbereich, möchten Sie die Lenkradlesewerte in der Regel nicht skalieren; Räder, die mehr Drehgrade unterstützen, bieten nur eine höhere Präzision.
Lesen von Gas und Bremse
Die Gas- und Bremsensteuerelemente sind erforderliche Steuerelemente, die jeweils analoge Ablesewerte zwischen 0,0 (vollständig freigegeben) und 1,0 (vollständig gedrückt) bereitstellen, dargestellt als Gleitkommawerte. Der Wert des Gassteuerelements wird aus der Throttle
-Eigenschaft der RacingWheelReading-Struktur gelesen. Der Wert des Bremssteuerelements wird aus der Brake
-Eigenschaft gelesen.
float throttle = reading.Throttle; // returns a value between 0.0 and 1.0
float brake = reading.Brake; // returns a value between 0.0 and 1.0
Lesen von Handbremse und Kupplung
Handbremse und Kupplung sind optionale Steuerelemente, die jeweils analoge Ablesewerte zwischen 0,0 (vollständig freigegeben) und 1,0 (vollständig gedrückt) bereitstellen, dargestellt als Gleitkommawerte. Der Wert des Handbremsensteuerelements wird aus der Handbrake
-Eigenschaft der RacingWheelReading-Struktur gelesen. Der Wert des Kupplungssteuerelements wird aus der Clutch
-Eigenschaft gelesen.
float handbrake = 0.0;
float clutch = 0.0;
if(racingwheel->HasHandbrake)
{
handbrake = reading.Handbrake; // returns a value between 0.0 and 1.0
}
if(racingwheel->HasClutch)
{
clutch = reading.Clutch; // returns a value between 0.0 and 1.0
}
Lesen der Gangschaltung
Die Gangschaltung ist ein optionales Steuerelement, das einen digitalen Ablesewert zwischen -1 und MaxPatternShifterGear bereitstellt, der als signierter ganzzahliger Wert dargestellt wird. Der Wert -1 bzw. 0 entspricht dem Rückwärtsgang bzw. dem Leerlaufgang. Aufsteigende positive Werte entsprechen den jeweiligen höheren Vorwärtsgängen bis einschließlich MaxPatternShifterGear. Der Wert der Gangschaltung wird aus der PatternShifterGear-Eigenschaft der RacingWheelReading-Struktur gelesen.
if (racingwheel->HasPatternShifter)
{
gear = reading.PatternShifterGear;
}
Hinweis
Wenn unterstützt, ist die Gangschaltung zusätzlich zu den erforderlichen Tasten für Vorheriger Gang und Nächster Gang vorhanden, die sich ebenfalls auf den aktuellen Gang des Autos des Spielers auswirken. Wenn beides vorhanden ist, besteht eine einfache Strategie für die Zusammenführung dieser Eingaben im Ignorieren von Gangschaltung (und Kupplung), wenn sich ein Spieler für ein Automatikgetriebe entscheidet, und im Ignorieren der Tasten Vorheriger Gang und Nächster Gang, wenn sich ein Spieler für ein manuelles Getriebe entscheidet (nur möglich, wenn das Rennlenkrad über ein Gangschaltungs-Steuerelement verfügt). Sie können eine andere Vereinheitlichungsstrategie implementieren, wenn dies nicht für Ihr Spiel geeignet ist.
Ausführen des InputInterfacing-Beispiels
Die InputInterfacingUWP-Beispiel-App auf GitHub veranschaulicht, wie Rennlenkräder und verschiedene Arten von Eingabegeräten zusammen verwendet werden, und wie sich diese Eingabegeräte als Benutzeroberflächen-Navigationscontroller verhalten.
Übersicht zur Kraftrückmeldung
Viele Rennlenkräder besitzen eine Kraftrückmeldungsfunktion, um ein umfassenderes und stärker herausforderndes Fahrerlebnis zu ermöglichen. Rennlenkräder, die Kraftrückmeldung unterstützen, sind in der Regel mit einem einzelnen Motor ausgestattet, der entlang einer einzelnen Achse, der Achse der Raddrehung, Kraft auf das Lenkrad ausübt. Die Kraftrückmeldung wird in Windows 10- oder Windows 11- und Xbox One-UWP-Apps durch den Namespace Windows.Gaming.Input.ForceFeedback unterstützt.
Hinweis
Die Kraftrückmeldungs-APIs können mehrere Krafteinwirkungsachsen unterstützen. Rennlenkräder unterstützen zurzeit jedoch nur die Lenkraddrehungsachse als Kraftrückmeldungsachse.
Verwenden der Kraftrückmeldung
In diesen Abschnitten werden die Grundlagen der Programmierung von Kraftrückmeldungseffekten für Rennlenkräder beschrieben. Rückmeldung wird mithilfe von Effekten ausgeübt, die zuerst auf das Kraftrückmeldungsgerät geladen werden und dann auf eine ähnliche Weise wie Soundeffekte gestartet, angehalten, fortgesetzt und beendet werden können; Sie müssen jedoch zuerst die Rückmeldungsfunktionen des Rennlenkrads ermitteln.
Ermitteln von Kraftrückmeldungsfunktionen
Sie können ermitteln, ob ein verbundenes Rennlenkrad Kraftrückmeldung unterstützt, indem Sie die WheelMotor-Eigenschaft des Rennlenkrads lesen. Die Kraftrückmeldung wird nicht unterstützt, wenn WheelMotor
den Wert NULL hat. Andernfalls wird die Kraftrückmeldung unterstützt, und Sie können mit der Ermittlung der spezifischen Kraftrückmeldungsfunktionalität des Motors fortfahren, beispielsweise der Achsen, auf die Kraft ausgeübt werden kann.
if (racingwheel->WheelMotor != nullptr)
{
auto axes = racingwheel->WheelMotor->SupportedAxes;
if(ForceFeedbackEffectAxes::X == (axes & ForceFeedbackEffectAxes::X))
{
// Force can be applied through the X axis
}
if(ForceFeedbackEffectAxes::Y == (axes & ForceFeedbackEffectAxes::Y))
{
// Force can be applied through the Y axis
}
if(ForceFeedbackEffectAxes::Z == (axes & ForceFeedbackEffectAxes::Z))
{
// Force can be applied through the Z axis
}
}
Laden von Kraftrückmeldungseffekten
Kraftrückmeldungseffekte werden auf das Rückmeldungsgerät geladen, wo sie autonom auf Befehl Ihres Spiels „abgespielt“ werden. Es wird eine Reihe von Basiseffekten bereitgestellt. Benutzerdefinierte Effekte können über eine Klasse erstellt werden, die die IForceFeedbackEffect-Schnittstelle implementiert.
Effektklasse | Effektbeschreibung |
---|---|
ConditionForceEffect | Ein Effekt, der als Reaktion auf den aktuellen Sensor innerhalb des Geräts variable Kraft ausübt. |
ConstantForceEffect | Ein Effekt, der konstante Kraft entlang eines Vektors ausübt. |
PeriodicForceEffect | Ein Effekt, der eine durch eine Wellenform definierte variable Kraft entlang eines Vektors ausübt. |
RampForceEffect | Ein Effekt, der eine linear steigende/abnehmende Kraft entlang eines Vektors ausübt. |
using FFLoadEffectResult = ForceFeedback::ForceFeedbackLoadEffectResult;
auto effect = ref new Windows.Gaming::Input::ForceFeedback::ConstantForceEffect();
auto time = TimeSpan(10000);
effect->SetParameters(Windows::Foundation::Numerics::float3(1.0f, 0.0f, 0.0f), time);
// Here, we assume 'racingwheel' is valid and supports force feedback
IAsyncOperation<FFLoadEffectResult>^ request
= racingwheel->WheelMotor->LoadEffectAsync(effect);
auto loadEffectTask = Concurrency::create_task(request);
loadEffectTask.then([this](FFLoadEffectResult result)
{
if (FFLoadEffectResult::Succeeded == result)
{
// effect successfully loaded
}
else
{
// effect failed to load
}
}).wait();
Verwenden von Kraftrückmeldungseffekten
Nach dem Laden können alle Effekte synchron gestartet, angehalten, fortgesetzt und beendet werden, indem Funktionen für die WheelMotor
-Eigenschaft des Rennlenkrads oder einzeln durch Aufrufen von Funktionen für den Rückmeldungseffekt selbst aufgerufen werden. In der Regel sollten Sie alle Effekte, die Sie auf dem Rückmeldungsgerät verwenden möchten, vor Spielbeginn laden, und dann die jeweiligen SetParameters
-Funktionen verwenden, um die Effekte im Verlauf des Spiels zu aktualisieren.
if (ForceFeedbackEffectState::Running == effect->State)
{
effect->Stop();
}
else
{
effect->Start();
}
Schließlich können Sie bei Bedarf das gesamte Kraftrückmeldungssystem auf einem bestimmten Rennlenkrad asynchron aktivieren, deaktivieren oder zurücksetzen.