UGUI 学习

1. Grid Layout Group(网格布局)

  Hierachy:

     

  Game:

  属性和功能:

  

2. 根据鼠标位置旋转界面实现:

 1 public class TiltWindow : MonoBehaviour
 2 {
 3     public Vector2 range = new Vector2(5f, 3f);
 4 
 5     Transform mTrans;
 6     Quaternion mStart;
 7     Vector2 mRot = Vector2.zero;
 8 
 9     void Start ()
10     {
11         mTrans = transform;
12         mStart = mTrans.localRotation;
13     }
14 
15     void Update ()
16     {
17         Vector3 pos = Input.mousePosition;
18 
19         float halfWidth = Screen.width * 0.5f;
20         float halfHeight = Screen.height * 0.5f;
21         float x = Mathf.Clamp((pos.x - halfWidth) / halfWidth, -1f, 1f);
22         float y = Mathf.Clamp((pos.y - halfHeight) / halfHeight, -1f, 1f);
23         mRot = Vector2.Lerp(mRot, new Vector2(x, y), Time.deltaTime * 5f);
24 
25         mTrans.localRotation = mStart * Quaternion.Euler(-mRot.y * range.y, mRot.x * range.x, 0f);
26     }
27 }

   

3. 按钮动画实现:

  修改 Transisition 为 Animation,设置触发器

 

  在 Animator 设计状态机

 

 

