获取点击位置的相对位置
采用
RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, Input.mousePosition, canvas.worldCamera, out pos)方法。
- RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, Input.mousePosition, canvas.worldCamera, out pos)
判断鼠标点击位置在不在UI画布内,并返回点击的位置 - rectTransform:画布的位置属性
- Input.mousePosition:鼠标点击的屏幕位置
- canvas.worldCamera:画布的相机
- out pos:pos为返回鼠标点击位置,out代表将此数据输出(默认返回为bool类型,out 语句表示额外返回该值),且返回的pos位置即为该UI摄像机下的相对位置,在实际的使用过程中还需要进一步的转换坐标系。
#region 返回鼠标点击的位置-Vector2 ReturnMouseDownPos()
private Vector2 ReturnMouseDownPos() {
Vector2 pos;
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, Input.mousePosition, canvas.worldCamera, out pos))
//if语句判断的是bool返回值,而真正要获取的是点击的位置信息。
{
return pos;
}
else {
return pos;
}
}
#endregion
通过获得的点击位置来计算距离摇杆中心的距离
鼠标点到中心点的相对位置
pos是以canvas为基准的坐标系,该代码将坐标系转换为了以Point中心为基准的
Vector2 relativePos = new Vector2((pos.x - this.transform.localPosition.x), (pos.y - this.transform.localPosition.y));
- 由于虚拟摇杆的中心点位置也是以canvas为基准坐标系的,所以通过将相应坐标相减,使得点击位置的坐标转换为以虚拟摇杆中心点为(0,0)点的坐标,方便计算距离。
计算鼠标点击处与中心点的距离
float distance = Mathf.Sqrt((relativePos.x*relativePos.x) + (relativePos.y*relativePos.y));
使用直角三角形边长计算公式
Mathf.Sqrt()方法代表根号。
根据距离的不同采取不同的反馈
1、 距离小于30像素,移动虚拟摇杆
if (distance <= 30f)
{
//缩起控制按钮,开始跟随鼠标移动
Narrow(ControlPanel);//缩小虚拟摇杆底盘
isFollowMouse = true;//开启移动模式
}
2、距离大于30像素,改变方向
分别通过判断x和y的正负号,来确定移动的方向,并且修改方向属性。
if (Mathf.Abs(relativePos.x) >= Mathf.Abs(relativePos.y))
{
if (relativePos.x >= 0)
{
heroDistance = HeroDistance.Right;
UpdateCountrolDirection();
}
else
{
heroDistance = HeroDistance.Left;
UpdateCountrolDirection();
}
}
else
{
if (relativePos.y >= 0)
{
heroDistance = HeroDistance.Top;
UpdateCountrolDirection();
}
else
{
heroDistance = HeroDistance.Bottom;
UpdateCountrolDirection();
}
}
根据移动方向改变控件的显示和运动方向
检测对象属性的变化,根据实际的要求进行相应的反馈。
#region 根据移动方向改变控件的显示和运动方向-UpdateCountrolDirection()
private void UpdateCountrolDirection() {
if (!isFollowMouse && GameControl._instance.gameState == GameControl.GameState.Playing) {
if (heroDistance == HeroDistance.None)
{
for (int i = 0; i < ControlDirection.Length; i++)
{
ControlDirection[i].SetActive(false);
}
GameControl._instance.direction = GameControl.Direction.None;
}
else if (heroDistance == HeroDistance.Top)
{
//判断如果与现在的方向完全相反,将不起作用
if (GameControl._instance.direction != GameControl.Direction.Bottom) {
for (int i = 0; i < ControlDirection.Length; i++)
{
ControlDirection[i].SetActive(false);
}
ControlDirection[0].SetActive(true);
GameControl._instance.direction = GameControl.Direction.Top;
}
}
else if (heroDistance == HeroDistance.Bottom)
{
//判断如果与现在的方向完全相反,将不起作用
if (GameControl._instance.direction != GameControl.Direction.Top) {
for (int i = 0; i < ControlDirection.Length; i++)
{
ControlDirection[i].SetActive(false);
}
ControlDirection[1].SetActive(true);
GameControl._instance.direction = GameControl.Direction.Bottom;
}
}
else if (heroDistance == HeroDistance.Left)
{
//判断如果与现在的方向完全相反,将不起作用
if (GameControl._instance.direction != GameControl.Direction.Right) {
for (int i = 0; i < ControlDirection.Length; i++)
{
ControlDirection[i].SetActive(false);
}
ControlDirection[2].SetActive(true);
GameControl._instance.direction = GameControl.Direction.Left;
}
}
else if (heroDistance == HeroDistance.Right)
{
//判断如果与现在的方向完全相反,将不起作用
if (GameControl._instance.direction != GameControl.Direction.Left) {
for (int i = 0; i < ControlDirection.Length; i++)
{
ControlDirection[i].SetActive(false);
}
ControlDirection[3].SetActive(true);
GameControl._instance.direction = GameControl.Direction.Right;
}
}
}
}
#endregion