【Unity】新的UI系统技巧
发表于2018-10-18
从Unity4.6开始,集成了新的UI系统。这篇文章将记录新的UI系统的一些使用技巧,分享给大家,希望大家可以将学到的这些知识应用到自己在做的项目中去。
1、给人物加血条效果
把要挂载的父节点的RectTransform中的锚点设置位buttonLeft。并获得当前的Canvas中的CanvasScaler,计算出缩放因子(比如下面是按照y来进行缩放的)
CanvasScaler scaler = GetComponent<CanvasScaler> (); if(scaler != null) { float s = scaler.referenceResolution.y / Screen.height; UIScaleFactor = Vector3.one * s; // 初始化缩放因子, 因为本游戏是按照高度来缩放的,所以这里是y的缩放因子 } else { Debug.LogError("[UIBattle] Cannot get component of CanvasScaler!"); } var pos = Camera.main.WorldToScreenPoint(BloodBarPos); // 获取屏幕地址 pos.Scale(UIScaleFactor); // 进行缩放 bloodTrans.anchoredPosition = pos; // 设置位置,当然这个bloodTrans在某个锚点在ButtonLeft的父节点下
2、定制一个雷达图控件
代码如下:
using System.Collections; using UnityEngine.UI; [ExecuteInEditMode] public class RadarChart : Graphic { public RectTransform[] maxPoints; private float[] percents = new float[5] { 1, 1, 1, 1, 1 }; private Vector3[] vertexes = new Vector3[6]; private bool isDirty = true; void Update() { #if UNITY_EDITOR isDirty = true; #endif if(isDirty) { isDirty = false; refresh(); } } public void refresh() { vertexes[0] = maxPoints[0].anchoredPosition; for(int i=1; i<maxPoints.Length; i++) { vertexes[i] = maxPoints[0].anchoredPosition + (maxPoints[i].anchoredPosition - maxPoints[0].anchoredPosition)*percents[i-1]; } SetAllDirty(); } public float perA { get { return percents[0]; } set { percents[0] = Mathf.Clamp01(value); isDirty = true; } } public float perB { get { return percents[1]; } set { percents[1] = Mathf.Clamp01(value); isDirty = true; } } public float perC { get { return percents[2]; } set { percents[2] = Mathf.Clamp01(value); isDirty = true; } } public float perD { get { return percents[3]; } set { percents[3] = Mathf.Clamp01(value); isDirty = true; } } public float perE { get { return percents[4]; } set { percents[4] = Mathf.Clamp01(value); isDirty = true; } } protected override void OnPopulateMesh(Mesh m) { var r = GetPixelAdjustedRect(); var v = new Vector4(r.x, r.y, r.x + r.width, r.y + r.height); Color32 color32 = color; using (var vh = new VertexHelper()) { foreach (Vector3 p in vertexes) { vh.AddVert(p, color32, Vector2.zero); } vh.AddTriangle(2, 0, 1); vh.AddTriangle(3, 0, 2); vh.AddTriangle(4, 0, 3); vh.AddTriangle(5, 0, 4); vh.AddTriangle(1, 0, 5); vh.FillMesh(m); } } }
编辑器代码:
using UnityEditor; using UnityEngine; using System.Collections; [CustomEditor(typeof(RadarChart))] public class RadarChartEditor : Editor { SerializedProperty maxPointsProp, color, raycast, material; SerializedProperty percents; string[] names ; void OnEnable() { maxPointsProp = serializedObject.FindProperty("maxPoints"); percents = serializedObject.FindProperty("percents"); color = serializedObject.FindProperty("m_Color"); raycast = serializedObject.FindProperty("m_RaycastTarget"); material = serializedObject.FindProperty("m_Material"); names = new string[6] { "Center", "ATK", "HP", "ASS", "REV", "CON" }; } bool showMaxProp = false, showPercent = true; public override void OnInspectorGUI() { serializedObject.Update (); showMaxProp = EditorGUILayout.Foldout(showMaxProp, "Max Points"); if(showMaxProp) { int size = maxPointsProp.arraySize; for(int i=0; i<size; i++) { SerializedProperty p = maxPointsProp.GetArrayElementAtIndex(i); EditorGUILayout.PropertyField(p, new GUIContent(names[i], "")); } } EditorGUILayout.PropertyField(raycast); EditorGUILayout.PropertyField(material); EditorGUILayout.PropertyField(color); EditorGUILayout.Space(); showPercent = EditorGUILayout.Foldout(showPercent, "percents"); if(showPercent) { int size = percents.arraySize; for(int i=0; i<size; i++) { SerializedProperty p = percents.GetArrayElementAtIndex(i); EditorGUILayout.Slider(p, 0, 1, new GUIContent(names[i+1], "")); } } serializedObject.ApplyModifiedProperties (); } }
3、定制属性面板
官方有一个很不错的例子:http://docs.unity3d.com/ScriptReference/Editor.html
把Property暴露到面板上:http://wiki.unity3d.com/index.php?title=Expose_properties_in_inspector
详细的Editor例子:http://catlikecoding.com/unity/tutorials/editor/custom-list/
http://catlikecoding.com/unity/tutorials/editor/custom-data/
Editor高阶例子:http://catlikecoding.com/unity/tutorials/editor/star/
4、定制一个刻度条相关的控件
如下:
基本原理是继承Graphic类,并重写OnPopulateMesh函数,用到一些基本的OpenGL画矩形的算法。比较有参考的是制作控件的习惯和编辑器的使用,从而使工程模块化,提供工作效率。
代码如下:
using UnityEngine; using UnityEngine.UI; using System.Collections; using System.Collections.Generic; [ExecuteInEditMode] public class BloodBar : Graphic { public float _bloodNum = 7; public float bloodNum { get { return _bloodNum; } set { _bloodNum = value; if(_bloodNum < 1) { _bloodNum = 1; Debug.LogWarningFormat("The number should not less than 1!"); } SetAllDirty(); } } private float lineWidth = 1f; private float deltaWidth = 1; /// <summary> /// Update the UI renderer mesh. /// </summary> protected override void OnPopulateMesh(VertexHelper vh) { Rect r = GetPixelAdjustedRect(); deltaWidth = r.width / bloodNum; Vector2 offset = new Vector2(r.xMin, r.yMin); vh.Clear(); for(int i = 0; i < bloodNum-1; i++) { drawLine(vh, r, offset, i); } } private void drawLine(VertexHelper vh, Rect r, Vector2 offset, int idx) { float pos = (idx + 1) * deltaWidth; int ti = idx * 4; float p = (idx + 1) % 5 == 0 ? 0 : 0.4f; vh.AddVert(new Vector2(pos, r.height*p) + offset, Color.black, Vector2.zero); vh.AddVert(new Vector2(pos + lineWidth, r.height*p) + offset, Color.black, Vector2.zero); vh.AddVert(new Vector2(pos + lineWidth, r.height) + offset, Color.black, Vector2.zero); vh.AddVert(new Vector2(pos, r.height) + offset, Color.black, Vector2.zero); vh.AddTriangle(0 + ti, 1 + ti, 2 + ti); vh.AddTriangle(2 + ti, 3 + ti, 0 + ti); } }
编辑器代码:
using UnityEngine; using System.Collections; using UnityEditor; [CustomEditor(typeof(BloodBar))] public class BloodBarEditor : Editor { SerializedProperty bloodNum; void OnEnable() { bloodNum = serializedObject.FindProperty("_bloodNum"); } public override void OnInspectorGUI() { serializedObject.Update(); //DrawDefaultInspector(); //BloodBar btns = (BloodBar)target; //btns.bloodNum = EditorGUILayout.Slider(btns.bloodNum, 0, 30); EditorGUILayout.Slider(bloodNum, 1, 30, new GUIContent("blood Num")); serializedObject.ApplyModifiedProperties(); } }
来自:https://blog.csdn.net/stalendp/article/details/42621917