| | |
| | | |
| | | if (base.graphic) |
| | | { |
| | | if (base.graphic.material == null || base.graphic.material.shader.name != "TSF Shaders/UI/OutlineEx") |
| | | { |
| | | // 先设置材质(无论是否已设置,都确保正确) |
| | | var texMaterial = ResManager.Instance.LoadAsset<Material>("Materials", "OutlineMat"); |
| | | if (texMaterial != null) |
| | | { |
| | | base.graphic.material = texMaterial; |
| | | // 创建实例材质,避免共享材质的问题 |
| | | var instanceMat = new Material(texMaterial); |
| | | |
| | | // 获取正确的纹理并绑定 |
| | | Texture mainTexture = null; |
| | | if (base.graphic is Text text) |
| | | { |
| | | mainTexture = text.font.material.mainTexture; |
| | | } |
| | | else if (base.graphic is Image image && image.sprite != null) |
| | | { |
| | | mainTexture = image.sprite.texture; |
| | | } |
| | | else if (base.graphic is RawImage rawImage && rawImage.texture != null) |
| | | { |
| | | mainTexture = rawImage.texture; |
| | | } |
| | | else |
| | | { |
| | | // 兜底:使用当前材质的纹理 |
| | | mainTexture = instanceMat.GetTexture("_MainTex"); |
| | | } |
| | | |
| | | if (mainTexture != null) |
| | | { |
| | | instanceMat.SetTexture("_MainTex", mainTexture); |
| | | } |
| | | |
| | | base.graphic.material = instanceMat; |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("没有找到材质OutlineMat.mat"); |
| | | } |
| | | } |
| | | |
| | | if (base.graphic.canvas) |
| | |
| | | |
| | | this._Refresh(); |
| | | |
| | | // 注册字体纹理重建事件(动态字体首次渲染时可能未就绪) |
| | | if (base.graphic is Text textComponent && textComponent.font != null) |
| | | { |
| | | Font.textureRebuilt += OnFontTextureRebuilt; |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void OnFontTextureRebuilt(Font font) |
| | | { |
| | | if (base.graphic is Text textComponent && textComponent.font == font) |
| | | { |
| | | // 在字体重建回调中不能直接调用SetVerticesDirty,需要延迟 |
| | | if (gameObject.activeInHierarchy) |
| | | { |
| | | StartCoroutine(DelayRefresh()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private System.Collections.IEnumerator DelayRefresh() |
| | | { |
| | | yield return null; |
| | | this._Refresh(); |
| | | } |
| | | |
| | | protected override void OnDestroy() |
| | | { |
| | | base.OnDestroy(); |
| | | Font.textureRebuilt -= OnFontTextureRebuilt; |
| | | } |
| | | |
| | | protected override void OnDisable() |
| | | { |
| | | base.OnDisable(); |
| | | Font.textureRebuilt -= OnFontTextureRebuilt; |
| | | } |
| | | |
| | | protected override void OnEnable() |
| | | { |
| | | base.OnEnable(); |
| | | if (base.graphic is Text textComponent && textComponent.font != null) |
| | | { |
| | | Font.textureRebuilt += OnFontTextureRebuilt; |
| | | } |
| | | } |
| | | |
| | | #if UNITY_EDITOR |
| | | protected override void OnValidate() |
| | |
| | | // UV |
| | | var uv = pVertex.uv0; |
| | | |
| | | |
| | | // X方向UV偏移 |
| | | float xSign = Vector2.Dot(pTriangleX, Vector2.right) >= 0 ? 1f : -1f; |
| | | Vector2 uvOffsetX = (pUVX / pTriangleX.magnitude) * posXOffset * xSign; |
| | | |
| | | // Y方向UV偏移 - 使用更稳定的判断方式 |
| | | float ySign = pTriangleY.y >= 0 ? 1f : -1f; |
| | | Vector2 uvOffsetY = (pUVY / pTriangleY.magnitude) * posYOffset * ySign; |
| | | |
| | | uv += new Vector4(uvOffsetX.x + uvOffsetY.x, uvOffsetX.y + uvOffsetY.y, 0, 0); |
| | | 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; |
| | | |