4. HorizontalLayoutGroup(垂直布局)

  Hierachy:

 

  Game:

 

  属性和功能:

 

 5. 拖拽功能实现

   Hierarchy(其中 Panel 中 Image 绑定 DragMe,Panel2,Panel3 中 Image 绑定 DropMe):

 1 public class DragMe : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
 2 {
 3     public bool dragOnSurfaces = true;
 4     
 5     private Dictionary<int,GameObject> m_DraggingIcons = new Dictionary<int, GameObject>();
 6     private Dictionary<int, RectTransform> m_DraggingPlanes = new Dictionary<int, RectTransform>();
 7 
 8     // 开始拖拽
 9     // 创建拖拽图片的 clone 体
10     public void OnBeginDrag(PointerEventData eventData)
11     {
12         var canvas = FindInParents<Canvas>(gameObject);
13         if (canvas == null)
14             return;
15 
16         // We have clicked something that can be dragged.
17         // What we want to do is create an icon for this.
18         m_DraggingIcons[eventData.pointerId] = new GameObject("icon");
19 
20         m_DraggingIcons[eventData.pointerId].transform.SetParent (canvas.transform, false);
21         m_DraggingIcons[eventData.pointerId].transform.SetAsLastSibling();
22         
23         var image = m_DraggingIcons[eventData.pointerId].AddComponent<Image>();
24         // The icon will be under the cursor.
25         // We want it to be ignored by the event system.
26         var group = m_DraggingIcons[eventData.pointerId].AddComponent<CanvasGroup>();
27         group.blocksRaycasts = false;
28 
29         image.sprite = GetComponent<Image>().sprite;
30         image.SetNativeSize();
31         
32         if (dragOnSurfaces)
33             m_DraggingPlanes[eventData.pointerId] = transform as RectTransform;
34         else
35             m_DraggingPlanes[eventData.pointerId]  = canvas.transform as RectTransform;
36         
37         SetDraggedPosition(eventData);
38     }
39 
40     // 正在拖拽
41     // 更新拖拽物位置
42     public void OnDrag(PointerEventData eventData)
43     {
44         if (m_DraggingIcons[eventData.pointerId] != null)
45             SetDraggedPosition(eventData);
46     }
47 
48     // 根据鼠标位置更新拖拽物位置和旋转
49     private void SetDraggedPosition(PointerEventData eventData)
50     {
51         if (dragOnSurfaces && eventData.pointerEnter != null && eventData.pointerEnter.transform as RectTransform != null)
52             m_DraggingPlanes[eventData.pointerId] = eventData.pointerEnter.transform as RectTransform;
53         
54         var rt = m_DraggingIcons[eventData.pointerId].GetComponent<RectTransform>();
55         Vector3 globalMousePos;
56         if (RectTransformUtility.ScreenPointToWorldPointInRectangle(m_DraggingPlanes[eventData.pointerId], eventData.position, eventData.pressEventCamera, out globalMousePos))
57         {
58             rt.position = globalMousePos;
59             rt.rotation = m_DraggingPlanes[eventData.pointerId].rotation;
60         }
61     }
62 
63     // 结束拖拽
64     // 销毁克隆体
65     public void OnEndDrag(PointerEventData eventData)
66     {
67         if (m_DraggingIcons[eventData.pointerId] != null)
68             Destroy(m_DraggingIcons[eventData.pointerId]);
69 
70         m_DraggingIcons[eventData.pointerId] = null;
71     }
72 
73     // 在父亲节点中寻找 T 组件
74     static public T FindInParents<T>(GameObject go) where T : Component
75     {
76         if (go == null) return null;
77         var comp = go.GetComponent<T>();
78 
79         if (comp != null)
80             return comp;
81         
82         var t = go.transform.parent;
83         while (t != null && comp == null)
84         {
85             comp = t.gameObject.GetComponent<T>();
86             t = t.parent;
87         }
88         return comp;
89     }
90 }

 

 

 1 public class DropMe : MonoBehaviour, IDropHandler, IPointerEnterHandler, IPointerExitHandler
 2 {
 3     public Image containerImage;
 4     public Image receivingImage;
 5     private Color normalColor;
 6     public Color highlightColor = Color.yellow;
 7     
 8     public void OnEnable ()
 9     {
10         if (containerImage != null)
11             normalColor = containerImage.color;
12     }
13     
14     // 放置图片
15     public void OnDrop(PointerEventData data)
16     {
17         containerImage.color = normalColor;
18         
19         if (receivingImage == null)
20             return;
21         
22         Sprite dropSprite = GetDropSprite (data);
23         if (dropSprite != null)
24             receivingImage.overrideSprite = dropSprite;
25     }
26 
27     // 鼠标移入
28     // 背景高亮
29     public void OnPointerEnter(PointerEventData data)
30     {
31         if (containerImage == null)
32             return;
33         
34         Sprite dropSprite = GetDropSprite (data);
35         if (dropSprite != null)
36             containerImage.color = highlightColor;
37     }
38 
39     // 鼠标移出
40     public void OnPointerExit(PointerEventData data)
41     {
42         if (containerImage == null)
43             return;
44         
45         containerImage.color = normalColor;
46     }
47     
48     // 得到拖拽图片
49     private Sprite GetDropSprite(PointerEventData data)
50     {
51         var originalObj = data.pointerDrag;
52         if (originalObj == null)
53             return null;
54         
55         var dragMe = originalObj.GetComponent<DragMe>();
56         if (dragMe == null)
57             return null;
58         
59         var srcImage = originalObj.GetComponent<Image>();
60         if (srcImage == null)
61             return null;
62         
63         return srcImage.sprite;
64     }
65 }

 

 

  

 6. 拖拽改变面板位置(屏幕坐标到本地坐标的转换)

 1 public class DragPanel : MonoBehaviour, IPointerDownHandler, IDragHandler {
 2     
 3     private Vector2 originalLocalPointerPosition;
 4     private Vector3 originalPanelLocalPosition;
 5     private RectTransform panelRectTransform;
 6     private RectTransform parentRectTransform;
 7     
 8     void Awake () {
 9         panelRectTransform = transform.parent as RectTransform;
10         parentRectTransform = panelRectTransform.parent as RectTransform;
11     }
12     
13     public void OnPointerDown (PointerEventData data) {
14         originalPanelLocalPosition = panelRectTransform.localPosition;
15         // 屏幕坐标转成本地坐标
16         RectTransformUtility.ScreenPointToLocalPointInRectangle (parentRectTransform, data.position, data.pressEventCamera, out originalLocalPointerPosition);
17     }
18     
19     public void OnDrag (PointerEventData data) {
20         if (panelRectTransform == null || parentRectTransform == null)
21             return;
22         
23         Vector2 localPointerPosition;
24         if (RectTransformUtility.ScreenPointToLocalPointInRectangle (parentRectTransform, data.position, data.pressEventCamera, out localPointerPosition)) {
25             Vector3 offsetToOriginal = localPointerPosition - originalLocalPointerPosition;
26             panelRectTransform.localPosition = originalPanelLocalPosition + offsetToOriginal;
27         }
28         
29         ClampToWindow ();
30     }
31     
32     // 将面板限制在父组件之内
33     // Clamp panel to area of parent
34     void ClampToWindow () {
35         Vector3 pos = panelRectTransform.localPosition;
36         
37         Vector3 minPosition = parentRectTransform.rect.min - panelRectTransform.rect.min;
38         Vector3 maxPosition = parentRectTransform.rect.max - panelRectTransform.rect.max;
39         
40         pos.x = Mathf.Clamp (panelRectTransform.localPosition.x, minPosition.x, maxPosition.x);
41         pos.y = Mathf.Clamp (panelRectTransform.localPosition.y, minPosition.y, maxPosition.y);
42         
43         panelRectTransform.localPosition = pos;
44     }
45 }

 

 

 7. 拖拽改变面板大小

 1 public class ResizePanel : MonoBehaviour, IPointerDownHandler, IDragHandler {
 2     
 3     public Vector2 minSize = new Vector2 (100, 100);
 4     public Vector2 maxSize = new Vector2 (400, 400);
 5     
 6     private RectTransform panelRectTransform;
 7     private Vector2 originalLocalPointerPosition;
 8     private Vector2 originalSizeDelta;
 9     
10     void Awake () {
11         panelRectTransform = transform.parent.GetComponent<RectTransform> ();
12     }
13     
14     public void OnPointerDown (PointerEventData data) {
15         originalSizeDelta = panelRectTransform.sizeDelta;
16         RectTransformUtility.ScreenPointToLocalPointInRectangle (panelRectTransform, data.position, data.pressEventCamera, out originalLocalPointerPosition);
17     }
18     
19     public void OnDrag (PointerEventData data) {
20         if (panelRectTransform == null)
21             return;
22         
23         Vector2 localPointerPosition;
24         RectTransformUtility.ScreenPointToLocalPointInRectangle (panelRectTransform, data.position, data.pressEventCamera, out localPointerPosition);
25         Vector3 offsetToOriginal = localPointerPosition - originalLocalPointerPosition;
26         // 根据鼠标偏移改变窗口大小
27         Vector2 sizeDelta = originalSizeDelta + new Vector2 (offsetToOriginal.x, -offsetToOriginal.y);
28         sizeDelta = new Vector2 (
29             Mathf.Clamp (sizeDelta.x, minSize.x, maxSize.x),
30             Mathf.Clamp (sizeDelta.y, minSize.y, maxSize.y)
31         );
32         
33         panelRectTransform.sizeDelta = sizeDelta;
34     }
35 }

 

 

