Retour d'effort dans une scène dynamique Tutoriel
Parce que le fil haptique peut être un ordre de grandeur plus rapide que le fil physique
plusieurs mises à jour haptiques peuvent être effectuées entre chaque FixedUpdate()
appel. Cela entraîne des incohérences entre les données de la scène utilisées pour calculer les changements physiques et les données du fil haptique utilisées pour calculer le retour haptique.
données du fil haptique utilisées pour calculer le retour haptique.
Dans cet exemple, nous montrons une approche sans fil pour synchroniser les données de la scène avec la boucle haptique. avec la boucle haptique.
Configuration de la scène
- Ajoutez un fil et un curseur haptique comme indiqué dans Force et position du curseur.
- Créer un Sphère appelé Balle en mouvement et fixer sa position à
(0, 0.15, -0.15)
et son échelle à(0.1, 0.1, 0.1)
La boucle haptique
Ajouter un nouveau Script C# appelé MovingBallForce.cs
à la Balle en mouvement l'objet du jeu. La source de ce script est donnée ci-dessous.
using Haply.HardwareAPI.Unity;
using UnityEngine;
public class MovingBallForce : MonoBehaviour
{
// Thread-safe scene data struct
private struct AdditionalData
{
public Vector3 ballPosition;
// cursor radius + ball radius
public float radiuses;
}
[Range(0, 800)]
public float stiffness = 600f;
// Moving/scaling speed (by pressing arrow keys)
public float speed = 0.2f;
private HapticThread m_hapticThread;
private void Awake ()
{
// Find the HapticThread object before the our first FixedUpdate() call
m_hapticThread = FindObjectOfType<HapticThread>();
// Run the haptic loop with an initial state returned by AdditionalData.
var initialState = GetAdditionalData();
m_hapticThread.onInitialized.AddListener(() => m_hapticThread.Run(ForceCalculation, initialState));
}
private void FixedUpdate ()
{
// Change the scale of the ball
if ( Input.GetKey( KeyCode.UpArrow ) )
transform.localScale += Vector3.one * (Time.fixedDeltaTime * speed);
else if ( Input.GetKey( KeyCode.DownArrow ) )
transform.localScale -= Vector3.one * (Time.fixedDeltaTime * speed);
// Move the ball
if ( Input.GetKey( KeyCode.LeftArrow ) )
transform.transform.position += Vector3.left * (Time.fixedDeltaTime * speed);
else if (Input.GetKey(KeyCode.RightArrow))
transform.transform.position += Vector3.right * (Time.fixedDeltaTime * speed);
// Update AdditionalData with the latest physics data
m_hapticThread.SetAdditionalData(GetAdditionalData());
}
// Method used by HapticThread.Run(ForceCalculation) and HapticThread.GetAdditionalData()
// to synchronize dynamic data between the unity scene and the haptic thread
private AdditionalData GetAdditionalData ()
{
AdditionalData additionalData;
additionalData.ballPosition = transform.localPosition;
additionalData.radiuses = (transform.localScale.x + m_hapticThread.avatar.localScale.x) / 2f;
return additionalData;
}
// Calculate the force to apply when the cursor touches the ball.
// This is done through additionalData to keep things thread-safe.
private Vector3 ComputeForce ( in Vector3 position, in Vector3 velocity, in AdditionalData additionalData )
{
var force = Vector3.zero;
var distance = Vector3.Distance( position, additionalData.ballPosition );
if ( distance < additionalData.radiuses )
{
var penetration = additionalData.radiuses - distance;
force = (position - additionalData.ballPosition) / distance * penetration * stiffness;
}
return force;
}
}
Entrez dans le mode jeu et utilisez les touches fléchées pour déplacer et redimensionner la sphère. Vous devriez voir et sentir les changements de taille et de position de la sphère.
Fichiers sources
La scène finale et tous les fichiers associés utilisés dans cet exemple peuvent être importés à partir du gestionnaire de paquets de Unity.