Files
2025-01-25 04:38:09 +08:00

120 lines
4.2 KiB
C#

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace Thousandto.GameUI.Form
{
/// <summary>
/// 画多边形 -- 暂时最多是6边型
/// 这个需要配合Shader"Ares/UI/Polygon"所对应的材质来处理
/// </summary>
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<Vector4> _tmpPointList = new List<Vector4>(6);
private List<int> _tmpRemoveList = new List<int>(6);
//当前脚本所在对象的纹理
private UITexture _tex;
/// <summary>
/// 设置属性等级 ,根据属性等级,来设置多边型的形状
/// </summary>
/// <param name="attrLevels"></param>
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<UITexture>();
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);
}
}
}
}