设备工作区转换教程
触觉模拟试图复制物理物体的几何形状,这些物体可大可小。 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;
}
}