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 Dictionarym_DraggingIcons = new Dictionary (); 6 private Dictionary m_DraggingPlanes = new Dictionary (); 7 8 // 开始拖拽 9 // 创建拖拽图片的 clone 体10 public void OnBeginDrag(PointerEventData eventData)11 {12 var canvas = FindInParents
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();56 if (dragMe == null)57 return null;58 59 var srcImage = originalObj.GetComponent ();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 parent34 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();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() != null)23 c = GetComponent ().material.color;24 else if (GetComponent () != null)25 c = GetComponent ().color;26 27 c[channel] = value;28 29 if (GetComponent () != null)30 GetComponent ().material.color = c;31 else if (GetComponent () != null)32 GetComponent ().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 // 根据参数名字得到id15 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(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 中添加组件:
效果图: