拿了Kinect的demo(场景叫KinectOverlayDemo),测试了一下。发现图片充满屏幕的时候,位置和关节能匹配。但是项目需要竖屏,也就是说屏幕不是16:9,如果还是充满,人会变形。
于是我首先想到了适配高(我把GUI Texture换成了UGUI的Raw Image,以达到适配效果)
接下来问题出现了:跟踪的屏幕上关节位置不对,上下位置能对得上,左右位置会缩小许多>_< !!!
个中细节就不多说了,直接贴出解决办法
搞定了这个问题,来不及沾沾自喜,下一个问题接踵而至——点击 ~@_@~
怎么点击UI?看了一下,里面夹带了一个MouseControl的类,其核心就是导入了Windows系统的User32.dll这个程序集
捣鼓了一天,没想出来怎么把窗口坐标转换成屏幕坐标……PS..知道的小伙伴还请分享一下方法~~~
于是,这个方法弃用 0.0
接下来,问度娘:
接下来,就是撸代码了:
using UnityEngine;
using UnityEngine.UI;
//按钮形状
public enum ButtonType
{
Circular,//圆形
Square,//矩形
Triangle,//三角形
Irregular,//不规则形状
}
//按钮锚点
public enum ButtonAnchor
{
Middle,
LeftTop,
LeftBottom,
RightTop,
RightBottom
}
public class XButtons : MonoBehaviour {
private Button btn;
private RectTransform rectTrans;
private Vector2 buttonResolution;
[SerializeField] private ButtonType btnType = ButtonType.Circular;
[SerializeField] private ButtonAnchor btnAnc = ButtonAnchor.RightTop;
// Use this for initialization
void Start () {
rectTrans = GetComponent<RectTransform>();
float xRes = rectTrans.parent.parent.GetComponent<CanvasScaler>().referenceResolution.x;
buttonResolution = new Vector2(xRes, 16.0f * xRes / 9);
}
public bool OnClick(Vector2 point,Vector2 resolution,float scale)
{
bool isClick = false;
float scaleTimes = scale / rectTrans.lossyScale.x;
Debug.Log("scaleTimes:" + scaleTimes);
point.x += resolution.x / (scaleTimes * 2.0f);
point.y += resolution.y / 2.0f;
point.y *= buttonResolution.y / resolution.y;
point.x *= buttonResolution.x * scaleTimes / resolution.x ;
if (rectTrans)
{
switch (btnType)
{
case ButtonType.Circular:
Debug.Log(string.Format("point:{0}..PosOffset():{1}..Vector2.Distance:{2}..rectTrans.rect.width / 2.0f:{3}.", point, PosOffset(), Vector2.Distance(point, PosOffset()), rectTrans.rect.width / 2.0f));
if (Vector2.Distance(point, PosOffset()) <= rectTrans.rect.width / 2.0f )
{
//响应点击
isClick = true;
//Debug.Log("Click:" + this.name);
}
break;
case ButtonType.Square:
if (CheckSquareRange(point.x, PosOffset().x, rectTrans.rect.width) &&
CheckSquareRange(point.y, PosOffset().y, rectTrans.rect.height))
{
//响应点击
isClick = true;
//Debug.Log("Click:" + this.name);
}
break;
case ButtonType.Triangle:
break;
case ButtonType.Irregular:
break;
}
}
return isClick;
}
Vector2 PosOffset()
{
Vector2 offsetVec = Vector2.zero;
Debug.Log("buttonResolution:::" + buttonResolution);
switch (btnAnc)
{
case ButtonAnchor.Middle:
break;
case ButtonAnchor.LeftTop:
offsetVec = new Vector2(0, -buttonResolution.y);
break;
case ButtonAnchor.LeftBottom:
offsetVec = new Vector2(0, 0);
break;
case ButtonAnchor.RightTop:
offsetVec = new Vector2(-buttonResolution.x, -buttonResolution.y);
break;
case ButtonAnchor.RightBottom:
offsetVec = new Vector2(-buttonResolution.x, 0);
break;
}
return (rectTrans.anchoredPosition - offsetVec);
}
bool CheckSquareRange(float f1,float f2,float range)
{
bool isInRange = false;
if (Mathf.Abs(f1 - f2) <= range / 2.0f)
{
isInRange = true;
}
return isInRange;
}
}
//外部调用
foreach (XButtons btn in buttons)
{
Vector2 resolution = cursorIcon.parent.GetComponent<CanvasScaler>().referenceResolution;
float scale = cursorIcon.lossyScale.x;
if (btn.OnClick(cursorIcon.anchoredPosition, resolution,scale))
{
Debug.Log(btn.name + ": Click");
float c = Random.Range(0, 1.0f);
btn.GetComponent<Image>().color = new Color(c, c, c);
}
}