跳到主要内容
本页面由机器自动翻译,可能包含错误。 查看英文原文

Class UBhapticsSDK2

继承自 UBlueprintFunctionLibrary


UBhapticsSDK2 类包含用于使用 bHaptics 触觉设备的函数。

参考

ModuleBhapticsPlugin
HeaderEngine\Plugins\Marketplace\BhapticsPlugin\Source\BhapticsPlugin\Public\BhapticsSDK2.h
Include#include "BhapticsSDK2.h"

静态函数 — 事件驱动触觉播放

播放绑定到 Designer/Portal 中创建的特定触觉事件的触觉模式。我们强烈推荐使用这些函数。

PlayHaptic

static int PlayHaptic(FString eventId);

播放触觉事件。这是调用触觉事件最基本的方式,在所有触觉事件调用函数中开销最低。

参数

  • FString eventId: 要播放的触觉事件的名称。

返回值

Request ID。您可以使用 Request ID 来停止触觉。如果返回失败,则返回 -1

但是,当连接到 Hub 时,由于 Hub 不提供返回值,失败的调用不会返回 -1

示例

#include "BhapticsSDK2.h"

void AExample::Shoot()
{
// Assuming the event name is "shootpistol"
UBhapticsSDK2::PlayHaptic("shootpistol");
}

PlayHapticWithOption

static int PlayHapticWithOption(FString eventId, float intensity = 1.0f, float duration = 1.0f, float angleX = 0.0f, float offsetY = 0.0f);

在调整触觉的强度、Duration 和方向的同时播放触觉事件。

参数

  • FString eventId: 要播放的触觉事件的名称。
  • float intensity: 触觉 Intensity 乘以此值。
  • float duration: 触觉 Duration 乘以此值。
  • float angleX: 围绕全局 Vector3.up 逆时针旋转触觉。有效范围: [0.0f - 360.0f]
  • float offsetY: 将触觉向上或向下移动。有效范围: [-0.5f - 0.5f]

返回值

Request ID。您可以使用 Request ID 来停止触觉。如果返回失败,则返回 -1

但是,当连接到 Hub 时,由于 Hub 不提供返回值,失败的调用不会返回 -1

示例

#include "BhapticsSDK2.h"

void AExample::Shoot()
{
UBhapticsSDK2::PlayHapticWithOption(
"shootpistol", // Haptic name
1.0f, // Haptic intensity
1.0f, // Haptic duration
0.0f, // Rotate haptic around global Vector3.up (0f - 360f)
0.0f // Move haptic up or down (-0.5f - 0.5f)
);
}

PlayWithStartTime

static int PlayWithStartTime(FString eventId, int startMillis = 0, float intensity = 1.0f, float duration = 1.0f, float angleX = 0.0f, float offsetY = 0.0f);

在调整触觉的强度、Duration 和方向的同时播放触觉事件。

参数

  • FString eventId: 要播放的触觉事件的名称。
  • int startMillis: 播放开始位置(以毫秒为单位)。事件开头的 startMillis 毫秒会被跳过(这是起始 Offset,而非播放前的延迟)。默认值为 0仅限 Windows/macOS/Android。
  • float intensity: 触觉 Intensity 乘以此值。
  • float duration: 触觉 Duration 乘以此值。
  • float angleX: 围绕全局 Vector3.up 逆时针旋转触觉。有效范围: [0.0f - 360.0f]
  • float offsetY: 将触觉向上或向下移动。有效范围: [-0.5f - 0.5f]

返回值

Request ID。您可以使用 Request ID 来停止触觉。如果返回失败,则返回 -1

但是,当连接到 Hub 时,由于 Hub 不提供返回值,失败的调用不会返回 -1

示例

#include "BhapticsSDK2.h"

