关于力和位置的基础教程
本指南通过一个简单的示例,演示了如何施加力以及如何可视化光标的位移Inverse3 。 最后,Inverse3 将模拟出光标被一条虚拟橡皮筋拉回起始位置的感觉,同时一个球形 GameObject 将显示光标的位置。
导言
《入门指南》介绍了该对象 Inverse3、其功能以及生成恒定力的方法。 我们此处的目标是模拟橡皮筋对滑块的作用效果。橡皮筋的行为与弹簧类似:其作用力既取决于刚度,也取决于两端之间的距离。 因此,我们的目标是设计一个函数,该函数根据给定的位置和刚度,生成一种能够阻止滑块远离原点的力。
场景设置
首先通过“GameObjects”>“Haply ”菜单创建一个单手触觉装置(Haptic Rig)。
ForceAndPosition 组件
选择该 GameObject 触觉起源 并添加一个名为 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 et OnDisable,正如《》中所描述的那样 指南《入门指南》 :
protected void OnEnable()
{
inverse3.DeviceStateChanged += OnDeviceStateChanged;
}
protected void OnDisable()
{
inverse3.DeviceStateChanged -= OnDeviceStateChanged;
}
游戏体验
将光标Inverse3 ,启用“播放模式”,然后尝试操控该设备。你会发现,光标的移动会产生一种力。 光标离初始位置越远,这种力就越明显。

源文件
本示例中使用的最终场景及所有相关文件均可从 Unity包 管理器的“Tutorials”示例中导入。
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);
}
}
}