다이내믹 씬 튜토리얼의 강제 피드백
햅틱 스레드는 물리 스레드보다 훨씬 빠를 수 있기 때문에
스레드보다 훨씬 빠를 수 있기 때문에, 각각의 FixedUpdate()
호출합니다. 이로 인해 물리 변화를 계산하는 데 사용되는 씬 데이터와 햅틱 피드백을 계산하는 데 사용되는
햅틱 피드백을 계산하는 데 사용되는 햅틱 스레드의 데이터 사이에 불일치가 발생합니다.
이 예제에서는 햅틱 루프와 씬 데이터를 동기화하는 스레드 안전 접근 방식 를 동기화하는 스레드 안전 접근 방식을 보여줍니다.
장면 설정
- 힘 및 커서 위치에 표시된 대로 햅틱 스레드 및 커서 추가하기
- 만들기 구체 호출 움직이는 공 를 클릭하고 위치를
(0, 0.15, -0.15)
그리고 그 규모는(0.1, 0.1, 0.1)
햅틱 루프
새 C# 스크립트 호출 MovingBallForce.cs
를 움직이는 공 게임 오브젝트입니다. 이 스크립트의 소스는 아래에 나와 있습니다.
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;
}
}
재생 모드로 들어가서 화살표 키를 사용하여 구를 이동하고 크기를 조정합니다. 구의 크기와 위치가 변경되는 것을 보고 느낄 수 있을 것입니다.
소스 파일
이 예제에서 사용된 최종 씬과 모든 관련 파일은 Unity의 패키지 관리자에서 임포트할 수 있습니다.