1. 程式人生 > >Unity 判斷 滑鼠/觸控 位置是否在指定Ui上,非射線檢測方式。觸屏移動物體。

Unity 判斷 滑鼠/觸控 位置是否在指定Ui上,非射線檢測方式。觸屏移動物體。

事出有因:
1.專案的觸控點選事件,並且有手指縮放/移動功能。
2.unity本身支援touch功能,這個不多說。
3.當做手指縮放/移動的時候就要判斷touch點位置了,但是如果不加任何判斷則會亂套。
如:本來想移動A(讓A跟隨 手指touch 的座標就行了),但是如果我在B區域觸控並移動手指,A也會跟隨移動,這樣就不對了。應該是在A所在的區域才有效,才能移動。

解決方法
way1:A物體新增碰撞,滑鼠/觸控點的位置發射射線,檢測是否碰撞到A上的碰撞體,進而移動。此方法簡單,但麻煩。
way2:
首先看一下螢幕座標的關係:
草圖奉上:
螢幕座標系
1.獲取ui的長、寬:m_ui.GetComponent<RectTransform>().rect.width/m_uiGetComponent<RectTransform>().rect.height


2.ui座標轉螢幕座標:Vector2 pos2D; pos2D = Camera.main.WorldToScreenPoint(m_ui.localPosition);,得到對應的螢幕座標點。
3.判斷 滑鼠/觸控 位置是否在ABCD的區域內即可。

上程式碼

    void Update()
    {
        Debug.Log(IsTouchInUi(Input.mousePosition) ? "在地圖上" : "不在上面");//滑鼠
        if (Input.touchCount>0)
            Debug.Log(IsTouchInUi(Input.GetTouch(0).deltaPosition) ? "在地圖上" : "不在上面");//觸屏
        if(Input.GetTouch(0).deltaPosition)
        {
        	//單指觸屏移動
        	if (Input.touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Moved)
        	{
        		Vector3 touchDeltaPosition = Input.GetTouch(0).deltaPosition;
        		_map.Translate(touchDeltaPosition.x * 5, -touchDeltaPosition.y * 5, 0);
        	}
        }
    }
    /// <summary>
    /// 獲取ui的螢幕座標
    /// </summary>
    /// <param name="trans">UI物體</param>
    /// <returns></returns>
    Vector3 GetUiToScreenPos(Transform trans)
    {
        _mapWidth = trans.GetComponent<RectTransform>().rect.width;//獲取ui的實際寬度
        _mapHight = trans.GetComponent<RectTransform>().rect.height;//長度
        Vector2 pos2D;
        pos2D = Camera.main.WorldToScreenPoint(trans.localPosition);
        Vector3 newPos = new Vector3(pos2D.x, pos2D.y, 0);
        return newPos;
    }
    /// <summary>
    /// 判斷是否在ui上
    /// </summary>
    /// <param name="pos">輸入的座標資訊</param>
    /// <returns></returns>
    bool IsTouchInUi(Vector3 pos)
    {
        bool isInRect = false;
        Vector3 newPos = GetUiToScreenPos(_map);
        if (Input.mousePosition.x < (newPos.x+_mapWidth/2) && Input.mousePosition.x > (newPos.x-_mapWidth/2) && 
            Input.mousePosition.y < (newPos.y+_mapHight/2) && Input.mousePosition.y > (newPos.y-_mapHight/2))
        {
            isInRect = true;
        }
        return isInRect;
    }

Over