• UnityLeapMotion流程记录


    突然接到一个LeapMotion的项目,回想起上次做LeapMotion还是在几年前,但是当时没有去记录,所以这次就相当于是重新走了一遍流程。很苦恼,赶紧记录下来。防止之后忘记。这次的需求还是比较简单的,用手滑动控制图片序列播放。

    准备

    • Unity版本2021.3.19f1c1
    • LeapMotion一台

    开始接入

    Downloads – Page Array – Ultraleap

    首先来到官网下载LeapMotion的必备组件

    选择对应的设备,我这台设备是比较旧的。

    无脑安装

    安装好后还需要来到github页面下载unity-leapmotion的插件

    https://github.com/ultraleap/UnityPlugin

    然后导入到unity工程中

    导入后找到Capsule Hands场景就是官方的示例

    针对需求查看了官网文档。有两种想法:

    1. 通过XRXRI and XRHands Integration - Ultraleap documentation

    去用手滑动UI。

    1. 获取手部追踪数据,用程序去判断,得到值,然后去改变视频的帧。

    最终选择了第二种方法,觉得第二种比较简单。

    创建HandControl.cs脚本

    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Leap;
    5. using Leap.Unity;
    6. public class HandControl : MonoBehaviour
    7. {
    8. public static bool Gesture_left = false;
    9. public static bool Gesture_right = false;
    10. public static bool Gesture_up = false;
    11. public static bool Gesture_down = false;
    12. public static bool Gesture_zoom = false;
    13. public static float movePOs = 0.0f;
    14. private LeapProvider mProvider;
    15. private Frame mFrame;
    16. private Hand mHand;
    17. public ImageSwitcher imageSwitcher;
    18. private Vector3 leftPosition;
    19. private Vector3 rightPosition;
    20. public static float zoom = 1.0f;
    21. [Tooltip("Velocity (m/s) of Palm ")]
    22. public float smallestVelocity = 1.45f;//手掌移动的最小速度
    23. [Tooltip("Velocity (m/s) of Single Direction ")]
    24. [Range(0, 1)]
    25. public float deltaVelocity = 1.0f;//单方向上手掌移动的速度
    26. // Use this for initialization
    27. void Start()
    28. {
    29. mProvider = FindObjectOfType<LeapProvider>() as LeapProvider;
    30. }
    31. // Update is called once per frame
    32. void Update()
    33. {
    34. mFrame = mProvider.CurrentFrame;//获取当前帧
    35. //获得手的个数
    36. //print ("hand num are " + mFrame.Hands.Count);
    37. if (mFrame.Hands.Count > 0)
    38. {
    39. if (mFrame.Hands.Count == 2)
    40. zoom = CalcuateDistance(mFrame);
    41. if (mFrame.Hands.Count == 1)
    42. LRUDGestures(mFrame, ref movePOs);
    43. }
    44. }
    45. float CalcuateDistance(Frame mFrame)
    46. {
    47. Gesture_zoom = true;
    48. Gesture_left = false;
    49. Gesture_right = false;
    50. float distance = 0f;
    51. //print ("Two hands");
    52. foreach (var itemHands in mFrame.Hands)
    53. {
    54. if (itemHands.IsLeft)
    55. {
    56. leftPosition = itemHands.PalmPosition;
    57. //print ("leftPosition" + leftPosition);
    58. }
    59. if (itemHands.IsRight)
    60. {
    61. rightPosition = itemHands.PalmPosition;
    62. //print ("rightPosition" + rightPosition);
    63. }
    64. }
    65. if (leftPosition != Vector3.zero && rightPosition != Vector3.zero)
    66. {
    67. Vector3 leftPos = new Vector3(leftPosition.x, leftPosition.y, leftPosition.z);
    68. Vector3 rightPos = new Vector3(rightPosition.x, rightPosition.y, rightPosition.z);
    69. distance = 10 * Vector3.Distance(leftPos, rightPos);
    70. //print("distance" + distance);
    71. }
    72. if (distance != 0)
    73. return distance;
    74. else
    75. return distance = 1;
    76. }
    77. void LRUDGestures(Frame mFrame, ref float movePOs)
    78. {
    79. Gesture_zoom = false;
    80. foreach (var item in mFrame.Hands)
    81. {
    82. int numFinger = item.Fingers.Count;
    83. //print ("item is " + numFinger);
    84. //print("hand are " + isOpenFullHand (item));
    85. // print ("isOpenFullHands is " + isOpenFullHands(item));
    86. if (item.GrabStrength == 1)
    87. {
    88. }
    89. else if (item.GrabStrength == 0)
    90. {
    91. //print ("num is 5, open your hand");
    92. //print("PalmVelocity" + item.PalmVelocity);
    93. //print("PalmPosition" + item.PalmPosition);
    94. movePOs = item.PalmPosition.x;
    95. if (isMoveLeft(item))
    96. {
    97. Gesture_left = true;
    98. Gesture_right = false;
    99. //print("move left");
    100. }
    101. else if (isMoveRight(item))
    102. {
    103. Gesture_left = false;
    104. Gesture_right = true;
    105. //print("move Right");
    106. }
    107. else if (isMoveUp(item))
    108. {
    109. Gesture_left = false;
    110. Gesture_right = false;
    111. print("move Up");
    112. imageSwitcher.PreviousImage();
    113. }
    114. else if (isMoveDown(item))
    115. {
    116. Gesture_left = false;
    117. Gesture_right = false;
    118. print("move Down");
    119. imageSwitcher.NextImage();
    120. }
    121. else if (isMoveForward(item))
    122. {
    123. Gesture_left = false;
    124. Gesture_right = false;
    125. print("move Forward");
    126. imageSwitcher.PreviousImage();
    127. }
    128. else if (isMoveBack(item))
    129. {
    130. Gesture_left = false;
    131. Gesture_right = false;
    132. print("move back");
    133. imageSwitcher.NextImage();
    134. }
    135. }
    136. }
    137. }
    138. private bool isStone(Hand hand)
    139. {
    140. //print ("hand.GrabAngle" + hand.GrabAngle);
    141. return hand.GrabStrength > 2.0f;
    142. }
    143. //是否抓取
    144. public bool isGrabHand(Hand hand)
    145. {
    146. return hand.GrabStrength > 0.8f; //抓取力
    147. }
    148. //hand move four direction
    149. public bool isMoveRight(Hand hand)
    150. {
    151. return hand.PalmVelocity.x > deltaVelocity && !isStationary(hand);
    152. }
    153. // 手划向右边
    154. public bool isMoveLeft(Hand hand)
    155. {
    156. //print (hand.PalmVelocity.x );
    157. return hand.PalmVelocity.x < -deltaVelocity && !isStationary(hand);
    158. }
    159. //手向上
    160. public bool isMoveUp(Hand hand)
    161. {
    162. //print ("hand.PalmVelocity.y" + hand.PalmVelocity.y);
    163. return hand.PalmVelocity.y > deltaVelocity && !isStationary(hand);
    164. }
    165. //手向下
    166. public bool isMoveDown(Hand hand)
    167. {
    168. return hand.PalmVelocity.y < -deltaVelocity && !isStationary(hand);
    169. }
    170. //手向前
    171. public bool isMoveForward(Hand hand)
    172. {
    173. //print (hand.PalmVelocity.z);
    174. return hand.PalmVelocity.z > deltaVelocity && !isStationary(hand);
    175. }
    176. //手向后
    177. public bool isMoveBack(Hand hand)
    178. {
    179. return hand.PalmVelocity.z < -deltaVelocity && !isStationary(hand);
    180. }
    181. //固定不动的
    182. public bool isStationary(Hand hand)
    183. {
    184. return hand.PalmVelocity.magnitude < smallestVelocity; //Vector3.Magnitude返回向量的长度
    185. }
    186. }

    创建ImageSwitcher.cs脚本

    1. using UnityEngine;
    2. using UnityEngine.UI; // 引入UI命名空间
    3. public class ImageSwitcher : MonoBehaviour
    4. {
    5. public Image displayImage; // 用于显示图片的Image组件
    6. public Sprite[] images; // 存储所有图片的数组
    7. private int currentImageIndex = 0; // 当前显示的图片索引
    8. void Start()
    9. {
    10. // 初始化时显示第一张图片
    11. if (images.Length > 0)
    12. {
    13. displayImage.sprite = images[currentImageIndex];
    14. }
    15. }
    16. // 切换到下一张图片
    17. public void NextImage()
    18. {
    19. if (images.Length > 0)
    20. {
    21. currentImageIndex = (currentImageIndex + 1) % images.Length; // 使用模运算确保索引循环
    22. displayImage.sprite = images[currentImageIndex];
    23. }
    24. }
    25. // 切换到上一张图片
    26. public void PreviousImage()
    27. {
    28. if (images.Length > 0)
    29. {
    30. currentImageIndex = (currentImageIndex - 1 + images.Length) % images.Length; // 使用模运算确保索引循环
    31. displayImage.sprite = images[currentImageIndex];
    32. }
    33. }
    34. }

    将两个脚本挂载在场景中并赋值

    image switcher中的images将准备好的序列帧拖入

    创建Canvas和Image。将image拖入image Switcher中

    最终场景是这样的结构。使用的场景是官方的Capsule Hands。

    成功运行。这个项目比较简单,开发的时候也没有遇到坑,在此记录下防止后面忘了流程。

    官方文档

    Get started with our plugins for XR developers - Ultraleap documentation

  • 相关阅读:
    Win10下Hadoop3.2.1的安装与配置
    MySQL数据库 || 增删改查操作详解
    Java学习笔记(十四)
    MySQL权限
    pagehelper 分页写法
    【内网攻击】DHCP协议概念——地址池耗尽攻击
    工作中使用Redis的10种场景
    OpenMesh 网格顶点Quadric误差计算
    Git常用命令
    SWIFT:自我认知微调
  • 原文地址:https://blog.csdn.net/weixin_43935971/article/details/139360977