void AExample::Shoot()
{
UBhapticsSDK2::PlayWithStartTime(
"shootpistol", // Haptic name
0, // Playback start position (millisecond)
1.0f, // Haptic intensity
1.0f, // Haptic duration
0.0f, // Rotate haptic around global Vector3.up (0f - 360f)
0.0f // Move haptic up or down (-0.5f - 0.5f)
);
}

PlayLoop

static int PlayLoop(FString eventId, float intensity = 1.0f, float duration = 1.0f, float angleX = 0.0f, float offsetY = 0.0f, int interval = 200, int maxCount = 999999);

重复播放触觉。此外,与 PlayHapticWithOption 函数一样,您可以调整触觉的强度、Duration 和方向。

参数

  • FString eventId: 要播放的触觉事件的名称。
  • float intensity: 触觉 Intensity 乘以此值。
  • float duration: 触觉 Duration 乘以此值。
  • float angleX: 围绕全局 Vector3.up 逆时针旋转触觉。有效范围: [0.0f - 360.0f]
  • float offsetY: 将触觉向上或向下移动。有效范围: [-0.5f - 0.5f]
  • int interval: 循环之间的时间间隔,以毫秒为单位。
  • int maxCount: 循环次数。

返回值

Request ID。您可以使用 Request ID 来停止触觉。如果返回失败,则返回 -1

但是,当连接到 Hub 时,由于 Hub 不提供返回值,失败的调用不会返回 -1

示例

#include "BhapticsSDK2.h"

void AExample::Shoot()
{
UBhapticsSDK2::PlayLoop(
"shootpistol", // Haptic name
1.0f, // Haptic intensity
1.0f, // Haptic duration
0.0f, // Rotate haptic around global Vector3.up (0f - 360f)
0.0f, // Move haptic up or down (-0.5f - 0.5f)
200, // Loop interval time (millisecond)
999999 // Loop count
);
}

静态函数 — 触觉直接播放

如果您想在不创建新事件的情况下播放触觉,请使用这些函数。

PlayDot

static int PlayDot(int position, TArray<int> motorValues, float seconds = 0.5f);

在特定触觉执行器上播放触觉反馈。无需创建事件即可使用此函数。

参数

  • int position: 触觉设备的类型。更多信息请参阅此处
    设备等同于...电机数
    0TactSuit ProEBhapticsDevicePosition::Vest32
    1TactSleeve(Left)EBhapticsDevicePosition::ForearmL3
    2TactSleeve(Right)EBhapticsDevicePosition::ForearmR3
    3TactVisorEBhapticsDevicePosition::Head4
    4Tactosy for Hands(Left)EBhapticsDevicePosition::HandL3
    5Tactosy for Hands(Right)EBhapticsDevicePosition::HandR3
    6Tactosy for Feet(Left)EBhapticsDevicePosition::FootL3
    7Tactosy for Feet(Right)EBhapticsDevicePosition::FootR3
    8TactGlove(Left)EBhapticsDevicePosition::GloveL8
    9TactGlove(Right)EBhapticsDevicePosition::GloveR8
  • TArray<int> motorValues: 根据设备的电机数量指定数组长度。数组中的值表示电机的 Intensity。数组中每个值的有效范围: [0 - 100]
  • float seconds: 触觉的 Duration,以秒为单位。建议大于或等于 0.1f

返回值

Request ID。您可以使用 Request ID 来停止触觉。如果返回失败,则返回 -1

但是,当连接到 Hub 时,由于 Hub 不提供返回值,失败的调用不会返回 -1

示例

#include "BhapticsSDK2.h"

void AExample::Shoot()
{
// TactSuit Pro has 32 motors, so length of array should be 32 too.
TArray<int> MotorValueArray = TArray<int>{
50, 40, 30, 20, 10, 50, 40, 30,
50, 40, 30, 20, 10, 50, 40, 30,
50, 40, 30, 20, 10, 50, 40, 30,
50, 40, 30, 20, 10, 50, 40, 30};

UBhapticsSDK2::PlayDot(
(int)EBhapticsDevicePosition::Vest, // Device type
MotorValueArray, // Haptic intensities
0.5f // Haptic duration (second)
);
}

