在做体感项目时,在边缘部分的抓取动作识别非常差
于是我做出了优化,不采用原本的映射关系:
假设原本人物站在中间,保持位置不动,右手臂向右伸直,终点为屏幕的极限位置
此时我们并不将手臂伸直的位置映射到屏幕的极限位置,而是映射到屏幕的120%处,如此一来,原设备检测的区域就变为了20%——80%之间,保证了一定的精度
Rect rectCanvas = LeftCursor.canvas.pixelRect;float xoffset = (rectCanvas.width) / 2;float yoffset = rectCanvas.height / 2;float multiple = 2f;Vector3 posSprite = new Vector2(Mathf.Clamp(multiple * (leftHandScreenPos.x * rectCanvas.width - xoffset) ,- xoffset,xoffset) , Mathf.Clamp(multiple*(leftHandScreenPos.y * rectCanvas.height - yoffset),-yoffset,yoffset) );Vector3 posSprite1 = new Vector2(Mathf.Clamp(multiple * (rightHandScreenPos.x * rectCanvas.width - xoffset), -xoffset, xoffset),Mathf.Clamp(multiple*(rightHandScreenPos.y * rectCanvas.height - yoffset),-yoffset,yoffset) );
此外,还可以使用List<Vector3>来存储历史数据,然后在每次更新时计算平均值,获得更稳定的位置更新。
// 存储关节历史数据,用于平滑private readonly Queue<Vector3> LefthandData = new Queue<Vector3>();private readonly Queue<Vector3> RighthandData = new Queue<Vector3>();/// <summary>/// 设置空间坐标/// </summary>private void ScreenSetting(){if (interactionManager!=null){leftHandScreenPos = interactionManager.GetLeftHandScreenPos();rightHandScreenPos = interactionManager.GetRightHandScreenPos();Rect rectCanvas = LeftCursor.canvas.pixelRect;float xoffset = (rectCanvas.width) / 2;float yoffset = rectCanvas.height / 2;float multiple = 2f;Vector3 posSprite = new Vector2(Mathf.Clamp(multiple * (leftHandScreenPos.x * rectCanvas.width - xoffset) ,- xoffset,xoffset) , Mathf.Clamp(multiple*(leftHandScreenPos.y * rectCanvas.height - yoffset),-yoffset,yoffset) );Vector3 posSprite1 = new Vector2(Mathf.Clamp(multiple * (rightHandScreenPos.x * rectCanvas.width - xoffset), -xoffset, xoffset),Mathf.Clamp(multiple*(rightHandScreenPos.y * rectCanvas.height - yoffset),-yoffset,yoffset) );if (!isLerp){if (LefthandData.Count < 20){LefthandData.Enqueue(posSprite);}else{LefthandData.Dequeue();LefthandData.Enqueue(posSprite);}if (RighthandData.Count < 20){RighthandData.Enqueue(posSprite1);}else{RighthandData.Dequeue();RighthandData.Enqueue(posSprite1);}LeftCursor.transform.GetComponent<RectTransform>().anchoredPosition = new Vector3(LefthandData.Average(item => item.x), LefthandData.Average(item => item.y), LefthandData.Average(item => item.z));if (BothHand){RightCursor.transform.GetComponent<RectTransform>().anchoredPosition = new Vector3(RighthandData.Average(item => item.x), RighthandData.Average(item => item.y), RighthandData.Average(item => item.z));}}else{LeftCursor.transform.GetComponent<RectTransform>().anchoredPosition = Vector3.Lerp(LeftCursor.transform.GetComponent<RectTransform>().anchoredPosition, posSprite, Time.deltaTime * 10);if (BothHand){RightCursor.transform.GetComponent<RectTransform>().anchoredPosition = Vector3.Lerp(RightCursor.transform.GetComponent<RectTransform>().anchoredPosition, posSprite1, Time.deltaTime * 10); ;}}}}