UGUI源码学习
https://github.com/Unity-Technologies/uGUI/tree/2018.4
加了注释的源码 https://github.com/void87/TestForUGUI
https://www.cnblogs.com/revoid/p/6911699.html
layer主要通过光线投射来选择性地忽略碰撞器,或者添加碰撞功能。
而sorting layer就是一个渲染层级的顺序的控制。
决定Unity渲染关系的层级顺序是:
Camera
sorting layer
sorting order
IME(Input Method Editor) 输入法编辑器
// The position of the pivot of this RectTransform relative to the anchor reference point // 中心点相对于自身的锚点的为止 rectTransform.anchoredPosition
// Position of the transform relative to the parent transform // 中心点相对于父物体中心点的位置 rectTransform.localPosition
Debug.Log(rectTransform.localPosition); // Matrix that transforms a point from local space into world space Vector3 worldPosition = rectTransform.localToWorldMatrix.MultiplyPoint(rectTransform.localPosition); Debug.Log(worldPosition); // Matrix that transforms a point from world space into local space Vector3 localPosition = rectTransform.worldToLocalMatrix.MultiplyPoint(worldPosition); Debug.Log(localPosition);
Vector3[] localCorners = new Vector3[4]; // Get the corners of the calculated rectangle in the local space of its Transform // 获取localspace中的4个角的坐标 rectTransform.GetLocalCorners(localCorners); Vector3[] worldCorners = new Vector3[4]; // Get the corners of the calculated rectangle in the local space of its Transform // 获取worldspacee中的4个角的坐标 rectTransform.GetWorldCorners(worldCorners);
// The calculated rectangle in the local space of Transform // 以左下角为原点的rect(x轴正方向为左,y轴正方向为下) var rect = rectTransform.rect; // The minimum X coordinate of the rectangle == left var xMin = rect.xMin; // The maximum Y coordinate of the rectangle == right var xMax = rect.xMax; // The minimum Y coordinate of the rectangle == top var yMin = rect.yMin; // The maximum Y coordinate of the rectangle == bottom var yMax = rect.yMax; // The X and Y position of the rectangle // 中心点相对于rect左下角的点的位置 var rectPos = rect.position; // 宽高 var with = rect.width; var height = rect.height; var size = rect.size; // The position of the center of the rectangle // 相对于rect的pivot的中心点 var center = rect.center;
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; internal class ObjectPool<T> where T: new() { private readonly Stack<T> m_Stack = new Stack<T>(); private readonly UnityAction<T> m_ActionOnGet; private readonly UnityAction<T> m_ActionOnRelease; public int countAll { get; private set; } public int countActive { get { return countAll - countInactive; } } public int countInactive { get { return m_Stack.Count; } } public ObjectPool(UnityAction<T> actionOnGet, UnityAction<T> actionOnRelease) { m_ActionOnGet = actionOnGet; m_ActionOnRelease = actionOnRelease; } public T Get() { T element; if (m_Stack.Count== 0) { element = new T(); countAll++; } else { element = m_Stack.Pop(); } if (m_ActionOnGet != null) { m_ActionOnGet(element); } return element; } public void Release(T element) { if (m_Stack.Count > 0 && ReferenceEquals(m_Stack.Peek(), element)) { Debug.LogError("Internal error. Trying to destroy object that is already released to pool."); } if (m_ActionOnRelease != null) { m_ActionOnRelease(element); } m_Stack.Push(element); } }
internal static class ListPool<T> { private static readonly ObjectPool<List<T>> s_ListPool = new ObjectPool<List<T>>(null, Clear); static void Clear(List<T> l) { l.Clear(); } public static List<T> Get() { return s_ListPool.Get(); } public static void Release(List<T> toRelease) { s_ListPool.Release(toRelease); } }
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; public class IndexedSet<T> : IList<T> { //This is a container that gives: // - Unique items // - Fast random removal // - Fast unique inclusion to the end // - Sequential access //Downsides: // - Uses more memory // - Ordering is not persistent // - Not Serialization Friendly. //We use a Dictionary to speed up list lookup, this makes it cheaper to guarantee no duplicates (set) //When removing we move the last item to the removed item position, this way we only need to update the index cache of a single item. (fast removal) //Order of the elements is not guaranteed. A removal will change the order of the items. readonly List<T> m_List = new List<T>(); Dictionary<T, int> m_Dictionary = new Dictionary<T, int>(); public void Add(T item) { m_List.Add(item); m_Dictionary.Add(item, m_List.Count - 1); } public bool AddUnique(T item) { if (m_Dictionary.ContainsKey(item)) return false; m_List.Add(item); m_Dictionary.Add(item, m_List.Count - 1); return true; } public bool Remove(T item) { int index = -1; if (!m_Dictionary.TryGetValue(item, out index)) return false; RemoveAt(index); return true; } public IEnumerator<T> GetEnumerator() { throw new System.NotImplementedException(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public void Clear() { m_List.Clear(); m_Dictionary.Clear(); } public bool Contains(T item) { return m_Dictionary.ContainsKey(item); } public void CopyTo(T[] array, int arrayIndex) { m_List.CopyTo(array, arrayIndex); } public int Count { get { return m_List.Count; } } public bool IsReadOnly { get { return false; } } public int IndexOf(T item) { int index = -1; m_Dictionary.TryGetValue(item, out index); return index; } public void Insert(int index, T item) { //We could support this, but the semantics would be weird. Order is not guaranteed.. throw new NotSupportedException("Random Insertion is semantically invalid, since this structure does not guarantee ordering."); } public void RemoveAt(int index) { T item = m_List[index]; m_Dictionary.Remove(item); if (index == m_List.Count - 1) m_List.RemoveAt(index); else { int replaceItemIndex = m_List.Count - 1; T replaceItem = m_List[replaceItemIndex]; m_List[index] = replaceItem; m_Dictionary[replaceItem] = index; m_List.RemoveAt(replaceItemIndex); } } public T this[int index] { get { return m_List[index]; } set { T item = m_List[index]; m_Dictionary.Remove(item); m_List[index] = value; m_Dictionary.Add(item, index); } } public void RemoveAll(Predicate<T> match) { //I guess this could be optmized by instead of removing the items from the list immediatly, //We move them to the end, and then remove all in one go. //But I don't think this is going to be the bottleneck, so leaving as is for now. int i = 0; while (i < m_List.Count) { T item = m_List[i]; if (match(item)) Remove(item); else i++; } } //Sorts the internal list, this makes the exposed index accessor sorted as well. //But note that any insertion or deletion, can unorder the collection again. public void Sort(Comparison<T> sortLayoutFunction) { //There might be better ways to sort and keep the dictionary index up to date. m_List.Sort(sortLayoutFunction); //Rebuild the dictionary index. for (int i = 0; i < m_List.Count; ++i) { T item = m_List[i]; m_Dictionary[item] = i; } } }