PlayPath

static int PlayPath(int position, TArray<float> x, TArray<float> y, TArray<int> motorValues, float seconds = 0.5);

在特定坐标周围播放触觉。与为每个触觉执行器单独指定触觉 Intensity 的 PlayDot 函数不同,此方法为特定坐标指定触觉 Intensity。

在指定触觉位置时,PlayDot 提供离散控制,而 PlayPath 则更为连续。PlayDot 为各个执行器分配 Intensity,而 PlayPath 为特定坐标(X 轴和 Y 轴均在 0 和 1 之间)分配 Intensity,从而使附近的执行器相应地振动。

您可以在数组中放入多个坐标和多个 Intensity。请注意,数组中这些坐标周围的所有执行器将**同时(在同一时刻)**作动,而非顺序作动。此外,所有数组的大小必须相同。

通过在逐渐改变值的同时持续调用此函数,您可以实现触觉点移动的效果。

[TactGlove DK3] PlayPath 不驱动 DK3 手套上的手腕音圈电机(VCM)。

Frame 82.png

参数

  • int position: 触觉设备的类型。
    设备等同于...
    0TactSuit ProEBhapticsDevicePosition::Vest
    1TactSleeve(Left)EBhapticsDevicePosition::ForearmL
    2TactSleeve(Right)EBhapticsDevicePosition::ForearmR
    3TactVisorEBhapticsDevicePosition::Head
    4Tactosy for Hands(Left)EBhapticsDevicePosition::HandL
    5Tactosy for Hands(Right)EBhapticsDevicePosition::HandR
    6Tactosy for Feet(Left)EBhapticsDevicePosition::FootL
    7Tactosy for Feet(Right)EBhapticsDevicePosition::FootR
    8TactGlove(Left)EBhapticsDevicePosition::GloveL
    9TactGlove(Right)EBhapticsDevicePosition::GloveR
  • TArray<float> x: 指定 X 坐标。数组中每个值的有效范围: [0.0f - 1.0f]
  • TArray<float> y: 指定 Y 坐标。数组中每个值的有效范围: [0.0f - 1.0f]
  • TArray<int> motorValues: 根据坐标数量指定数组长度。数组中的值表示坐标的 Intensity。数组中每个值的有效范围: [0 - 100]
  • float seconds: 触觉的 Duration,以秒为单位。建议大于或等于 0.1f

返回值

Request ID。您可以使用 Request ID 来停止触觉。如果返回失败,则返回 -1

但是,当连接到 Hub 时,由于 Hub 不提供返回值,失败的调用不会返回 -1

示例

#include "BhapticsSDK2.h"

/* Assumption:
- For TactSuit Pro
- Coordinate with Intensity
- (X: 0.1, Y: 0.2) Intensity 40
- (X: 0.3, Y: 0.4) Intensity 80
- (X: 0.5, Y: 0.6) Intensity 10
- Duration 0.5 second
*/
void AExample::Shoot()
{
UBhapticsSDK2::PlayPath(
(int)EBhapticsDevicePosition::Vest, // Device Type
TArray<float>{0.1f, 0.3f, 0.5f}, // X Coordinates
TArray<float>{0.2f, 0.4f, 0.6f}, // Y Coordinates
TArray<int>{40, 80, 10}, // Intensities
0.5f // Duration
);
}

PlayWaveform

static int PlayWaveform(int position, TArray<int> motorIntensities, TArray<EBhapticsGlovePlayTime> playTimeValues, TArray<EBhapticsGloveShapeValue> shapeValues, int frequency = 80, int repeatCount = 0);

仅限 TactGlove。 在 TactGlove 中播放触觉。与使用 PlayDot 不同,您可以精细地调整触觉 Duration 和振动 Intensity 的变化。这使得触觉反馈的表现更加精细。

