using UnityEngine; using System.Collections; using System.Collections.Generic; namespace Thousandto.GameUI.Form { /// /// 画多边形 -- 暂时最多是6边型 /// 这个需要配合Shader"Ares/UI/Polygon"所对应的材质来处理 /// public class UIPolygonScript : MonoBehaviour { //记录几个最大顶点 -- 标准点 private static Vector2[] _ConstPoint = new Vector2[] { new Vector2(0f,0.5f), new Vector2(0.433f,0.25f), new Vector2(0.433f,-0.25f), new Vector2(0,-0.5f), new Vector2(-0.433f,-0.25f), new Vector2(-0.433f,0.25f), }; //点的数量 private int _pointCount = 6; //在所有最大和最小的坐标 private Vector4 _maxPoint = new Vector4(-0.5f, 0.5f, -0.5f, 0.5f); //提供给Shader的点 private Vector4[] _points = null; //临时列表 private List _tmpPointList = new List(6); private List _tmpRemoveList = new List(6); //当前脚本所在对象的纹理 private UITexture _tex; /// /// 设置属性等级 ,根据属性等级,来设置多边型的形状 /// /// public void SetAttrLevel(float[] attrLevels) { if (!Initialize()) { //Debug.LogError("当前GameObject没有找到UITexture组件:" + gameObject.name); return; } //创建节点 _tmpPointList.Clear(); for (int i = 0; i < attrLevels.Length && i < _ConstPoint.Length; i++) { var p = _ConstPoint[i] * attrLevels[i]; _tmpPointList.Add(p); //这里记录最大和最小的坐标点 _maxPoint.x = Mathf.Min(p.x, _maxPoint.x); _maxPoint.y = Mathf.Max(p.x, _maxPoint.y); _maxPoint.z = Mathf.Min(p.x, _maxPoint.z); _maxPoint.w = Mathf.Max(p.x, _maxPoint.w); } _pointCount = _tmpPointList.Count; //判断哪些节点是凹进去的. _tmpRemoveList.Clear(); for (int i = 0; i < _pointCount; i++) { int p = (i - 1 + _pointCount) % _pointCount; int n = (i + 1 + _pointCount) % _pointCount; //向量1 Vector4 v1 = _tmpPointList[i] - _tmpPointList[p]; //向量2 Vector4 v2 = _tmpPointList[n] - _tmpPointList[i]; //通过叉积,来判断两个向量之间,是顺时针关系,还是逆时针关系 if ((v2.y * v1.x - v2.x * v1.y) >= 0) { _tmpRemoveList.Add(i); } } //清理哪些凹进去的节点 -- 倒着删除,因为是通过索引删除 for (int i = _tmpRemoveList.Count - 1; i >= 0; i--) { _tmpPointList.RemoveAt(_tmpRemoveList[i]); } //最终设置 _pointCount = _tmpPointList.Count; for (int i = 0; i < 6 - _tmpPointList.Count; i++) { _tmpPointList.Add(Vector4.zero); } _points = _tmpPointList.ToArray(); } //初始化 private bool Initialize() { if (_tex == null) { _tex = GetComponent(); if (_tex.material != null && _tex.material.shader == null) { _tex.material.shader = Core.Base.ShaderEx.Find("Ares/UI/Polygon"); } _tex.mOnRender = OnRenderCallBack; } return _tex != null; } //开始渲染纹理 private void OnRenderCallBack(Material mat) { if (_points != null && mat != null) { mat.SetFloat("_PointCount", _pointCount); mat.SetVectorArray("_PolyPoints", _points); mat.SetVector("_MinOrMaxPoint", _maxPoint); } } } }