0312 新shader文字描边 和 图片流光shader; 武将部分代码
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public class OutlineColor : Outline | 
|---|
|  |  |  | { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | [Header("扩展Outline增加颜色选择")] | 
|---|
|  |  |  | [SerializeField][HideInInspector] | 
|---|
|  |  |  | QualityTextColType m_ColorType = QualityTextColType.None; | 
|---|
|  |  |  | public QualityTextColType colorType | 
|---|
| New file | 
|  |  |  | 
|---|
|  |  |  | using UnityEngine; | 
|---|
|  |  |  | using UnityEngine.UI; | 
|---|
|  |  |  | using System.Collections.Generic; | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /// <summary> | 
|---|
|  |  |  | /// UGUI描边 | 
|---|
|  |  |  | /// </summary> | 
|---|
|  |  |  | public class OutlineEx : BaseMeshEffect | 
|---|
|  |  |  | { | 
|---|
|  |  |  | [Header("新shader描边")] | 
|---|
|  |  |  | public Color OutlineColor = Color.white; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | QualityTextColType m_ColorType = QualityTextColType.None; | 
|---|
|  |  |  | public QualityTextColType colorType | 
|---|
|  |  |  | { | 
|---|
|  |  |  | get { return m_ColorType; } | 
|---|
|  |  |  | set | 
|---|
|  |  |  | { | 
|---|
|  |  |  | if (m_ColorType != value) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | m_ColorType = value; | 
|---|
|  |  |  | OutlineColor = UIHelper.GetUIOutlineColor(value); | 
|---|
|  |  |  | this._Refresh(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | [Range(0, 15)] | 
|---|
|  |  |  | public int OutlineWidth = 0; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private static List<UIVertex> m_VetexList = new List<UIVertex>(); | 
|---|
|  |  |  | // 材质池:Key为"颜色_宽度"格式的字符串,Value为对应的材质; 减少合批问题,又能保持不同的描边;共用材质会同时改变参数 | 
|---|
|  |  |  | private static Dictionary<string, Material> m_MaterialPool = new Dictionary<string, Material>(); | 
|---|
|  |  |  | private static Shader m_Shader; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | protected override void Start() | 
|---|
|  |  |  | { | 
|---|
|  |  |  | base.Start(); | 
|---|
|  |  |  | if (m_Shader == null) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | m_Shader = Shader.Find("TSF Shaders/UI/OutlineEx"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 使用材质池获取或创建材质 | 
|---|
|  |  |  | string key = GetMaterialKey(OutlineColor, OutlineWidth); | 
|---|
|  |  |  | if (!m_MaterialPool.TryGetValue(key, out Material material)) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | material = new Material(m_Shader); | 
|---|
|  |  |  | material.SetColor("_OutlineColor", this.OutlineColor); | 
|---|
|  |  |  | material.SetInt("_OutlineWidth", this.OutlineWidth); | 
|---|
|  |  |  | m_MaterialPool[key] = material; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | base.graphic.material = material; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | var v1 = base.graphic.canvas.additionalShaderChannels; | 
|---|
|  |  |  | var v2 = AdditionalCanvasShaderChannels.TexCoord1; | 
|---|
|  |  |  | if ((v1 & v2) != v2) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | base.graphic.canvas.additionalShaderChannels |= v2; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | v2 = AdditionalCanvasShaderChannels.TexCoord2; | 
|---|
|  |  |  | if ((v1 & v2) != v2) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | base.graphic.canvas.additionalShaderChannels |= v2; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | this._Refresh(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | #if UNITY_EDITOR | 
|---|
|  |  |  | protected override void OnValidate() | 
|---|
|  |  |  | { | 
|---|
|  |  |  | base.OnValidate(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (base.graphic.material != null) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | this._Refresh(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | #endif | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private void _Refresh() | 
|---|
|  |  |  | { | 
|---|
|  |  |  | // 检查当前材质是否与所需属性匹配,如果不匹配则从池中获取或创建新材质 | 
|---|
|  |  |  | string key = GetMaterialKey(OutlineColor, OutlineWidth); | 
|---|
|  |  |  | Material material; | 
|---|
|  |  |  | if (!m_MaterialPool.TryGetValue(key, out material)) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | // 如果池中没有对应的材质,创建新材质 | 
|---|
|  |  |  | var shader = Shader.Find("TSF Shaders/UI/OutlineEx"); | 
|---|
|  |  |  | material = new Material(shader); | 
|---|
|  |  |  | m_MaterialPool[key] = material; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | material.SetColor("_OutlineColor", this.OutlineColor); | 
|---|
|  |  |  | material.SetInt("_OutlineWidth", this.OutlineWidth); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 更新图形材质 | 
|---|
|  |  |  | base.graphic.material = material; | 
|---|
|  |  |  | base.graphic.SetVerticesDirty(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public override void ModifyMesh(VertexHelper vh) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | vh.GetUIVertexStream(m_VetexList); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | this._ProcessVertices(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | vh.Clear(); | 
|---|
|  |  |  | vh.AddUIVertexTriangleStream(m_VetexList); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private void _ProcessVertices() | 
|---|
|  |  |  | { | 
|---|
|  |  |  | for (int i = 0, count = m_VetexList.Count - 3; i <= count; i += 3) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | var v1 = m_VetexList[i]; | 
|---|
|  |  |  | var v2 = m_VetexList[i + 1]; | 
|---|
|  |  |  | var v3 = m_VetexList[i + 2]; | 
|---|
|  |  |  | // 计算原顶点坐标中心点 | 
|---|
|  |  |  | // | 
|---|
|  |  |  | var minX = _Min(v1.position.x, v2.position.x, v3.position.x); | 
|---|
|  |  |  | var minY = _Min(v1.position.y, v2.position.y, v3.position.y); | 
|---|
|  |  |  | var maxX = _Max(v1.position.x, v2.position.x, v3.position.x); | 
|---|
|  |  |  | var maxY = _Max(v1.position.y, v2.position.y, v3.position.y); | 
|---|
|  |  |  | var posCenter = new Vector2(minX + maxX, minY + maxY) * 0.5f; | 
|---|
|  |  |  | // 计算原始顶点坐标和UV的方向 | 
|---|
|  |  |  | // | 
|---|
|  |  |  | Vector2 triX, triY, uvX, uvY; | 
|---|
|  |  |  | Vector2 pos1 = v1.position; | 
|---|
|  |  |  | Vector2 pos2 = v2.position; | 
|---|
|  |  |  | Vector2 pos3 = v3.position; | 
|---|
|  |  |  | if (Mathf.Abs(Vector2.Dot((pos2 - pos1).normalized, Vector2.right)) | 
|---|
|  |  |  | > Mathf.Abs(Vector2.Dot((pos3 - pos2).normalized, Vector2.right))) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | triX = pos2 - pos1; | 
|---|
|  |  |  | triY = pos3 - pos2; | 
|---|
|  |  |  | uvX = v2.uv0 - v1.uv0; | 
|---|
|  |  |  | uvY = v3.uv0 - v2.uv0; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | else | 
|---|
|  |  |  | { | 
|---|
|  |  |  | triX = pos3 - pos2; | 
|---|
|  |  |  | triY = pos2 - pos1; | 
|---|
|  |  |  | uvX = v3.uv0 - v2.uv0; | 
|---|
|  |  |  | uvY = v2.uv0 - v1.uv0; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | // 计算原始UV框 | 
|---|
|  |  |  | // | 
|---|
|  |  |  | var uvMin = _Min(v1.uv0, v2.uv0, v3.uv0); | 
|---|
|  |  |  | var uvMax = _Max(v1.uv0, v2.uv0, v3.uv0); | 
|---|
|  |  |  | var uvOrigin = new Vector4(uvMin.x, uvMin.y, uvMax.x, uvMax.y); | 
|---|
|  |  |  | // 为每个顶点设置新的Position和UV,并传入原始UV框 | 
|---|
|  |  |  | // | 
|---|
|  |  |  | v1 = _SetNewPosAndUV(v1, this.OutlineWidth, posCenter, triX, triY, uvX, uvY, uvOrigin); | 
|---|
|  |  |  | v2 = _SetNewPosAndUV(v2, this.OutlineWidth, posCenter, triX, triY, uvX, uvY, uvOrigin); | 
|---|
|  |  |  | v3 = _SetNewPosAndUV(v3, this.OutlineWidth, posCenter, triX, triY, uvX, uvY, uvOrigin); | 
|---|
|  |  |  | // 应用设置后的UIVertex | 
|---|
|  |  |  | // | 
|---|
|  |  |  | m_VetexList[i] = v1; | 
|---|
|  |  |  | m_VetexList[i + 1] = v2; | 
|---|
|  |  |  | m_VetexList[i + 2] = v3; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private static UIVertex _SetNewPosAndUV(UIVertex pVertex, int pOutLineWidth, | 
|---|
|  |  |  | Vector2 pPosCenter, | 
|---|
|  |  |  | Vector2 pTriangleX, Vector2 pTriangleY, | 
|---|
|  |  |  | Vector2 pUVX, Vector2 pUVY, | 
|---|
|  |  |  | Vector4 pUVOrigin) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | // Position | 
|---|
|  |  |  | var pos = pVertex.position; | 
|---|
|  |  |  | var posXOffset = pos.x > pPosCenter.x ? pOutLineWidth : -pOutLineWidth; | 
|---|
|  |  |  | var posYOffset = pos.y > pPosCenter.y ? pOutLineWidth : -pOutLineWidth; | 
|---|
|  |  |  | pos.x += posXOffset; | 
|---|
|  |  |  | pos.y += posYOffset; | 
|---|
|  |  |  | pVertex.position = pos; | 
|---|
|  |  |  | // UV | 
|---|
|  |  |  | var uv = pVertex.uv0; | 
|---|
|  |  |  | uv += new Vector4((pUVX / pTriangleX.magnitude * posXOffset * (Vector2.Dot(pTriangleX, Vector2.right) > 0 ? 1 : -1)).x, (pUVX / pTriangleX.magnitude * posXOffset * (Vector2.Dot(pTriangleX, Vector2.right) > 0 ? 1 : -1)).y, 0, 0); | 
|---|
|  |  |  | uv += new Vector4((pUVY / pTriangleY.magnitude * posYOffset * (Vector2.Dot(pTriangleY, Vector2.up) > 0 ? 1 : -1)).x, (pUVY / pTriangleY.magnitude * posYOffset * (Vector2.Dot(pTriangleY, Vector2.up) > 0 ? 1 : -1)).y, 0, 0); | 
|---|
|  |  |  | pVertex.uv0 = uv; | 
|---|
|  |  |  | // 原始UV框 | 
|---|
|  |  |  | pVertex.uv1 = new Vector2(pUVOrigin.x, pUVOrigin.y); | 
|---|
|  |  |  | pVertex.uv2 = new Vector2(pUVOrigin.z, pUVOrigin.w); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | return pVertex; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private static float _Min(float pA, float pB, float pC) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | return Mathf.Min(Mathf.Min(pA, pB), pC); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private static float _Max(float pA, float pB, float pC) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | return Mathf.Max(Mathf.Max(pA, pB), pC); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private static Vector2 _Min(Vector2 pA, Vector2 pB, Vector2 pC) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | return new Vector2(_Min(pA.x, pB.x, pC.x), _Min(pA.y, pB.y, pC.y)); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private static Vector2 _Max(Vector2 pA, Vector2 pB, Vector2 pC) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | return new Vector2(_Max(pA.x, pB.x, pC.x), _Max(pA.y, pB.y, pC.y)); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 生成材质池的键 | 
|---|
|  |  |  | private string GetMaterialKey(Color color, int width) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | // 使用颜色的RGBA值和宽度生成唯一键 | 
|---|
|  |  |  | return string.Format("{0}_{1}_{2}_{3}_{4}", | 
|---|
|  |  |  | color.r, color.g, color.b, color.a, width); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
| New file | 
|  |  |  | 
|---|
|  |  |  | fileFormatVersion: 2 | 
|---|
|  |  |  | guid: 0952a679e87c6c743874501bacc08eb9 | 
|---|
|  |  |  | MonoImporter: | 
|---|
|  |  |  | externalObjects: {} | 
|---|
|  |  |  | serializedVersion: 2 | 
|---|
|  |  |  | defaultReferences: [] | 
|---|
|  |  |  | executionOrder: 0 | 
|---|
|  |  |  | icon: {instanceID: 0} | 
|---|
|  |  |  | userData: | 
|---|
|  |  |  | assetBundleName: | 
|---|
|  |  |  | assetBundleVariant: | 
|---|
|  |  |  | 
|---|
|  |  |  | //-------------------------------------------------------- | 
|---|
|  |  |  | //    [Author]:           YYL | 
|---|
|  |  |  | //    [  Date ]:           Tuesday, July 15, 2025 | 
|---|
|  |  |  | //    [  Date ]:           Wednesday, July 16, 2025 | 
|---|
|  |  |  | //-------------------------------------------------------- | 
|---|
|  |  |  |  | 
|---|
|  |  |  | using System.Collections.Generic; | 
|---|
|  |  |  | 
|---|
|  |  |  | { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public int HeroID; | 
|---|
|  |  |  | public string Name; | 
|---|
|  |  |  | public int Country; | 
|---|
|  |  |  | public int Quality; | 
|---|
|  |  |  | public int Class; | 
|---|
|  |  |  | 
|---|
|  |  |  | public int HPInheritPer; | 
|---|
|  |  |  | public string BatAttrDict; | 
|---|
|  |  |  | public int[] FetterIDList; | 
|---|
|  |  |  | public float UIScale; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public override int LoadKey(string _key) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | 
|---|
|  |  |  | string[] tables = input.Split('\t'); | 
|---|
|  |  |  | int.TryParse(tables[0],out HeroID); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | int.TryParse(tables[1],out Country); | 
|---|
|  |  |  | Name = tables[1]; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | int.TryParse(tables[2],out Quality); | 
|---|
|  |  |  | int.TryParse(tables[2],out Country); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | int.TryParse(tables[3],out Class); | 
|---|
|  |  |  | int.TryParse(tables[3],out Quality); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (tables[4].Contains("[")) | 
|---|
|  |  |  | int.TryParse(tables[4],out Class); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (tables[5].Contains("[")) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | SkinIDList = JsonMapper.ToObject<int[]>(tables[4]); | 
|---|
|  |  |  | SkinIDList = JsonMapper.ToObject<int[]>(tables[5]); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | else | 
|---|
|  |  |  | { | 
|---|
|  |  |  | string[] SkinIDListStringArray = tables[4].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries); | 
|---|
|  |  |  | string[] SkinIDListStringArray = tables[5].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries); | 
|---|
|  |  |  | SkinIDList = new int[SkinIDListStringArray.Length]; | 
|---|
|  |  |  | for (int i=0;i<SkinIDListStringArray.Length;i++) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | int.TryParse(tables[5],out AtkSkillID); | 
|---|
|  |  |  | int.TryParse(tables[6],out AtkSkillID); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | int.TryParse(tables[6],out AngerSkillID); | 
|---|
|  |  |  | int.TryParse(tables[7],out AngerSkillID); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | int.TryParse(tables[7],out AtkInheritPer); | 
|---|
|  |  |  | int.TryParse(tables[8],out AtkInheritPer); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | int.TryParse(tables[8],out DefInheritPer); | 
|---|
|  |  |  | int.TryParse(tables[9],out DefInheritPer); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | int.TryParse(tables[9],out HPInheritPer); | 
|---|
|  |  |  | int.TryParse(tables[10],out HPInheritPer); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | BatAttrDict = tables[10]; | 
|---|
|  |  |  | BatAttrDict = tables[11]; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (tables[11].Contains("[")) | 
|---|
|  |  |  | if (tables[12].Contains("[")) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | FetterIDList = JsonMapper.ToObject<int[]>(tables[11]); | 
|---|
|  |  |  | FetterIDList = JsonMapper.ToObject<int[]>(tables[12]); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | else | 
|---|
|  |  |  | { | 
|---|
|  |  |  | string[] FetterIDListStringArray = tables[11].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries); | 
|---|
|  |  |  | string[] FetterIDListStringArray = tables[12].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries); | 
|---|
|  |  |  | FetterIDList = new int[FetterIDListStringArray.Length]; | 
|---|
|  |  |  | for (int i=0;i<FetterIDListStringArray.Length;i++) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | int.TryParse(FetterIDListStringArray[i],out FetterIDList[i]); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | float.TryParse(tables[13],out UIScale); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | catch (Exception exception) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | 
|---|
|  |  |  | { | 
|---|
|  |  |  | public static GameObject LoadWindow(string name) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | return ResManager.Instance.LoadAsset<GameObject>("UI", name); | 
|---|
|  |  |  | return ResManager.Instance.LoadAsset<GameObject>(ResourcesPath.UI_WINDOW_SUFFIX, name); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public static GameObject LoadPrefab(string _name) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | return ResManager.Instance.LoadAsset<GameObject>("UIComp", _name); | 
|---|
|  |  |  | return ResManager.Instance.LoadAsset<GameObject>(ResourcesPath.UI_PREFAB_SUFFIX, _name); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public static void UnLoadPrefab(string _assetName) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | ResManager.Instance.UnloadAsset("UIComp", _assetName); | 
|---|
|  |  |  | ResManager.Instance.UnloadAsset(ResourcesPath.UI_PREFAB_SUFFIX, _assetName); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public static Sprite LoadSprite(string _iconKey) | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public static Sprite LoadSprite(string _folder, string _file) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | return ResManager.Instance.LoadAsset<Sprite>("Sprite/" + _folder, _file); | 
|---|
|  |  |  | return ResManager.Instance.LoadAsset<Sprite>(StringUtility.Contact(ResourcesPath.UI_SPRITE_SUFFIX, "/", _folder) , _file); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public static void UnLoadSprite(string _iconKey) | 
|---|
|  |  |  | 
|---|
|  |  |  | var iconConfig = IconConfig.Get(_iconKey); | 
|---|
|  |  |  | if (iconConfig != null) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | var bundleName = StringUtility.Contact("Sprite/", iconConfig.folder); | 
|---|
|  |  |  | var bundleName = StringUtility.Contact(ResourcesPath.UI_SPRITE_SUFFIX, "/", iconConfig.folder); | 
|---|
|  |  |  | ResManager.Instance.UnloadAsset(bundleName, iconConfig.sprite); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public static Font LoadFont(string _fontName) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | return ResManager.Instance.LoadAsset<Font>("Font", _fontName); | 
|---|
|  |  |  | return ResManager.Instance.LoadAsset<Font>(ResourcesPath.UI_FONT_SUFFIX, _fontName); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public static void UnLoadFont(string _fontName) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | ResManager.Instance.UnloadAsset("Font", _fontName); | 
|---|
|  |  |  | ResManager.Instance.UnloadAsset(ResourcesPath.UI_FONT_SUFFIX, _fontName); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 
|---|
|  |  |  | EventBroadcast.Instance.AddListener<BattleObject, List<int>>(EventName.BATTLE_DAMAGE_TAKEN, OnDamageTaken); | 
|---|
|  |  |  | EventBroadcast.Instance.AddListener<BattleObject, SkillConfig>(EventName.BATTLE_BUFF_MOUNTED, OnBuffMounted); | 
|---|
|  |  |  | EventBroadcast.Instance.AddListener<BattleObject, SkillConfig>(EventName.BATTLE_BUFF_DISAPEAR, OnBuffDisapear); | 
|---|
|  |  |  | damagePrefabPool = GameObjectPoolManager.Instance.RequestPool(ResManager.Instance.LoadAsset<GameObject>("UIComp", "DamageContent")); | 
|---|
|  |  |  | damagePrefabPool = GameObjectPoolManager.Instance.RequestPool(UILoader.LoadPrefab("DamageContent")); | 
|---|
|  |  |  | // buffIconPrefabPool = GameObjectPoolManager.Instance.RequestPool(); | 
|---|
|  |  |  | // buffLabelPrefabPool = GameObjectPoolManager.Instance.RequestPool(ResManager.Instance.LoadAsset<GameObject>("UIComp", "BuffContent")); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 优先功能提醒类型:1觉醒 2升级 3突破 4升星 | 
|---|
|  |  |  | // 优先顺序: | 
|---|
|  |  |  | public int funcState | 
|---|
|  |  |  | { | 
|---|
|  |  |  | get | 
|---|
|  |  |  | { | 
|---|
|  |  |  | return 0; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | //武将列表界面 | 
|---|
|  |  |  | public List<string> heroSortList = new List<string>(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //武将红点 | 
|---|
|  |  |  | //MainRedDot.HeroCardRedpoint * 1000 + hero.itemHero.gridIndex; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public Action<HeroInfo> onNewHeroEvent; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public Action<HeroInfo> onHeroChangeEvent; | 
|---|
|  |  |  | 
|---|
|  |  |  | using UnityEngine.EventSystems; | 
|---|
|  |  |  | public class UIHeroController : MonoBehaviour | 
|---|
|  |  |  | { | 
|---|
|  |  |  | public void Create(int _skinID, Action _onComplete = null) | 
|---|
|  |  |  | public void Create(int _skinID, float scale = 1f, Action _onComplete = null) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | skinID = _skinID; | 
|---|
|  |  |  | onComplete = _onComplete; | 
|---|
|  |  |  | GameObject battleGO = ResManager.Instance.LoadAsset<GameObject>("Hero/SpineRes", "Hero_001"); | 
|---|
|  |  |  | GameObject battleGO = UILoader.LoadPrefab("UIHero"); | 
|---|
|  |  |  | GameObject instanceGO = null; | 
|---|
|  |  |  | if (!transform.gameObject.activeSelf) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | 
|---|
|  |  |  | var skinConfig = HeroSkinConfig.Get(skinID); | 
|---|
|  |  |  | skeletonGraphic.skeletonDataAsset = ResManager.Instance.LoadAsset<SkeletonDataAsset>("Hero/SpineRes/", skinConfig.SpineRes + "_SkeletonData"); | 
|---|
|  |  |  | skeletonGraphic.Initialize(true); | 
|---|
|  |  |  | this.transform.localScale = Vector3.one * scale; | 
|---|
|  |  |  | spineAnimationState = skeletonGraphic.AnimationState; | 
|---|
|  |  |  | PlayAnimation(MotionName.idle, true); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | using UnityEngine; | 
|---|
|  |  |  | using UnityEngine; | 
|---|
|  |  |  | using UnityEngine.UI; | 
|---|
|  |  |  | using UnityEngine.Events; | 
|---|
|  |  |  | using System.Collections.Generic; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public class HeroCardCell : MonoBehaviour | 
|---|
|  |  |  | { | 
|---|
|  |  |  | [SerializeField] Button heroCardBtn; | 
|---|
|  |  |  | [SerializeField] Image heroCardBG; | 
|---|
|  |  |  | [SerializeField] Material glowMaterial; // 流光效果材质 | 
|---|
|  |  |  | [SerializeField] Text lvText; | 
|---|
|  |  |  | [SerializeField] Image countryImg; | 
|---|
|  |  |  | [SerializeField] Image jobImg; | 
|---|
|  |  |  | 
|---|
|  |  |  | this.gameObject.SetActive(false); | 
|---|
|  |  |  | return; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | this.gameObject.SetActive(true); | 
|---|
|  |  |  | lvText.text = hero.heroLevel.ToString(); | 
|---|
|  |  |  | heroCardBG.SetSprite("herocardbg" + hero.Quality); | 
|---|
|  |  |  | if (glowMaterial != null) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | heroCardBG.material = glowMaterial; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | lvText.text = Language.Get("L1094") + hero.heroLevel.ToString(); | 
|---|
|  |  |  | var heroConfig = hero.heroConfig; | 
|---|
|  |  |  | countryImg.SetSprite("herocountry" + hero.heroCountry); | 
|---|
|  |  |  | countryImg.SetSprite("herocountry" + heroConfig.Country); | 
|---|
|  |  |  | jobImg.SetSprite("herojob" + heroConfig.Class); | 
|---|
|  |  |  | heroModel.Create(heroConfig.SkinIDList[hero.SkinIndex]); | 
|---|
|  |  |  | heroModel.Create(heroConfig.SkinIDList[hero.SkinIndex], heroConfig.UIScale); | 
|---|
|  |  |  | onStateImg.SetActive(hero.isInMainBattle); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | redpoint.redpointId = MainRedDot.HeroCardRedpoint * 1000 + hero.itemHero.gridIndex; | 
|---|
|  |  |  | var funcState = hero.funcState; | 
|---|
|  |  |  | if (funcState > 0) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | trainStateImg.SetActive(true); | 
|---|
|  |  |  | trainStateImg.SetSprite("herofuncstate" + hero.funcState); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | else | 
|---|
|  |  |  | { | 
|---|
|  |  |  | trainStateImg.SetActive(false); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | nameText.text = hero.breakLevel == 0 ? heroConfig.Name : Language.Get("herocardbreaklv" + heroConfig.Name + hero.breakLevel); | 
|---|
|  |  |  | awakeImg.SetActive(hero.awakeLevel > 0); | 
|---|
|  |  |  | awakeLVText.text = hero.awakeLevel.ToString(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | for (int i = 0; i < starImgList.Count; i++) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | if (hero.heroStar == 0 && i == 0) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | // 无星级 特殊处理 | 
|---|
|  |  |  | starImgList[i].SetActive(true); | 
|---|
|  |  |  | starImgList[i].SetSprite("herostar" + hero.heroStar); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | else if ((hero.heroStar - 1) % starImgList.Count >= i) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | starImgList[i].SetActive(true); | 
|---|
|  |  |  | starImgList[i].SetSprite("herostar" +  (((hero.heroStar - 1)/starImgList.Count)+1)*starImgList.Count); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | else | 
|---|
|  |  |  | { | 
|---|
|  |  |  | starImgList[i].SetActive(false); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | if (i + index < HeroManager.Instance.heroSortList.Count) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | cardList[i].SetActive(true); | 
|---|
|  |  |  | cardList[i].Display(index); | 
|---|
|  |  |  | cardList[i].Display(index + i); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | else | 
|---|
|  |  |  | { | 
|---|
|  |  |  | 
|---|
|  |  |  | { | 
|---|
|  |  |  | heroListScroller.Refresh(); | 
|---|
|  |  |  | for (int i = 0; i < HeroManager.Instance.heroSortList.Count; i++) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | heroListScroller.AddCell(ScrollerDataType.Header, i); | 
|---|
|  |  |  | { | 
|---|
|  |  |  | if (i % 4 == 0) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | heroListScroller.AddCell(ScrollerDataType.Header, i); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | heroListScroller.Restart(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 
|---|
|  |  |  | public Redpoint redpointGuild = new Redpoint(MainGuildRedpoint); | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public const int RedPoint_key = 11; | 
|---|
|  |  |  | public const int FAIRY_REDPOINT_KEY1 = 107; | 
|---|
|  |  |  | public const int RedPoint_UpFuncBase = 12; | 
|---|
|  |  |  | //以下红点规则:功能基础红点3位数,子红点至少大于1000, | 
|---|
|  |  |  | //比如功能A红点100,子红点1001,以此类推,或者100*10000 +1类推,避免重复的可能性,如1010 就可能和功能B中的红点重复 | 
|---|
|  |  |  | //    功能B红点101,子红点1011,以此类推,或者101*10000 +1类推,避免重复的可能性 | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private Redpoint rightTopRedpint = new Redpoint(RedPoint_UpFuncBase); | 
|---|
|  |  |  | private Redpoint redPointStrePrentOne = new Redpoint(RedPoint_key); | 
|---|
|  |  |  | //武将卡 | 
|---|
|  |  |  | public const int HeroCardRedpoint = 200; | 
|---|
|  |  |  | public Redpoint HeroCardRedpoint1 = new Redpoint(MainHerosRedpoint, HeroCardRedpoint); | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //public Redpoint jadeDynastyRedpoint = new Redpoint(1, 117); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | #region 邮件红点 | 
|---|
|  |  |  | public const int RedPoint_MainMailKey = 24; | 
|---|
|  |  |  | public const int RedPoint_MainMailKey = 240; | 
|---|
|  |  |  | public const int RedPoint_MailFuncKey = 2401; | 
|---|
|  |  |  | public Redpoint redpointMainMail = new Redpoint(RedPoint_MainMailKey); | 
|---|
|  |  |  | public Redpoint redpointMailFunc = new Redpoint(RedPoint_MainMailKey, RedPoint_MailFuncKey); | 
|---|
|  |  |  | #endregion | 
|---|
|  |  |  |  | 
|---|
|  |  |  | #region 好友红点 | 
|---|
|  |  |  | public const int RedPoint_FriendQuestKey = 26; | 
|---|
|  |  |  | public const int RedPoint_FriendChatKey = 25; //好友 | 
|---|
|  |  |  | public const int RedPoint_FriendQuestKey = 260; | 
|---|
|  |  |  | public const int RedPoint_FriendChatKey = 250; //好友 | 
|---|
|  |  |  | public Redpoint redpointFriendQuest = new Redpoint(RedPoint_FriendQuestKey); | 
|---|
|  |  |  | public Redpoint redPointFriendChat = new Redpoint(RedPoint_FriendChatKey); | 
|---|
|  |  |  | #endregion | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | #region 仙盟公用红点 | 
|---|
|  |  |  | public const int FAIRY_REDPOINT_KEY2 = 10701; | 
|---|
|  |  |  | public Redpoint fairyLaunch = new Redpoint(RedPoint_key, FAIRY_REDPOINT_KEY1); | 
|---|
|  |  |  | public Redpoint fairyBaseFuncRedPoint = new Redpoint(FAIRY_REDPOINT_KEY1, FAIRY_REDPOINT_KEY2); | 
|---|
|  |  |  | #endregion | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | #region 仙盟商店红点 | 
|---|
|  |  |  | public const int FAIRYStore_REDPOINT_KEY3 = 1070106; | 
|---|
|  |  |  | public Redpoint fairyStoreRedPoint = new Redpoint(FAIRY_REDPOINT_KEY2, FAIRYStore_REDPOINT_KEY3); | 
|---|
|  |  |  | #endregion | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | ScrollTipDetail tip = null; | 
|---|
|  |  |  | if (pool == null) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | var _prefab = ResManager.Instance.LoadAsset<GameObject>("UIComp", "Tip");// UILoader.LoadPrefab("Tip"); | 
|---|
|  |  |  | var _prefab = UILoader.LoadPrefab("Tip"); | 
|---|
|  |  |  | pool = GameObjectPoolManager.Instance.RequestPool(_prefab); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (pool != null) | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public static GameObject CreateWidget(string _sourceName, string _name) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | var prefab = ResManager.Instance.LoadAsset<GameObject>("UIComp", _sourceName); | 
|---|
|  |  |  | var prefab = UILoader.LoadPrefab(_sourceName); | 
|---|
|  |  |  | if (prefab == null) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | return null; | 
|---|