每个数组(motorIntensitiesplayTimeValuesshapeValues)对于 TactGlove DK2 必须有六个元素,对于 TactGlove DK3 必须有八个元素,并且这三个数组的长度必须相同。任何其他长度都会返回 -1

参数

  • int position: 触觉设备的类型。

    设备等同于…
    8TactGlove(Left)EBhapticsDevicePosition::GloveL
    9TactGlove(Right)EBhapticsDevicePosition::GloveR
  • TArray<int> motorIntensities: 表示每个电机 Intensity 的数组。其长度必须与 TactGlove 的电机数量一致:六个(TactGlove DK2)或八个(TactGlove DK3)。数组索引 67(见下表)处的手掌电机仅在 DK3 上存在。数组中每个值的有效范围: [0 - 100]

    数组索引电机位置…
    0拇指指尖
    1食指指尖
    2中指指尖
    3无名指指尖
    4小指指尖
    5手腕上
    6手掌(拇指侧)
    7手掌(小指侧)
  • TArray<EBhapticsGlovePlayTime> playTimeValues: 与 motorIntensities 长度相同的数组(DK2 为六个,DK3 为八个),每个元素表示一个作动的时间间隔,时间使用 EBhapticsGlovePlayTime enum 定义。

    Duration等同于…
    EBhapticsGlovePlayTime::None0
    EBhapticsGlovePlayTime::FiveMS5ms1
    EBhapticsGlovePlayTime::TenMS10ms2
    EBhapticsGlovePlayTime::TwentyMS20ms4
    EBhapticsGlovePlayTime::ThirtyMS30ms6
    EBhapticsGlovePlayTime::FortyMS40ms8
  • TArray<EBhapticsGloveShapeValue> shapeValues: 与 motorIntensities 长度相同的数组(DK2 为六个,DK3 为八个),每个元素表示触觉 Intensity 随时间变化的形态,由 EBhapticsGloveShapeValue enum 指定。

    波形等同于…
    EBhapticsGloveShapeValue::Constant在 Duration 期间保持恒定 Intensity0
    EBhapticsGloveShapeValue::Decreasing从指定的 Intensity 开始并减小一半1
    EBhapticsGloveShapeValue::Increasing从指定 Intensity 的一半开始并增加到指定值。2

    [TactGlove DK3] 在 DK3 手套上,手腕执行器(数组索引 5)是音圈电机(VCM),反映 shapeValues。其余七个电机应用波形形态的方式与 DK2 手套相同。

  • int frequency: [仅限 TactGlove DK3] DK3 手套自身执行器的振动频率(Hz)。默认值为 80。这仅影响 DK3 手套本身,不会更改任何其他已连接设备的工作频率。它对 DK2 手套或通用(非 Windows/macOS)路径没有影响。仅限 Windows/macOS。

  • int repeatCount: 重复波形的次数,从 1 开始计数。0 表示播放一次。仅限 Windows/macOS。

返回值

Request ID。您可以使用 Request ID 来停止触觉。如果返回失败,则返回 -1

但是,当连接到 Hub 时,由于 Hub 不提供返回值,失败的调用不会返回 -1

示例

#include "BhapticsSDK2.h"

void AExample::Shoot()
{
TArray<int> GloveMotorValue = TArray<int>{50, 50, 50, 50, 50, 50, 50, 50};

TArray<EBhapticsGlovePlayTime> GlovePlayTime = {
EBhapticsGlovePlayTime::FiveMS, EBhapticsGlovePlayTime::TenMS,
EBhapticsGlovePlayTime::TwentyMS, EBhapticsGlovePlayTime::ThirtyMS,
EBhapticsGlovePlayTime::FortyMS, EBhapticsGlovePlayTime::None,
EBhapticsGlovePlayTime::None, EBhapticsGlovePlayTime::None};

TArray<EBhapticsGloveShapeValue> GloveShapeValue = {
EBhapticsGloveShapeValue::Constant, EBhapticsGloveShapeValue::Decreasing,
EBhapticsGloveShapeValue::Increasing, EBhapticsGloveShapeValue::Constant,
EBhapticsGloveShapeValue::Decreasing, EBhapticsGloveShapeValue::Increasing,
EBhapticsGloveShapeValue::Constant, EBhapticsGloveShapeValue::Constant};

UBhapticsSDK2::PlayWaveform(
(int)EBhapticsDevicePosition::GloveL, // Device Type
GloveMotorValue, // Intensities
GlovePlayTime, // Intervals
GloveShapeValue // Intensity changing forms
);
}

静态函数 — 其他

StopHapticByEventId

static bool StopHapticByEventId(FString eventId);

通过 Event ID 停止触觉事件。返回停止是否成功。

#include "BhapticsSDK2.h"

void AExample::Example()
{
UBhapticsSDK2::StopHapticByEventId("eventID");
}

StopHapticByRequestId

static bool StopHapticByRequestId(int requestId);

使用执行触觉的函数返回的 Request ID 来停止触觉事件。返回停止是否成功。

#include "BhapticsSDK2.h"

void AExample::Example()
{
int RequestID = UBhapticsSDK2::PlayHaptic("eventID");
UBhapticsSDK2::StopHapticByRequestId(RequestID);
}

StopHaptic

static bool StopHaptic();

停止当前正在播放的所有触觉。返回停止是否成功。

#include "BhapticsSDK2.h"

void AExample::Example()
{
UBhapticsSDK2::PlayHaptic("bangbang");
UBhapticsSDK2::PlayHaptic("eventID");
UBhapticsSDK2::PlayHaptic("explosion");

UBhapticsSDK2::StopHaptic();
}

PauseHapticByEventId

static void PauseHapticByEventId(FString eventId);

通过 Event ID 暂停触觉事件。播放位置会被保留,以便之后可以用 ResumeHapticByEventId 继续播放。

#include "BhapticsSDK2.h"

void AExample::Example()
{
UBhapticsSDK2::PauseHapticByEventId("eventID");
}

ResumeHapticByEventId

static void ResumeHapticByEventId(FString eventId);

恢复之前用 PauseHapticByEventId 暂停的触觉事件,从暂停的位置继续播放。

#include "BhapticsSDK2.h"

void AExample::Example()
{
UBhapticsSDK2::ResumeHapticByEventId("eventID");
}

IsPlaying

static bool IsPlaying();

检查触觉是否正在播放。

#include "BhapticsSDK2.h"

void AExample::Example()
{
if (UBhapticsSDK2::IsPlaying())
{
StopHaptic();
}
}

IsPlayingByEventId

static bool IsPlayingByEventId(FString eventId);

检查此 Event ID 对应的触觉事件是否正在播放。

#include "BhapticsSDK2.h"

void AExample::Example()
{
UBhapticsSDK2::PlayHaptic("eventID");

if (UBhapticsSDK2::IsPlayingByEventId("eventID"))
{
UBhapticsSDK2::StopHapticByEventId("eventID");
}
}

IsPlayingByRequestId

static bool IsPlayingByRequestId(int requestId);

检查此 Request ID 对应的触觉事件是否正在播放。

#include "BhapticsSDK2.h"

void AExample::Example()
{
int RequestID = UBhapticsSDK2::PlayHaptic("eventID");
if (UBhapticsSDK2::IsPlayingByRequestId(RequestID))
{
UBhapticsSDK2::StopHapticByRequestId(RequestID);
}
}

Initialize

static void Initialize();

初始化触觉环境。在使用触觉相关函数之前应调用此函数。

Ping

static void Ping(FBhapticsDevice device);

向特定设备发送简单的触觉反馈。

PingAll

static void PingAll();

向所有已连接的设备发送简单的触觉反馈。

Destroy

static void Destroy();

销毁触觉环境。此函数必须在游戏结束时调用,并且只能调用一次。

