힘과 위치에 대한 기초 튜토리얼
이 가이드에서는 힘을 적용하고 ‘ Inverse3 ’ 커서의 움직임을 시각화하는 방법을 간단히 시연합니다. 마지막에는 Inverse3 가상 고무줄로 시작 위치에 묶여 있는 듯한 느낌을 시뮬레이션하며, 구형 GameObject가 커서의 위치를 표시합니다.
서론
‘첫걸음 가이드’에서는 해당 객체 Inverse3 및 그 작동 원리, 그리고 일정한 힘을 생성하는 방법을 소개했습니다. 여기서 우리의 목표는 커서에 고무줄 효과를 시뮬레이션하는 것입니다. 고무줄은 스프링과 비슷한 특성을 보이는데, 즉 그 힘은 강성과 양 끝점 사이의 거리 모두에 의해 영향을 받습니다. 따라서 주어진 위치와 강성을 바탕으로, 커서가 원점으로부터 멀어지는 움직임을 저항하는 힘을 계산하는 함수를 개발하고자 합니다.
장면 구성
먼저 ‘GameObjects > Haply ’ 메뉴를 통해 햅틱 리그(한 손용) 를 생성해 보세요.
ForceAndPosition 컴포넌트
GameObject를 선택하세요 햅틱 오리진 aus, 다음 이름의 새 스크립트를 추가하십시오. ForceAndPosition.cs 클래스를 수정하고 내용을 추가하십시오 ForceAndPosition 다음 코드를:
[SerializeField]
private Inverse3 inverse3 = null;
[SerializeField, Range(0, 400)]
private float stiffness = 100;
private void OnDeviceStateChanged(object sender, Inverse3EventArgs args)
{
var inverse3 = args.DeviceController;
// Calculate the force.
var force = (inverse3.WorkspaceCenterLocalPosition - inverse3.CursorLocalPosition) * stiffness;
// Apply the force to the cursor.
inverse3.SetCursorLocalForce(force);
}
이 섹션에서는 강성을 100 뉴턴/미터(N/m)로 설정하여 비교적 부드러운 스프링을 시뮬레이션합니다.
또한, inverse3.WorkspaceCenterLocalPosition 작업 영역의 중심점을 반환하는 속성이 도입되었습니다.
이 메서드는 커서의 위치를 작업 영역의 중심점에서 뺀 다음, 그 결과를 강성과 곱하여 힘을 계산합니다.
마지막으로, 힘을 inverse3.SetCursorLocalForce 커서에 적용됩니다.
콜백을 통합하세요 OnDeviceStateChanged 방법론에 대하여 OnEnable 그리고 OnDisable, 앞서 언급한 바와 같이 초보자용 안내서 설명:
protected void OnEnable()
{
inverse3.DeviceStateChanged += OnDeviceStateChanged;
}
protected void OnDisable()
{
inverse3.DeviceStateChanged -= OnDeviceStateChanged;
}
게임 플레이
Inverse3 커서를 길게 누른 상태에서 재생 모드를 활성화한 뒤 장치를 움직여 보세요. 커서를 이동하면 힘이 발생하는 것을 느낄 수 있습니다. 커서가 시작 위치에서 멀어질수록 이 힘이 더 강하게 느껴집니다.

원본 파일
이 예제에서 사용되는 최종 장면과 관련 파일들은 모두 Unity의 패키지 관리자에서 ‘예제 튜토리얼’을 통해 가져올 수 있습니다.
ForceAndPosition.cs
/*
* Copyright 2024 Haply Robotics Inc. All rights reserved.
*/
using Haply.Inverse.DeviceControllers;
using Haply.Inverse.DeviceData;
using UnityEngine;
namespace Haply.Samples.Tutorials._1_ForceAndPosition
{
/// <summary>
/// Demonstrates the application of force to maintain the cursor at its center position.
/// </summary>
public class ForceAndPosition : MonoBehaviour
{
public Inverse3Controller inverse3;
[Range(0, 400)]
// Stiffness of the force feedback.
public float stiffness = 100;
private void Awake()
{
inverse3 ??= FindObjectOfType<Inverse3Controller>();
}
/// <summary>
/// Subscribes to the DeviceStateChanged event when the component is enabled.
/// </summary>
protected void OnEnable()
{
inverse3.DeviceStateChanged += OnDeviceStateChanged;
}
/// <summary>
/// Unsubscribes from the DeviceStateChanged event and reset the force when the component is disabled.
/// </summary>
protected void OnDisable()
{
inverse3.DeviceStateChanged -= OnDeviceStateChanged;
inverse3.Release();
}
/// <summary>
/// Event handler that calculates and send the force to the device when the cursor's position changes.
/// </summary>
/// <param name="sender">The Inverse3 data object.</param>
/// <param name="args">The event arguments containing the device data.</param>
private void OnDeviceStateChanged(object sender, Inverse3EventArgs args)
{
var inverse3 = args.DeviceController;
// Calculate the force.
var force = (inverse3.WorkspaceCenterLocalPosition - inverse3.CursorLocalPosition) * stiffness;
// Apply the force to the cursor.
inverse3.SetCursorLocalForce(force);
}
}
}