Zum Hauptinhalt springen
Version: neueste

Grundlegendes Force-Feedback-Tutorial

Physikalische Objekte haben zwei Eigenschaften, die bestimmen, wie sie sich anfühlen: Steifigkeit und Dämpfung. Dieser Lehrgang führt in die haptische Simulation ein, die sowohl die Steifigkeit als auch die Dämpfung berücksichtigt, die durch den Kontakt mit einer horizontalen Ebene. Sobald die Simulation abgeschlossen ist, haben Sie die Möglichkeit, einen "Boden" zu fühlen und seine Steifigkeits- und Dämpfungseigenschaften einzustellen.

Einführung

Die größte Herausforderung dieses Tutorials besteht darin, eine Funktion zu entwickeln, die die Kräfte berechnet, die aus dem Kontakt die aus dem Kontakt mit einer Grundplatte resultieren, die sowohl Steifigkeit als auch Dämpfung aufweist.

Die Steifigkeit eines Objekts verhält sich wie eine Feder: Je stärker sie zusammengedrückt wird, desto höher ist die Kraft. Im Gegensatz dazu, ist die Dämpfung der Widerstand eines Objekts gegen Bewegung. Wasser hat zum Beispiel keine Steifigkeit, aber es hat Dämpfung, so dass es keinen Widerstand bietet, wenn es langsam berührt wird, und viel Widerstand, wenn es sich schnell bewegt. schnell.

Szene einrichten

Beginnen Sie mit der Erstellung eines HapticThread und eines sphärischen Cursor-Visualisierers, wie in der Schnellstartanleitung Anleitung. Als nächstes erstellen Sie eine Ebene, nennen sie Ground und setzen ihre y-Position auf -0,4. Erstellen Sie ein neues C#-Skript mit dem Namen GroundForce.cs, fügen Sie es demselben GameObject wie den HapticThread hinzu und fügen Sie die folgenden Eigenschaften zu der Klasse GroundForce

[Range(0, 800)]
public float stiffness = 600f;
[Range(0, 3)]
public float damping = 1;

public Transform ground;
private float m_groundHeight;
private float m_cursorRadius;

Wenn Sie sich von der Ebene entfernen, sollte Inverse3 keine Kräfte erzeugen. Kräfte treten nur auf, wenn der Cursor die Oberfläche der Ebene berührt, d. h. der Cursor dringt in die Ebene ein. Die Berechnung der Eindringtiefe hängt nicht nur von der Position der Ebene, sondern auch vom Cursor-Visualisierungsradius ab. Unter diesem Fall reicht es aus, den Cursorradius von der Position Inverse3 zu subtrahieren, um die die relative Position des Cursors korrekt wiederzugeben.

Wenn der Cursor die Ebene berührt, hängt die resultierende Kraft sowohl von der Position als auch von der Geschwindigkeit des Cursors ab, ab, die beide von Inverse3 bereitgestellt werden (siehe Entwickeln mit Inverse3), was bedeutet, dass die ForceCalculation-Methode ist

private Vector3 ForceCalculation ( in Vector3 position, in Vector3 velocity )
{
var force = Vector3.zero;

// Bottom of the sphere
var contactPoint = position.y - m_cursorRadius;

var penetration = m_groundHeight - contactPoint;
if ( penetration > 0 )
{
force.y = penetration * stiffness - velocity.y * damping;
}

return force;
}

Als nächstes aktualisieren Sie die Awake Methode zu: zuweisen m_groundHeight und m_cursorRadiusfinden Sie die HapticThread, und starten Sie es.

private void Awake ()
{
m_groundHeight = ground.transform.position.y;

var hapticThread = GetComponent<HapticThread>();
m_cursorRadius = hapticThread.avatar.lossyScale.y / 2;

hapticThread.onInitialized.AddListener(() => hapticThread.Run( ForceCalculation ));
}

Öffnen Sie schließlich das Inspektorfenster für das GroundForce-Skript und weisen Sie die Ground-Ebene dem entsprechenden Feld zu. Starten Sie den Spielmodus und berühren Sie die Bodenebene. Experimentieren Sie mit verschiedenen Steifigkeits und Dämpfungswerten und sehen Sie sich den Unterschied in der Empfindung an, die die beiden erzeugen.

Der Cursor ist auf dem Boden aufgeschlagen

Quelldateien

Die endgültige Szene und alle zugehörigen Dateien, die in diesem Beispiel verwendet werden, können aus dem Basic Force Feedback and Workspace Control-Beispiel im Paketmanager von Unity importiert werden.

using Haply.HardwareAPI.Unity;
using UnityEngine;

public class GroundForce : MonoBehaviour
{
[Range(0, 800)]
public float stiffness = 600f;
[Range(0, 3)]
public float damping = 1;

public Transform ground;

private float m_groundHeight;
private float m_cursorRadius;

private void Start ()
{
var hapticThread = GetComponent<HapticThread>();

m_groundHeight = ground.transform.position.y;
m_cursorRadius = hapticThread.avatar.lossyScale.y / 2;

hapticThread.onInitialized.AddListener(() => hapticThread.Run( ForceCalculation ));
}

private Vector3 ForceCalculation ( in Vector3 position, in Vector3 velocity )
{
var force = Vector3.zero;

var contactPoint = position.y - m_cursorRadius;
var penetration = m_groundHeight - contactPoint;
if ( penetration > 0 )
{
force.y = penetration * stiffness;
force.y -= velocity.y * damping;
}

return force;
}
}