1. 程式人生 > >【Unity】新的UI系統技巧

【Unity】新的UI系統技巧

從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/