bump the SenseGlove Unreal Engine Plugin to v2.1.4

This commit is contained in:
Mamadou Babaei
2024-10-22 07:33:34 +02:00
parent 93b7c31f74
commit 45e41e60d9
6 changed files with 235 additions and 204 deletions
@@ -6,56 +6,56 @@ Taking a closer look at the `FXRMotionControllerData` declaration inside the Unr
USTRUCT(BlueprintType)
struct FXRMotionControllerData
{
GENERATED_USTRUCT_BODY();
GENERATED_USTRUCT_BODY();
UPROPERTY(BlueprintReadOnly, Category = "XR")
bool bValid = false;
UPROPERTY(BlueprintReadOnly, Category = "XR")
FName DeviceName;
UPROPERTY(BlueprintReadOnly, Category = "XR")
FGuid ApplicationInstanceID;
UPROPERTY(BlueprintReadOnly, Category = "XR")
EXRVisualType DeviceVisualType = EXRVisualType::Controller;
UPROPERTY(BlueprintReadOnly, Category = "XR")
bool bValid = false;
UPROPERTY(BlueprintReadOnly, Category = "XR")
FName DeviceName;
UPROPERTY(BlueprintReadOnly, Category = "XR")
FGuid ApplicationInstanceID;
UPROPERTY(BlueprintReadOnly, Category = "XR")
EXRVisualType DeviceVisualType = EXRVisualType::Controller;
UPROPERTY(BlueprintReadOnly, Category = "XR")
EControllerHand HandIndex = EControllerHand::Left;
UPROPERTY(BlueprintReadOnly, Category = "XR")
EControllerHand HandIndex = EControllerHand::Left;
UPROPERTY(BlueprintReadOnly, Category = "XR")
ETrackingStatus TrackingStatus = ETrackingStatus::NotTracked;
UPROPERTY(BlueprintReadOnly, Category = "XR")
ETrackingStatus TrackingStatus = ETrackingStatus::NotTracked;
// Vector representing an object being held in the player's hand
UPROPERTY(BlueprintReadOnly, Category = "XR")
FVector GripPosition = FVector(0.0f);
// Quaternion representing an object being held in the player's hand
UPROPERTY(BlueprintReadOnly, Category = "XR")
FQuat GripRotation = FQuat(EForceInit::ForceInitToZero);
// Vector representing an object being held in the player's hand
UPROPERTY(BlueprintReadOnly, Category = "XR")
FVector GripPosition = FVector(0.0f);
// Quaternion representing an object being held in the player's hand
UPROPERTY(BlueprintReadOnly, Category = "XR")
FQuat GripRotation = FQuat(EForceInit::ForceInitToZero);
// For handheld controllers, gives a vector for pointing at objects
UPROPERTY(BlueprintReadOnly, Category = "XR")
FVector AimPosition = FVector(0.0f);
// For handheld controllers, gives a quaternion for pointing at objects
UPROPERTY(BlueprintReadOnly, Category = "XR")
FQuat AimRotation = FQuat(EForceInit::ForceInitToZero);
// For handheld controllers, gives a vector for pointing at objects
UPROPERTY(BlueprintReadOnly, Category = "XR")
FVector AimPosition = FVector(0.0f);
// For handheld controllers, gives a quaternion for pointing at objects
UPROPERTY(BlueprintReadOnly, Category = "XR")
FQuat AimRotation = FQuat(EForceInit::ForceInitToZero);
// For handheld controllers, gives a vector for representing the hand
UPROPERTY(BlueprintReadOnly, Category = "XR")
FVector PalmPosition = FVector(0.0f);
// For handheld controllers, gives a quaternion for representing the hand
UPROPERTY(BlueprintReadOnly, Category = "XR")
FQuat PalmRotation = FQuat(EForceInit::ForceInitToZero);
// For handheld controllers, gives a vector for representing the hand
UPROPERTY(BlueprintReadOnly, Category = "XR")
FVector PalmPosition = FVector(0.0f);
// For handheld controllers, gives a quaternion for representing the hand
UPROPERTY(BlueprintReadOnly, Category = "XR")
FQuat PalmRotation = FQuat(EForceInit::ForceInitToZero);
// The indices of this array are the values of EHandKeypoint (Palm, Wrist, ThumbMetacarpal, etc).
UPROPERTY(BlueprintReadOnly, Category = "XR")
TArray<FVector> HandKeyPositions;
// The indices of this array are the values of EHandKeypoint (Palm, Wrist, ThumbMetacarpal, etc).
UPROPERTY(BlueprintReadOnly, Category = "XR")
TArray<FQuat> HandKeyRotations;
// The indices of this array are the values of EHandKeypoint (Palm, Wrist, ThumbMetacarpal, etc).
UPROPERTY(BlueprintReadOnly, Category = "XR")
TArray<float> HandKeyRadii;
// The indices of this array are the values of EHandKeypoint (Palm, Wrist, ThumbMetacarpal, etc).
UPROPERTY(BlueprintReadOnly, Category = "XR")
TArray<FVector> HandKeyPositions;
// The indices of this array are the values of EHandKeypoint (Palm, Wrist, ThumbMetacarpal, etc).
UPROPERTY(BlueprintReadOnly, Category = "XR")
TArray<FQuat> HandKeyRotations;
// The indices of this array are the values of EHandKeypoint (Palm, Wrist, ThumbMetacarpal, etc).
UPROPERTY(BlueprintReadOnly, Category = "XR")
TArray<float> HandKeyRadii;
UPROPERTY(BlueprintReadOnly, Category = "XR")
bool bIsGrasped = false;
UPROPERTY(BlueprintReadOnly, Category = "XR")
bool bIsGrasped = false;
};
```
@@ -71,68 +71,88 @@ But, fear not, we've got you covered!
### Structure Members of FXRMotionControllerData
1. **bValid**
- **bValid**
- **Description**: A boolean flag indicating whether the data is valid or not.
- **Usage**: This is used to check if the motion controller data is correctly initialized and can be used for further processing.
2. **DeviceName**
- **DeviceName**
- **Type**: `FName`
- **Description**: The name of the device.
- **Usage**: Identifies which motion controller device the data is coming from, useful when multiple devices are in use.
3. **ApplicationInstanceID**
- **ApplicationInstanceID**
- **Type**: `FString`
- **Description**: A unique identifier for the application instance.
- **Usage**: Helps in differentiating data from different instances of an application, ensuring the correct instance processes the data.
4. **TrackingStatus**
- **DeviceVisualType**
- **Type**: `EXRVisualType`
- **Description**: Enum specifying the visual type of the device (e.g., controller, hand).
- **Usage**: Used to differentiate between various motion controller devices or hand-tracking representations for rendering and interaction purposes.
- **HandIndex**
- **Type**: `EControllerHand`
- **Description**: Enum indicating which hand is being tracked (left or right).
- **Usage**: Helps identify whether the motion data pertains to the left or right hand, essential for hand-specific actions or interactions.
- **TrackingStatus**
- **Type**: `EXRTrackingStatus`
- **Description**: Enum indicating the tracking status of the motion controller.
- **Usage**: Shows whether the controller is being tracked accurately, with possible statuses like `Tracked`, `NotTracked`, etc.
5. **GripPosition**
- **GripPosition**
- **Type**: `FVector`
- **Description**: The position of the grip in world coordinates.
- **Usage**: Provides the 3D coordinates of the controller's grip, essential for positioning the virtual representation of the controller.
6. **GripRotation**
- **GripRotation**
- **Type**: `FQuat`
- **Description**: The rotation of the grip in world coordinates.
- **Usage**: Provides the orientation of the controller's grip, allowing for accurate rotation and alignment in the virtual space.
7. **AimPosition**
- **AimPosition**
- **Type**: `FVector`
- **Description**: The position of the aim point in world coordinates.
- **Usage**: Specifies where the controller is aiming, useful for aiming or pointing actions.
8. **AimRotation**
- **AimRotation**
- **Type**: `FQuat`
- **Description**: The rotation of the aim point in world coordinates.
- **Usage**: Determines the orientation of the aim direction, important for actions like shooting or selecting objects in VR.
9. **HandKeyPositions**
- **PalmPosition**
- **Type**: `FVector`
- **Description**: The position of the palm in world coordinates.
- **Usage**: Provides the 3D location of the palm, important for determining hand gestures or interactions in VR.
- **PalmRotation**
- **Type**: `FQuat`
- **Description**: The rotation of the palm in world coordinates.
- **Usage**: Defines the orientation of the palm, crucial for hand-based interaction accuracy and realism in VR experiences.
- **HandKeyPositions**
- **Type**: `TArray<FVector>`
- **Description**: An array of vectors representing key positions of the hand.
- **Usage**: Provides detailed positions of key points on the hand, useful for precise hand tracking and interaction.
10. **HandKeyRotations**
- **HandKeyRotations**
- **Type**: `TArray<FQuat>`
- **Description**: An array of quaternions representing key rotations of the hand.
- **Usage**: Complements the hand key positions with rotational data, ensuring accurate representation of hand movements.
11. **HandKeyRadii**
- **HandKeyRadii**
- **Type**: `TArray<float>`
- **Description**: An array of floats representing the radii of key points of the hand.
- **Usage**: Gives the size of the hand key points, aiding in collision detection and interaction fidelity.
12. **bIsGrasped**
- **bIsGrasped**
- **Type**: `bool`
- **Description**: A boolean indicating whether the controller is currently grasping an object.
- **Usage**: Determines if the user is holding something, affecting interactions and animations.
### Organization of FXRMotionControllerData
The structure is organized to encapsulate all relevant data needed for motion controller tracking in a coherent and accessible manner. Boolean flags `bValid` and `bIsGrasped` provide quick checks on the state of the controller data. Identifiers `DeviceName` and `ApplicationInstanceID` ensure the correct association of data. Positional and rotational data `GripPosition`, `GripRotation`, `AimPosition`, and `AimRotation` offer precise tracking of the controller's movement. Arrays `HandKeyPositions`, `HandKeyRotations`, and `HandKeyRadii` allow detailed hand tracking, which is critical for immersive VR experiences. Lastly, the tracking status `TrackingStatus` informs the system of the reliability of the data being processed and whether the motion controller is actively being tracked or it's inactive at the moment.
The structure is organized to encapsulate all relevant data needed for hand and motion controller tracking in a coherent and accessible manner. Boolean flags `bValid` and `bIsGrasped` provide quick checks on the state of the controller data. Identifiers `DeviceName` and `ApplicationInstanceID` ensure the correct association of data. Positional and rotational data `GripPosition`, `GripRotation`, `AimPosition`, and `AimRotation` offer precise tracking of the controller's movement. Arrays `HandKeyPositions`, `HandKeyRotations`, and `HandKeyRadii` allow detailed hand tracking, which is critical for immersive VR experiences. Lastly, the tracking status `TrackingStatus` informs the system of the reliability of the data being processed and whether the motion controller is actively being tracked or it's inactive at the moment.
### Processing the Data for Drawing and Animating a Virtual Hand
@@ -150,32 +170,32 @@ Unreal Engine also provides an enum called `EHandKeypoint` naming the 26 joints,
UENUM(BlueprintType)
enum class EHandKeypoint : uint8
{
Palm,
Wrist,
ThumbMetacarpal,
ThumbProximal,
ThumbDistal,
ThumbTip,
IndexMetacarpal,
IndexProximal,
IndexIntermediate,
IndexDistal,
IndexTip,
MiddleMetacarpal,
MiddleProximal,
MiddleIntermediate,
MiddleDistal,
MiddleTip,
RingMetacarpal,
RingProximal,
RingIntermediate,
RingDistal,
RingTip,
LittleMetacarpal,
LittleProximal,
LittleIntermediate,
LittleDistal,
LittleTip
Palm,
Wrist,
ThumbMetacarpal,
ThumbProximal,
ThumbDistal,
ThumbTip,
IndexMetacarpal,
IndexProximal,
IndexIntermediate,
IndexDistal,
IndexTip,
MiddleMetacarpal,
MiddleProximal,
MiddleIntermediate,
MiddleDistal,
MiddleTip,
RingMetacarpal,
RingProximal,
RingIntermediate,
RingDistal,
RingTip,
LittleMetacarpal,
LittleProximal,
LittleIntermediate,
LittleDistal,
LittleTip
};
const int32 EHandKeypointCount = static_cast<int32>(EHandKeypoint::LittleTip) + 1;
@@ -217,7 +237,7 @@ So, getting the any joint's position or rotation is as easy as casting the enum
return;
}
// Ensure that MotionControllerData.HandKeyPositions has the rotation data
// Ensure that MotionControllerData.HandKeyRotations has the rotation data
// for 26 joints!
if (!ensureAlwaysMsgf(MotionControllerData.HandKeyRotations.Num()
== EHandKeypointCount,
@@ -48,4 +48,4 @@ Before continuing this section, please ensure you've studied the [Consuming FXRM
13. Now, go back to the `VRTemplateMap` and use the VR Preview button to run the game. If everything's done correctly, you should be able to see the virtual hands inside your VR simulation.
![FXRMotionControllerData animated debug virtual hands](consuming-fxrmotioncontrollerdata-animated-debug-virtual-hands.gif "FXRMotionControllerData animated debug virtual hands")
![FXRMotionControllerData animated debug virtual hands](consuming-fxrmotioncontrollerdata-animated-debug-virtual-hands.gif "FXRMotionControllerData animated debug virtual hands")
@@ -47,30 +47,30 @@ using UnrealBuildTool;
public class VirtualHandCpp : ModuleRules
{
public VirtualHandCpp(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" });
public VirtualHandCpp(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" });
PrivateDependencyModuleNames.AddRange(new string[]
{
"InputDevice",
"OpenXRHMD",
"SenseGloveBuildHacks",
"SenseGloveDebug",
"SenseGloveSettings",
"SenseGloveTracking"
});
PrivateDependencyModuleNames.AddRange(new string[]
{
"InputDevice",
"OpenXRHMD",
"SenseGloveBuildHacks",
"SenseGloveDebug",
"SenseGloveSettings",
"SenseGloveTracking"
});
// Uncomment if you are using Slate UI
// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
// Uncomment if you are using online features
// PrivateDependencyModuleNames.Add("OnlineSubsystem");
// Uncomment if you are using Slate UI
// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
// Uncomment if you are using online features
// PrivateDependencyModuleNames.Add("OnlineSubsystem");
// To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
}
// To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
}
}
```
@@ -93,32 +93,32 @@ public class VirtualHandCpp : ModuleRules
UCLASS()
class VIRTUALHANDCPP_API ADebugPawn : public APawn
{
GENERATED_BODY()
GENERATED_BODY()
private:
// The virtual hand drawing settings.
UPROPERTY(EditDefaultsOnly, Category="DebugPawn",
meta=(AllowPrivateAccess="false"))
FSGDebugGizmoSettings HandDrawingSettings;
// The virtual hand drawing settings.
UPROPERTY(EditDefaultsOnly, Category="DebugPawn",
meta=(AllowPrivateAccess="false"))
FSGDebugGizmoSettings HandDrawingSettings;
public:
// Sets default values for this pawn's properties
ADebugPawn();
// Sets default values for this pawn's properties
ADebugPawn();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
private:
// The method responsible for drawing a virtual hand.
void DrawHand(EControllerHand Hand) const;
// The method responsible for drawing a virtual hand.
void DrawHand(EControllerHand Hand) const;
};
```
@@ -137,116 +137,116 @@ private:
// Sets default values
ADebugPawn::ADebugPawn()
{
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
// Set the default virtual hand drawing settings.
HandDrawingSettings = FSGDebugGizmoSettings{
1.0f,
FColor{255, 0, 0, 255},
FColor{0, 255, 0, 255},
FColor{0, 0, 255, 255},
false,
1.1f,
0,
0.2f,
};
// Set the default virtual hand drawing settings.
HandDrawingSettings = FSGDebugGizmoSettings{
1.0f,
FColor{255, 0, 0, 255},
FColor{0, 255, 0, 255},
FColor{0, 0, 255, 255},
false,
1.1f,
0,
0.2f,
};
}
// Called when the game starts or when spawned
void ADebugPawn::BeginPlay()
{
Super::BeginPlay();
Super::BeginPlay();
}
// Called every frame
void ADebugPawn::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
Super::Tick(DeltaTime);
// Attempt at drawing the left/right virtual hands every frame.
DrawHand(EControllerHand::Left);
DrawHand(EControllerHand::Right);
// Attempt at drawing the left/right virtual hands every frame.
DrawHand(EControllerHand::Left);
DrawHand(EControllerHand::Right);
}
// Called to bind functionality to input
void ADebugPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
Super::SetupPlayerInputComponent(PlayerInputComponent);
}
void ADebugPawn::DrawHand(const EControllerHand Hand) const
{
// Get the world and cache it, if it's null we return early.
UWorld* World{GetWorld()};
if (!IsValid(World))
{
return;
}
// Get the world and cache it, if it's null we return early.
UWorld* World{GetWorld()};
if (!IsValid(World))
{
return;
}
FXRMotionControllerData MotionControllerData;
const bool bGotMotionControllerData = FSGXRTracker::GetMotionControllerData(
World, Hand, MotionControllerData);
FXRMotionControllerData MotionControllerData;
const bool bGotMotionControllerData = FSGXRTracker::GetMotionControllerData(
World, Hand, MotionControllerData);
// Return if the struct data is invalid!
if (!bGotMotionControllerData || !MotionControllerData.bValid)
{
return;
}
// Return if the struct data is invalid!
if (!bGotMotionControllerData || !MotionControllerData.bValid)
{
return;
}
// Return if the device is not being tracked!
if (MotionControllerData.TrackingStatus == ETrackingStatus::NotTracked)
{
return;
}
// Return if the device is not being tracked!
if (MotionControllerData.TrackingStatus == ETrackingStatus::NotTracked)
{
return;
}
// Ensure that MotionControllerData.DeviceVisualType is a hand!
if (!ensureAlwaysMsgf(MotionControllerData.DeviceVisualType
== EXRVisualType::Hand,
TEXT("Invalid DeviceVisualType type!")))
{
}
// Ensure that MotionControllerData.DeviceVisualType is a hand!
if (!ensureAlwaysMsgf(MotionControllerData.DeviceVisualType
== EXRVisualType::Hand,
TEXT("Invalid DeviceVisualType type!")))
{
}
// Ensure that MotionControllerData.HandKeyPositions has the position data
// for 26 joints!
if (!ensureAlwaysMsgf(MotionControllerData.HandKeyPositions.Num()
== EHandKeypointCount,
TEXT("Invalid HandKeyPositions count!")))
{
return;
}
// Ensure that MotionControllerData.HandKeyPositions has the position data
// for 26 joints!
if (!ensureAlwaysMsgf(MotionControllerData.HandKeyPositions.Num()
== EHandKeypointCount,
TEXT("Invalid HandKeyPositions count!")))
{
return;
}
// Ensure that MotionControllerData.HandKeyPositions has the rotation data
// for 26 joints!
if (!ensureAlwaysMsgf(MotionControllerData.HandKeyRotations.Num()
== EHandKeypointCount,
TEXT("Invalid HandKeyRotations count!")))
{
return;
}
// Ensure that MotionControllerData.HandKeyRotations has the rotation data
// for 26 joints!
if (!ensureAlwaysMsgf(MotionControllerData.HandKeyRotations.Num()
== EHandKeypointCount,
TEXT("Invalid HandKeyRotations count!")))
{
return;
}
// Iterate over the hand joint positions and rotations!
for (int32 JointIndex = 0; JointIndex < EHandKeypointCount; ++JointIndex)
{
const FVector& JointPosition{
MotionControllerData.HandKeyPositions[JointIndex]
};
const FQuat& JointRotation{
MotionControllerData.HandKeyRotations[JointIndex]
};
// Iterate over the hand joint positions and rotations!
for (int32 JointIndex = 0; JointIndex < EHandKeypointCount; ++JointIndex)
{
const FVector& JointPosition{
MotionControllerData.HandKeyPositions[JointIndex]
};
const FQuat& JointRotation{
MotionControllerData.HandKeyRotations[JointIndex]
};
// Draw a single joint's gizmo!
// Please note that we could alternatively:
// Use FSGDebugCube::Draw() to draw a cube.
// Or use the FSGDebugVirtualHand::Draw() method and pass the
// MotionControllerData directly to draw the virtual hand
// all at once without iterating the joints. But, that's not
// goal of this tutorial.
FSGDebugGizmo::Draw(World, JointPosition, JointRotation, HandDrawingSettings);
}
// Draw a single joint's gizmo!
// Please note that we could alternatively:
// Use FSGDebugCube::Draw() to draw a cube.
// Or use the FSGDebugVirtualHand::Draw() method and pass the
// MotionControllerData directly to draw the virtual hand
// all at once without iterating the joints. But, that's not
// goal of this tutorial.
FSGDebugGizmo::Draw(World, JointPosition, JointRotation, HandDrawingSettings);
}
}
```
15. Now, rebuild the source code and go back to the `VRTemplateMap`, then use the VR Preview button to run the game. If everything's done correctly, you should be able to see the virtual hands inside your VR simulation.
![FXRMotionControllerData animated debug virtual hands](consuming-fxrmotioncontrollerdata-animated-debug-virtual-hands.gif "FXRMotionControllerData animated debug virtual hands")
![FXRMotionControllerData animated debug virtual hands](consuming-fxrmotioncontrollerdata-animated-debug-virtual-hands.gif "FXRMotionControllerData animated debug virtual hands")
@@ -5,8 +5,19 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [2.1.4] - 2024-10-22
This is a bugfix release that delivers some documentation fixes.
### Documentation
- Updated the documentation on consuming the `FXRMotionControllerData` struct.
- Additional minor documentation fixes and improvements that may not be listed here.
## [2.1.3] - 2024-10-11
This bugfix release centers on adding initial support for the upcoming Unreal Engine `5.5`.
### Added
- Added initial support for the upcoming Unreal Engine `5.5` release. Please note that, while the plugin is functional, a few adjustments are still required to address deprecation warnings. Specifically, the `FXRMotionControllerData` struct needs to be replaced with the newly introduced `FXRMotionControllerState` and `FXRHandTrackingState` structs, along with adjustments to adhere to the new hand-tracking API changes.
@@ -722,4 +733,4 @@ This is a minor release focusing on adherence to the Unreal Engine Marketplace G
### Added
- Initial public release of the SenseGlove haptic API for Unreal Engine with support for Microsoft Windows and GNU/Linux.
- Initial public release of the SenseGlove haptic API for Unreal Engine with support for Microsoft Windows and GNU/Linux.
@@ -2,10 +2,10 @@
| | **Windows (MSVC 2017)** | **Windows (MSVC 2019)** | **Windows (MSVC 2022)** | **Linux x86-64 (Native Toolchain)** | **Linux AArch64 (Native Toolchain)** | **Meta Quest Stand-alone (Android NDK)** | **HTC VIVE Stand-alone (Android NDK)** | **UE Marketplace Version** | **Azure DevOps Version** |
|:--------:|:-----------------------:|:-----------------------:|:-----------------------:|:-----------------------------------:|:------------------------------------:|:----------------------------------------:|:--------------------------------------:|:--------------------------:|:------------------------:|
| **5.5** | ❌ | ❌ | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x (r25b) | ❓ | ❌ | ✅ v2.1.3 |
| **5.4** | ❌ | ❌ | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x (r25b) | ❓ | ✅ v2.1.2 | ✅ v2.1.3 |
| **5.3** | ❌ | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x (r25b) | ❓ | ✅ v2.1.2 | ✅ v2.1.3 |
| **5.2** | ❌ | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x (r25b) | ❓ | ✅ v2.1.2 | ✅ v2.1.3 |
| **5.5** | ❌ | ❌ | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x (r25b) | ❓ | ❌ | ✅ v2.1.4 |
| **5.4** | ❌ | ❌ | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x (r25b) | ❓ | ✅ v2.1.2 | ✅ v2.1.4 |
| **5.3** | ❌ | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x (r25b) | ❓ | ✅ v2.1.2 | ✅ v2.1.4 |
| **5.2** | ❌ | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x | ✅ v2.1.x (r25b) | ❓ | ✅ v2.1.2 | ✅ v2.1.4 |
| **5.1** | ❌ | ⚠️ v2.0.x | ⚠️ v2.0.x | ⚠️ v2.0.x | ⚠️ v2.0.x | ⚠️ v2.0.x (r25b) | ❓ | ⚠️ v2.0.1 | ⚠️ v2.0.2 |
| **5.0** | ❌ | ⚠️ v1.6.x | ⚠️ v1.6.x | ⚠️ v1.6.x | ⚠️ v1.6.x | ⚠️ v1.6.x (r21e) | ❓ | ⚠️ v1.6.1 | ⚠️ v1.6.1 |
| **4.27** | ⚠️ v1.4.x | ⚠️ v1.4.x | ⚠️ v1.4.x | ⚠️ v1.4.x | ⚠️ v1.4.x | ⚠️ v1.4.x (r21e) | ❓ | ⚠️ v1.3.1 | ⚠️ v1.4.3 |
+1 -1
View File
@@ -1,7 +1,7 @@
{
"FileVersion": 3,
"Version": 1,
"VersionName": "2.1.3",
"VersionName": "2.1.4",
"FriendlyName": "SenseGlove",
"Description": "Integrating the SenseGlove haptic controller into Unreal Engine",
"Category": "Virtual Reality",