GetBhapticsDevices

static TArray<FBhapticsDevice> GetBhapticsDevices();

获取已连接触觉设备信息的数组。

IsBhapticsAvailable

static bool IsBhapticsAvailable();

检查触觉环境是否已初始化并准备好使用触觉相关函数。

ProjectToVest

static FBhapticsRotationOption ProjectToVest(
FVector ContactLocation,
UPrimitiveComponent* PlayerComponent,
float HalfHeight = 0
);

用于计算给定碰撞接触点相对于玩家的 Offset 值(角度和高度)的辅助函数。这些 Offset 值可用于能够调整触觉位置的 PlayHapticWithOptionPlayLoop

此函数假定正面方向与背心的前面对齐,并将玩家的位置视为原点。

详细信息请查看下面的示例。

参数

  • FVector ContactLocation: 全局坐标系中的接触点。
  • UPrimitiveComponent* PlayerComponent: 对附加到玩家的图元组件的引用。
  • float HalfHeight: 玩家实际身高的一半值,以厘米为单位。

示例

假设要实现 VR 游戏中被枪击时的触觉。此事件对应的触觉模式将是 TactSuit 正面中央短促而强烈的触觉反馈。为了增强真实感,根据玩家被击中的位置改变触觉反馈的高度和角度将是理想的。

PlayHapticWithOptionPlayLoop 函数允许调整触觉模式的高度和角度。这些函数接受用于触觉调整的**角度(OffsetAngleX)和高度(OffsetY)**值。

ProjectToVest 函数根据玩家被击中的位置、玩家的变换信息以及用户的身高来计算角度和高度值。然后将这些值封装在 FBhapticsRotationOption 结构体中返回。

Frame 81 (1).png

#include "BhapticsSDK2.h"

void AExample::HitByBullet()
{
APawn *PlayerPawn = UGameplayStatics::GetPlayerPawn(GetWorld(), 0);
UPrimitiveComponent *PlayerComponent = Cast<UPrimitiveComponent>(PlayerPawn->GetRootComponent());

FVector ContactLocation = USomewhere::GetContactLocationSomehow();
float HalfHeight = YourActualHeight / 2;

FBhapticsRotationOption result = UBhapticsSDK2::ProjectToVest(ContactLocation, PlayerComponent, HalfHeight);

UBhapticsSDK2::PlayHapticWithOption("hit_by_bullet", 1.0f, 1.0f, result.OffsetAngleX, result.OffsetY);
}

ProjectToVestLocation

static FBhapticsRotationOption ProjectToVestLocation(FVector ContactLocation, FVector PlayerLocation, FRotator PlayerRotation);

用于根据接触位置和玩家变换信息计算 Offset 值的辅助函数。它类似于 ProjectToVest,但仅计算角度 Offset(OffsetAngleX)。高度(OffsetY)将始终为 0。

参数

  • FVector ContactLocation: 全局坐标系中的接触点。
  • FVector PlayerLocation: 玩家的位置。
  • FRotator PlayerRotation: 玩家的旋转。

CustomProjectToVest

static FBhapticsRotationOption CustomProjectToVest(FVector ContactLocation, UPrimitiveComponent* PlayerComponent, float HalfHeight = 0, FVector UpVector = FVector::ZeroVector, FVector ForwardVector = FVector::ZeroVector);

用于根据碰撞计算 Offset 值的辅助函数。执行与 ProjectToVest 相同的功能,但允许更改 Forward 和 Up 向量。

  • FVector ContactLocation: 全局坐标系中的接触点。
  • UPrimitiveComponent* PlayerComponent: 对附加到玩家的图元组件的引用。
  • float HalfHeight: 玩家实际身高的一半值,以厘米为单位。
  • FVector UpVector: 用于 Offset 计算的参考向上方向向量。
  • FVector ForwardVector: 用于 Offset 计算的参考正面方向向量。