第一种方式:
1.新建一个空对象,KinectController,添加Demo包里自带的两个脚本 KinectManager.cs,InteractionManager.cs,如图所示设置
Gui Hand Cursor 鼠标样式图片:
Gui Hand Cursor 增加握拳识别进度,下面添加一个对象,添加组件Image,把圆圈的图片放进去,额 什么图片都行,好看就行:
Grip Hand Texture:握拳时显示的图片
Release Hand Texture: 张开手时显示的图片
Normal Hand Texture: 不做任何操作时显示的图片
2. 新建一个Button 添加点击事件
我的代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UguiTest : MonoBehaviour {
// Use this for initialization
void Start () {
transform.GetComponent
效果如下:
第二种方式:通过将人的手骨骼点的坐标转换成UGUI坐标,再执行判断逻辑
注意点:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
///
/// 用Kinect实现UI的点击:追踪左手手掌,移动到UI矩形内握拳表示点击该按钮。
///
public class UIClick : MonoBehaviour {
public Canvas canvas;
public Image leftHandImage; // 表示左手
public Image btnImage; // 要被点击的UI控件
KinectManager _manager;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
if (_manager == null)
{
_manager = KinectManager.Instance;
}
// 是否初始化完成
if (_manager && _manager.IsInitialized())
{
// 是否人物被检测到
if (_manager.IsUserDetected())
{
// 获取用户ID
long userId = _manager.GetPrimaryUserID();
// 获取目标关节点的索引(以左手为例)
int jointIndex = (int)KinectInterop.JointType.HandLeft;
// 判断目标关节点是否被追踪
if (_manager.IsJointTracked(userId, jointIndex))
{
// 获取目标关节点在Kinect坐标系(世界坐标)的位置
Vector3 leftHandPos = _manager.GetJointKinectPosition(userId, jointIndex);
// 左手的世界坐标 --> 屏幕坐标
Vector3 leftHandScreenPos = Camera.main.WorldToScreenPoint(leftHandPos);
Vector2 leftHandScreenPosTemp = new Vector2(leftHandScreenPos.x, leftHandScreenPos.y); // 降维
// 判断左手的UGUI坐标是否在Canvas所表示的矩形内
Vector2 leftHandUguiPos;
if (RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)canvas.transform, leftHandScreenPosTemp, null, out leftHandUguiPos))
{
RectTransform leftHandRTF = rightHandImage.transform as RectTransform;
// 屏幕坐标 --> UGUI坐标
leftHandRTF.anchoredPosition = leftHandUguiPos;
}
// 判断左手的UGUI坐标是否在Button所表示的矩形内
if (RectTransformUtility.RectangleContainsScreenPoint(btnImage.rectTransform, leftHandScreenPosTemp, null))
{
Debug.Log("在按钮中");
// 获取左手的手势状态
KinectInterop.HandState leftHandState = _manager.GetLeftHandState(userId);
if (leftHandState == KinectInterop.HandState.Closed)
{
Debug.Log("左手握拳");
// todo:点击按钮触发的事件
}
}
else
{
Debug.Log("在按钮外");
}
}
}
}
}
}
基本思路是:
1、先判断是否检测到玩家
2、是否检测到对应玩家的对应关节点
3、该关节点的左边转换为当前屏幕坐标
4、判断该屏幕坐标在不在某个按钮或者图片中
但是,需要注意的是:场景中的Main Camera需要设置成Perspective,然后角度大约50-60度
网上有个 Kinect 切水果的视频,Kinect体感切水果游戏开发,链接地址为:http://www.maiziedu.com/course/525/
参考一下里面教程的坐标转换的代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class lesson16 : MonoBehaviour {
public Canvas canvas;
public Image rightHand;
public Sprite[] handStateSprites;
public Image btn1;
public Image btn2;
public Image btn3;
public Image circle1;
public Image circle2;
public Image circle3;
public int upForce = 8000;
public int gravityScale = 10;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
//print ("dw = "+KinectManager.Instance.GetDepthImageWidth() + "dy = " + KinectManager.Instance.GetDepthImageHeight());
if (KinectManager.Instance.IsUserDetected ())
{
//jian ce 到玩家
long userId = KinectManager.Instance.GetPrimaryUserID ();
int jointType = (int)KinectInterop.JointType.HandRight;//表示右手
if(KinectManager.Instance.IsJointTracked(userId,jointType))
{
//关jie点被追踪到
Vector3 handPos =KinectManager.Instance.GetJointKinectPosition(userId, jointType);
Vector3 handScreenPosV3 = Camera.main.WorldToScreenPoint (handPos);
Vector2 handSenPos = new Vector2 (handScreenPosV3.x, handScreenPosV3.y);
Vector2 uguiPos;
//zhi xing 屏幕 zuo biao 到 UGUI zuo biao 的 zhuan huan
bool changeSuccess = RectTransformUtility.ScreenPointToLocalPointInRectangle ((RectTransform)canvas.transform, handSenPos, Camera.main, out uguiPos);
if (changeSuccess)
{
//表示右手在canvas所表示的矩形范wei内
RectTransform rightRectTf = rightHand.transform as RectTransform;
rightRectTf.anchoredPosition = uguiPos;//Update the image of right hand
}
bool isHandClose = false;
rightHand.sprite = handStateSprites [0];
KinectInterop.HandState rightHandState = KinectManager.Instance.GetRightHandState (userId);
if (rightHandState == KinectInterop.HandState.Closed)
{
isHandClose = true;
rightHand.sprite = handStateSprites [1];
}
if(isHandClose == true)
{ //has handclosed, judge whether over the btns
if (RectTransformUtility.RectangleContainsScreenPoint (circle1.rectTransform, handSenPos, Camera.main) && circle1.enabled == true)
{
//over but1
handClickFruit(btn1);
print ("1");
}
else if (RectTransformUtility.RectangleContainsScreenPoint (circle2.rectTransform, handSenPos, Camera.main) && circle2.enabled == true)
{
//over but2
handClickFruit(btn2);
print ("2");
}
else if (RectTransformUtility.RectangleContainsScreenPoint (circle3.rectTransform, handSenPos, Camera.main) && circle3.enabled == true)
{
//over but3
handClickFruit(btn3);
print ("3");
}
}
}
}
}
private void handClickFruit(Image clickFruit)
{
Rigidbody2D r1 = btn1.GetComponent ();
Rigidbody2D r2 = btn2.GetComponent ();
Rigidbody2D r3 = btn3.GetComponent ();
if (clickFruit == btn1)
{
r1.AddForce (new Vector2 (0,upForce));
}
else if(clickFruit == btn2)
{
r2.AddForce (new Vector2 (0,upForce));
}
else if(clickFruit == btn3)
{
r3.AddForce (new Vector2 (0,upForce));
}
r1.gravityScale = gravityScale;
r2.gravityScale = gravityScale;
r3.gravityScale = gravityScale;
circle1.enabled = false;
circle2.enabled = false;
circle3.enabled = false;
}
}