基礎:添加KinectManager 組件
1)局部關節獲取(參考插件場景KinectOverlayDemo1)
要獲取局部某一關節及其位置,添加腳本JointOverlayer即可,通過Tracked joint參數可以分別獲取到相關關節位置以及坐標。
2)所有關節獲取(參考插件場景KinectOverlayDemo2)
獲取所有關節,可用腳本SkeletonOverlayer
也可參考如下代碼
/// <summary> /// 通過index獲取用戶的關節,並在每個關節點放置cube /// </summary> /// <param name="index"></param> private void GetBodyJoints(int index) { if(GetDetected()) { long userId = kinectManger.GetUserIdByIndex(index); int jointsCount = kinectManger.GetJointCount(); if(!isJointsCreated) { for (int i = 0; i < jointsCount; i++) { joints.Add(Instantiate(jointGo)); } isJointsCreated = true; } else { for (int i = 0; i < jointsCount; i++) { joints[i].transform.position = kinectManger.GetJointKinectPosition(userId,i); joints[i].name = i.ToString(); } } } }
3)交互功能(參考插件場景KinectOverlayDemo3)
交互功能即為通過手勢實現鼠標點擊功能需要InteractionManager以及HandOverlayer腳本,通過HandOverlayer/InteractionManager腳本上的參數帶texture的參數來實現抓取松開等樣式
如果要把手的位置反應到UI上則需要特殊處理,因為我們獲取的手的坐標單位為米,反應到unity中只是為數字(比如左手移動0.2m),但是如果分辨率為1920X1080,則手的移動0.2相對於分辨率來說幾乎為零,所以需要通過UICamera.ViewportToWorldPoint來轉化一下(或者 UICamera.ViewportToScreenPoint)下述腳本為在JointOverlayer中修改的update部分,通過獲取手移動的box(范圍),然后通過手實際位置轉換成相對坐標,然后轉化到實際分辨率下的位置。
void Update () { KinectManager manager = KinectManager.Instance; if(manager && manager.IsInitialized() && foregroundCamera) { //backgroundImage.renderer.material.mainTexture = manager.GetUsersClrTex(); if(backgroundImage && (backgroundImage.texture == null)) { backgroundImage.texture = manager.GetUsersClrTex(); } // get the background rectangle (use the portrait background, if available) Rect backgroundRect = foregroundCamera.pixelRect; PortraitBackground portraitBack = PortraitBackground.Instance; if(portraitBack && portraitBack.enabled) { backgroundRect = portraitBack.GetBackgroundRect(); } // overlay the joint int iJointIndex = (int)trackedJoint; if (manager.IsUserDetected()) { for (int i = 0; i < 6; i++) { long userId = manager.GetUserIdByIndex(i); //manager.IsUserTracked(userId); if (manager.IsJointTracked(userId, iJointIndex)) { //MainFunController.theController.OnDebug("Joint tracked\r\n" + GetPara(manager)); overlayObject.gameObject.SetActive(true); Vector3 rightIboxRightBotBack = Vector3.zero, rightIboxRightTopFront = Vector3.zero, rightHandScreenPos = Vector3.zero; bool isrightIboxValid = false; isrightIboxValid = manager.GetRightHandInteractionBox(userId, ref rightIboxRightBotBack, ref rightIboxRightTopFront, isrightIboxValid); if (isrightIboxValid && manager.GetJointTrackingState(userId, (int)KinectInterop.JointType.HandRight) != KinectInterop.TrackingState.NotTracked) { Vector3 rightHandPos = manager.GetJointPosition(userId, (int)KinectInterop.JointType.HandRight); rightHandScreenPos.x = Mathf.Clamp01((rightHandPos.x - rightIboxRightBotBack.x) / (rightIboxRightTopFront.x - rightIboxRightBotBack.x)); rightHandScreenPos.y = Mathf.Clamp01((rightHandPos.y - rightIboxRightBotBack.y) / (rightIboxRightTopFront.y - rightIboxRightBotBack.y)); rightHandScreenPos.z = Mathf.Clamp01((rightIboxRightBotBack.z - rightHandPos.z) / (rightIboxRightBotBack.z - rightIboxRightTopFront.z)); } Vector3 cursorTargetPos = UICamera.ViewportToWorldPoint(rightHandScreenPos); overlayObject.position = Vector2.Lerp(overlayObject.position, cursorTargetPos, 1f); break; } else { overlayObject.gameObject.SetActive(false); //MainFunController.theController.OnDebug("Joint miss"); //isFirstCatch = true; //CollisionEvent.theEvent.OnStop(); } } } else { //debugText.text = "body miss"; } } }
注:應用時建議復制此腳本,並修改名稱,然后做自己的修改