跳至主要内容

《基础力与位置教程》

本指南简要演示了如何施加力并可视化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 将该力施加到光标上。

根据 入门指南 中的详细说明,在 OnEnable 和 OnDisable 在方法中加入 OnDeviceStateChanged 回调:

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);
}
}
}