8. 根据滑动条调节光源颜色

  效果图:

  先设置 Slider 的 OnValueChange(其他两个同理) :

 

 1 public class ChangeColor : MonoBehaviour, IPointerClickHandler
 2 {
 3     public void SetRed(float value)
 4     {
 5         OnValueChanged(value, 0);
 6     }
 7     
 8     public void SetGreen(float value)
 9     {
10         OnValueChanged(value, 1);
11     }
12     
13     public void SetBlue(float value)
14     {
15         OnValueChanged(value, 2);
16     }
17     
18     public void OnValueChanged(float value, int channel)
19     {
20         Color c = Color.white;
21 
22         if (GetComponent<Renderer>() != null)
23             c = GetComponent<Renderer>().material.color;
24         else if (GetComponent<Light>() != null)
25             c = GetComponent<Light>().color;
26         
27         c[channel] = value;
28 
29         if (GetComponent<Renderer>() != null)
30             GetComponent<Renderer>().material.color = c;
31         else if (GetComponent<Light>() != null)
32             GetComponent<Light>().color = c;
33     }
34 }

 

 

 9. 面板切换

  效果图:

  面板管理代码:

 1 public class PanelManager : MonoBehaviour {
 2 
 3     public Animator initiallyOpen;
 4 
 5     private int m_OpenParameterId;
 6     private Animator m_Open;
 7     private GameObject m_PreviouslySelected;
 8 
 9     const string k_OpenTransitionName = "Open";
10     const string k_ClosedStateName = "Closed";
11 
12     public void OnEnable()
13     {
14         // 根据参数名字得到id
15         m_OpenParameterId = Animator.StringToHash (k_OpenTransitionName);
16 
17         if (initiallyOpen == null)
18             return;
19         // 打开初始面板
20         OpenPanel(initiallyOpen);
21     }
22 
23     // 打开面板
24     public void OpenPanel (Animator anim)
25     {
26         if (m_Open == anim)
27             return;
28 
29         anim.gameObject.SetActive(true);
30         var newPreviouslySelected = EventSystem.current.currentSelectedGameObject;
31 
32         // 最先显示
33         anim.transform.SetAsLastSibling();
34 
35         CloseCurrent();
36 
37         m_PreviouslySelected = newPreviouslySelected;
38 
39         m_Open = anim;
40         m_Open.SetBool(m_OpenParameterId, true);
41 
42         GameObject go = FindFirstEnabledSelectable(anim.gameObject);
43 
44         SetSelected(go);
45     }
46 
47     static GameObject FindFirstEnabledSelectable (GameObject gameObject)
48     {
49         GameObject go = null;
50         var selectables = gameObject.GetComponentsInChildren<Selectable> (true);
51         foreach (var selectable in selectables) {
52             if (selectable.IsActive () && selectable.IsInteractable ()) {
53                 go = selectable.gameObject;
54                 break;
55             }
56         }
57         return go;
58     }
59 
60     // 关闭当前面板
61     public void CloseCurrent()
62     {
63         if (m_Open == null)
64             return;
65 
66         m_Open.SetBool(m_OpenParameterId, false);
67         SetSelected(m_PreviouslySelected);
68         StartCoroutine(DisablePanelDeleyed(m_Open));
69         m_Open = null;
70     }
71 
72     // 关闭面板
73     IEnumerator DisablePanelDeleyed(Animator anim)
74     {
75         bool closedStateReached = false;
76         bool wantToClose = true;
77         while (!closedStateReached && wantToClose)
78         {
79             if (!anim.IsInTransition(0))
80                 closedStateReached = anim.GetCurrentAnimatorStateInfo(0).IsName(k_ClosedStateName);
81 
82             wantToClose = !anim.GetBool(m_OpenParameterId);             // 关闭的时候可打断
83 
84             yield return new WaitForEndOfFrame();               // 等待关闭动画播放完
85         }
86 
87         if (wantToClose)
88             anim.gameObject.SetActive(false);
89     }
90 
91     private void SetSelected(GameObject go)
92     {
93         EventSystem.current.SetSelectedGameObject(go);
94     }
95 }

 

 

10.   RenderTexure 在 UI 上显示模型

   设置 Camera TargetTexture,将 相机内容渲染到 RenderTexure 中。

  添加 RawImage,设置 Texture 为之前的 RenderTexture。

  效果图:

 

 

11. 图片遮挡(Mask,ScrollRect) 

  Hierarchy:

  在 GameObject 中添加组件:

 

  效果图:

 

posted @ 2018-03-31 13:56  Just_for_Myself  阅读(577)  评论(0编辑  收藏  举报