跳至主要内容
版本:最新

设备工作区转换教程

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

导言

为了缩放光标的移动,我们将创建一个触觉工作区游戏对象,并将光标球体作为其子对象。 球体作为其子对象。Haptic Workspace平移还可以控制 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;
}
}