1. 程式人生 > >3dContactPointAnnotationTool開發日誌(十)

3dContactPointAnnotationTool開發日誌(十)

  要是那幾個狀態列不能拖動的話豈不是顯得太呆板了,於是我又參考Unity官方視訊教程學習瞭如何實現拖動狀態列的功能,還挺簡單的。
  比如說要拖動這個PanelStatus面板,我只讓使用者通過拖動其Text元件來實現拖動整個面板移動的效果。
0.png
  只要為其Text繫結一個DragPanel.cs指令碼,程式碼如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class DragPanel : MonoBehaviour, IPointerDownHandler, IDragHandler
{
    private Vector2 pointerOffset;
    private RectTransform rectTransformCanvas;
    private RectTransform rectTransformPanel;
    void Awake()
    {
        rectTransformCanvas = GetComponentInParent<Canvas>().transform as RectTransform;
        rectTransformPanel = transform.parent as RectTransform;
    }
    public void OnPointerDown(PointerEventData data)
    {
        rectTransformPanel.SetAsLastSibling();//把該元件放到UI最前面
        RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransformPanel,data.position,data.pressEventCamera,out pointerOffset);        
    }

    public void OnDrag(PointerEventData data)
    {
        Vector2 localPointerPosition;
        if (RectTransformUtility.ScreenPointToLocalPointInRectangle(
            rectTransformCanvas,data.position,data.pressEventCamera,out localPointerPosition))
        {
            rectTransformPanel.localPosition = localPointerPosition - pointerOffset;
        }
    }

}

  大概意思就是在OnPointerDown裡獲取按下滑鼠時滑鼠指標相對於panel的位置pointerOffset,在OnDrag中獲取滑鼠指標相對於canvas的位置localPointerPosition,然後localPointerPosition - pointerOffset就是panel的位置了。
  固定位置的元件可以被拖動了,效果如下:
1.png
  有時候可能還想將這些面板給隱藏起來,於是又添加了三個按鈕來控制這三個面板是否顯示。直接呼叫控制物件的setActive即可,程式碼如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class ButtonPanelControllerOnClick : MonoBehaviour {
    public GameObject panel;//對應的面板
    private bool active;//對應的面板是否被啟用
    private void Start()
    {
        active = true;
        panel.SetActive(active);
        GetComponent<Image>().color = Color.cyan;
    }
    public void OnClick()
    {
        active=!active;
        if (active)
        {
            GetComponent<Image>().color = Color.cyan;
        }
        else {
            GetComponent<Image>().color = Color.white;
        }
        panel.SetActive(active);
    }
}

  效果如下,還挺好玩的:
2.png
3.png
  由於之前的程式碼裡用到了FindWithTag函式,然而這個函式是找不到active為false的物件的。為了避免這種尷尬情況,我又建立了一個ObjManager物件來管理那些需要被查詢的物件,將它們丟到ObjManager的指令碼中存起來,以後誰要取就直接從這個指令碼例項中拿就好了。
4.png