软件:Unity 2022.3.51f1c1、vscode、Meta XR All in One SDK V72(要提前导入哦)
硬件:Meta Quest3
参考Meta开发文档:https://developers.meta.com/horizon/documentation/unity/unity-haptics-sdk-integrate
这篇官方文档写得特别清晰明了强烈建议大家自己去看一看
效果:实现触碰物体时触碰的手柄震动
前置准备:导入Haptics示例包
我的目的是用里面的震动文件(.haptic),你们要是自己有也可以不导入samples
这个sdk很简单,有两种方式控制震动(HapticSource和HapticPlayer),两种方式能达到的效果是完全一样的,使用这两个类可以控制以下属性
Amplitude 振幅Amplitude refers to the strength or intensity of the vibration. It is a property on both APIs controlling how much force the actuator (the component that generates the haptic feedback) generates through vibrations. When playing back a haptic clip in Unity, adjust theamplitude
property either in advance of or during playback (dynamically at runtime).
振幅是指振动的强度或强度。它是两个 API 上的一个属性,用于控制执行器(生成触觉反馈的组件)通过振动产生的力的大小。在 Unity 中播放触觉片段时,可以在播放之前或播放期间(在运行时动态)调整amplitude
属性。Frequency 频率Frequency refers to the speed at which the actuator vibrates. A higher frequency value will result in a faster vibration, while a lower frequency value will result in a slower vibration. The frequency of a haptic clip can also be adjusted using thefrequencyShift
property on both APIs. This allows developers to create haptic effects that change frequency over time, such as a vibration that starts off slow and gradually increases in speed.
频率是指执行器振动的速度。频率值越高,振动越快,频率值越低,振动越慢。还可以使用两个 API 上的frequencyShift
属性调整触觉片段的频率。这样,开发人员就可以创建随时间改变频率的触觉效果,例如,振动从缓慢开始,然后逐渐增加速度。By adjusting the amplitude and frequency properties, developers can create a wide range of haptic effects.
通过调整幅度和频率属性,开发人员可以创建各种各样的触觉效果。Playback priority 播放优先The priority property determines the order in which haptic clips are played when multiple HapticSources and/or HapticClipPlayers are active at the same time. The priority is a value between 0 and 255, with lower values taking precedence over higher values.
当多个 HapticSources 和/或 HapticClipPlayers 同时处于活动状态时,优先级属性决定了触觉剪辑的播放顺序。优先级是介于 0 和 255 之间的值,较低的值优先于较高的值。When multiple HapticSources and/or HapticClipPlayers are playing haptic clips simultaneously, the one with the highest priority will play its clip first. If two or more have the same priority, the one that was started most recently will take precedence. You can set thepriority
on either API using the priority property in the Unity editor or through scripting. For example:
当多个HapticSources和/或HapticClipPlayers同时播放触觉剪辑时,优先级最高的将首先播放其剪辑。如果两个或多个优先级相同,则最近启动的将优先。您可以使用 Unity 编辑器中的优先级属性或通过脚本在任一 API 上设置priority
。例如:hapticSource.priority = 128;
Or: 或者:hapticClipPlayer.priority = 128;
This would set the priority to 128, which is a medium-high priority. It’s important to note that the priority only affects the playback of haptic clips when multiple sources/players are active at the same time. If only one is active, its priority has no effect on playback.
这会将优先级设置为 128,即中高优先级。需要注意的是,优先级仅在多个源/播放器同时处于活动状态时才会影响触觉剪辑的播放。如果只有一个处于活动状态,则其优先级对播放没有影响。When a HapticSource/HapticClipPlayer starts playback, it will interrupt a currently active source/player of the same or lower priority. Once it finishes playback, the source/player with the next highest priority will resume triggering vibrations.
当 HapticSource/HapticClipPlayer 开始播放时,它将中断当前处于活动状态的、优先级相同或更低的源/播放器。一旦播放完毕,下一个最高优先级的源/播放器将恢复触发振动。Loop haptics 循环触觉Use theloop
/isLooping
property of the HapticSource or HapticClipPlayer respectively. This property allows you to enable or disable looping of clip playback. You can call this property before or during playback. If you set it totrue
, the haptic clip will continue playing indefinitely until you callStop()
or disable looping again.
分别使用 HapticSource 或 HapticClipPlayer 的loop
/isLooping
属性。此属性允许您启用或禁用剪辑播放的循环。您可以在播放之前或播放期间调用此属性。如果将其设置为true
,触觉剪辑将无限期地继续播放,直到您再次调用Stop()
或禁用循环。
一、现成的组件HapticSource
这个东西是不是看起来很眼熟,有点像AudioSource,用法也差不多,可以在代码里配值也可以在场景里直接设置好,我的项目没用这个组件,就不展开讲了,感兴趣的朋友自己研究一下,在代码里用这个库就行了
using Oculus.Haptics;
HapticSource hapticSource;
二、只能在代码里实例化的HapticClipPlayer
这个类必须要实例化了才能使用,示例如下
达到触摸某物体就会震动的效果
1、代码及思路:就是用trigger检测触碰,检测到了就播放震动,同时记录是哪只手触发的trigger,使其对应手柄播放震动
public class NormalHapticTrigger : MonoBehaviour
{
public HapticClip hoverHaptic;
HapticClipPlayer hapticClipPlayer;
Controller activatedController = Controller.Right;
void Start()
{
hapticClipPlayer = new HapticClipPlayer(hoverHaptic);
}
void OnTriggerEnter(Collider other)//其实如果想要更真实的物理效果的话,用OnCollisonEnter更好一些
{
if (other.name.Contains("PalmTrigger"))
{
if (other.name.Contains("Left"))
{
Debug.Log("Left Hand");
activatedController = Controller.Left;
}
else if (other.name.Contains("Right"))
{
Debug.Log("Right Hand");
activatedController = Controller.Right;
}
//震动
hapticClipPlayer.Play(activatedController);
}
}
}
2、场景内配置
1)创建被交互物体
该脚本应该挂在被触碰到时需要手柄震动的物体上,我这里就建了个正方体,别忘了挂上碰撞体(这样才能触发trigger)
2)给HoverHaptic赋值
这里你只要前面导了示例包一打开一堆哈,(只是看看效果的话)随便选一个就行
3)配置手柄上触发器子物体
我的代码为了确定是哪只手柄需要触发震动,限定了if (other.name.Contains("PalmTrigger"))这个条件,所以需要在手柄的子物体里添加名字含有PalmTrigger的空物体
另外,左右手柄的trigger子物体名字加上Left/Right以便区分具体是哪个手柄触发
触发器发消息需要一方同时具有勾上trigger的collider和rigidbody
4)运行
这个效果不好展示,这样配置以后用手柄去触碰挂了我提供的代码的物体手柄就会震动了
最后,Meta提供了一个软件来帮助大家根据自己的音频来制作震动效果,我粗略扫了一眼也是傻瓜式操作(大概),感兴趣的朋友可以去试试,我暂时还没到这个需求
https://developers.meta.com/horizon/resources/haptics-studio
再贴一个关于HapticClipPlayer的API参考
HapticClipPlayer provides controls for playing a HapticClip.
HapticClipPlayer提供播放HapticClip的控制。A HapticClipPlayer only plays valid HapticClips. You can start and stop a HapticClip assigned to a HapticClipPlayer as often as required.
HapticClipPlayer仅播放有效的HapticClip 。您可以根据需要随时启动和停止分配给HapticClipPlayer的HapticClip 。A HapticClipPlayer can be in a stopped, playing, or paused state. By default a HapticClipPlayer is in a stopped state. A player returns to the stopped state when the loaded clip reaches its end during playback, or by explicitly calling HapticClipPlayer.Stop(). When calling HapticClipPlayer.Play(Controller) the player enters a playing state. A HapticClipPlayer in the playing state can enter a paused state by calling HapticClipPlayer.Pause(). Playback can be unpaused (i.e. playing) from the current paused playback position by calling HapticClipPlayer.Play(Controller) or HapticClipPlayer.Resume(). Calling HapticClipPlayer.Resume() on a playing player has no effect. Calling HapticClipPlayer.Play(Controller) on a playing player makes it play again from the start.
HapticClipPlayer可以处于停止、播放或暂停状态。默认情况下, HapticClipPlayer处于停止状态。当加载的剪辑在播放期间到达结尾时,或者通过明确调用HapticClipPlayer.Stop() ,播放器将返回到停止状态。调用HapticClipPlayer.Play(Controller)时,播放器进入播放状态。处于播放状态的HapticClipPlayer可以通过调用HapticClipPlayer.Pause()进入暂停状态。通过调用HapticClipPlayer.Play(Controller)或HapticClipPlayer.Resume() ,可以从当前暂停的播放位置取消暂停(即播放)。在正在播放的播放器上调用HapticClipPlayer.Resume()没有任何效果。在正在播放的播放器上调用HapticClipPlayer.Play(Controller)会使其从头开始再次播放。The rendered amplitude and frequency can be modulated during runtime using the HapticClipPlayer.amplitude and HapticClipPlayer.frequencyShift properties respectively. You can also loop a clip using the HapticClipPlayer.isLooping property.
渲染的振幅和频率可在运行时分别使用HapticClipPlayer.amplitude和HapticClipPlayer.frequencyShift属性进行调制。您还可以使用HapticClipPlayer.isLooping属性循环播放剪辑。It is possible to release HapticClipPlayer objects as needed to free up memory using the HapticClipPlayer.Dispose() method. Of course, calling any method on a released HapticClipPlayer will cause a runtime error.
可以根据需要使用HapticClipPlayer.Dispose()方法释放HapticClipPlayer对象以释放内存。当然,在已释放的HapticClipPlayer上调用任何方法都会导致运行时错误。