3dContactPointAnnotationTool開發日誌(十)
阿新 • • 發佈:2018-11-17
要是那幾個狀態列不能拖動的話豈不是顯得太呆板了,於是我又參考Unity官方視訊教程學習瞭如何實現拖動狀態列的功能,還挺簡單的。
比如說要拖動這個PanelStatus面板,我只讓使用者通過拖動其Text元件來實現拖動整個面板移動的效果。
只要為其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的位置了。
固定位置的元件可以被拖動了,效果如下:
有時候可能還想將這些面板給隱藏起來,於是又添加了三個按鈕來控制這三個面板是否顯示。直接呼叫控制物件的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); } }
效果如下,還挺好玩的:
由於之前的程式碼裡用到了FindWithTag函式,然而這個函式是找不到active為false的物件的。為了避免這種尷尬情況,我又建立了一個ObjManager物件來管理那些需要被查詢的物件,將它們丟到ObjManager的指令碼中存起來,以後誰要取就直接從這個指令碼例項中拿就好了。