跳至主要内容
版本:最新

设备工作区转换教程

触觉模拟试图复制物理物体的几何形状,这些物体可大可小。 Unity 在内部计算中使用浮点运算,这意味着使用大型场景(以米为单位)和缩放运动而非 米规模的大型场景,并缩放Inverse3的运动,而不是将场景缩放至 的工作空间。 缩放场景到Inverse3的工作空间。本教程以生成基本 力反馈教程的基础上,介绍如何缩放运动和定位 的工作空间。 Inverse3 的工作空间。

导言

为了缩放光标的移动,我们将创建一个触觉工作区游戏对象,并将光标球体作为其子对象。 球体作为其子对象。触觉工作区的平移还可以控制 Inverse3 相对于场景的位置进行控制,这意味着可以在不移动场景的情况下将光标移动到不同的位置。 不同的位置,而无需移动场景。

在开始之前,请完成 产生基本力反馈 教程并打开该项目。然后创建一个空的 GameObject,将其命名为 触觉工作区并 将其比例设为 (10, 10, 10).在此示例中,10 的比例将使场景中 1 米的物体感觉只有 10 厘米。 感觉只有 10 厘米,但您也可以将其设置为任何正数。

此外,通过触觉工作区,您还可以将设备工作区相对于场景进行定位。 改变其位置。在本例中,您可以上下移动工作区。

在层次结构窗口中,将光标对象拖到触觉工作区上,使其成为触觉工作区的子对象。 Haptic Workspace的子对象。

还有 HapticThread GroundForce 脚本可以从 触觉线程 游戏对象的 的 触觉工作区触觉线程 可以删除。

工作区层级

现在,打开 GroundForce.cs 并添加以下成员:

private float m_workspaceScale;
private float m_workspaceHeight;

m_workspaceScale 的缩放因子。 触觉工作区 上一步中设置的 同时 m_workspaceHeight 表示工作区在 Y 轴上的场景内位置偏移。下一步 初始化 Awake 方法时,添加

m_workspaceScale = hapticThread.avatar.parent.lossyScale.y;
m_workspaceHeight = hapticThread.avatar.parent.position.y;

现在,更新 ForceCalculation 这样,在计算位置偏移和比例变化时 在计算 contactPoint

var contactPoint = position.y - m_cursorRadius;

用、

var contactPoint = (position.y * m_workspaceScale) + m_workspaceHeight - m_cursorRadius;

缩放运动会导致力随着场景的缩放而缩放。为避免这种情况,力 计算必须通过除以缩放因子来消除位置缩放 m_workspaceScale 以致

force.y = penetration * stiffness;

成为、

force.y = (penetration / m_workspaceScale) * stiffness;

请注意 velocity 永远不会扩大或缩小。

进入播放模式后,您会发现光标的移动会更加明显,但检查窗口中的光标读数保持不变。 光标在检查器窗口中的读数保持不变。您还可以使用 位置参数移动工作区

请注意,触觉计算将在平面上产生一个力,就好像它是无限的一样,因此 横向移动工作区只会影响可视化效果。

工作区比例

工作区偏移平移

源文件

本示例使用的最终场景和所有相关文件可从 Unity 软件包管理器中的 "基本力反馈和工作区控制 "示例导入。 反馈和工作区控制示例中导入。

GroundForce.cs

using Haply.HardwareAPI.Unity;
using UnityEngine;

public class GroundForce : MonoBehaviour
{
[Range(0, 800)]
public float stiffness = 600f;

public Transform ground;

private float m_groundHeight;
private float m_cursorRadius;

// Cursor Offset
private float m_workspaceScale;
private float m_workspaceHeight;

private void Awake ()
{
var hapticThread = GetComponent<HapticThread>();

m_groundHeight = ground.transform.position.y;
m_cursorRadius = hapticThread.avatar.lossyScale.y / 2;

m_workspaceScale = hapticThread.avatar.parent.lossyScale.y;
m_workspaceHeight = hapticThread.avatar.parent.position.y;

hapticThread.onInitialized.AddListener(() => hapticThread.Run( ForceCalculation ));
}

private Vector3 ForceCalculation ( in Vector3 position, in Vector3 velocity )
{
var force = Vector3.zero;

// Contact point scaled by parent offset
var contactPoint = (position.y * m_workspaceScale) + m_workspaceHeight - m_cursorRadius;

var penetration = m_groundHeight - contactPoint;
if ( penetration > 0 )
{
force.y = (penetration / m_workspaceScale);;
force.y -= velocity.y * damping;
}
return force;
}
}