Unity UGUI 文字描邊與漸變
阿新 • • 發佈:2022-03-04
文字描邊
OutLine
預設頂點數為16
將描邊距離分別設定x=100,y=50,使用OutLine8 與禁用OutLine8 對比,如下圖,頂點數(Verts)相差100
一個字=一張圖=2個三角面=6個頂點(vertex)包括2個共用頂點
使用Text,一個文字對應4個頂點,其中2個頂點共用
使用OutLine8,相當於在Text文字後面多繪製了8個文字,此時頂點數=2*6*9=108
Outline8 Code
using System.Collections.Generic; using UGUIExtentions; namespace UnityEngine.UI { /// <summary> /// Adds an outline to a graphic using IVertexModifier. /// </summary> public class Outline8 : BaseMeshEffect { [SerializeField] private Color m_EffectColor = new Color(0f, 0f, 0f, 1f); [SerializeField] private Vector2 m_EffectDistance = new Vector2(1f, -1f); [SerializeField] private bool m_UseGraphicAlpha = true; private const float kMaxEffectDistance = 600f; protected Outline8() { } #if UNITY_EDITOR protected override void OnValidate() { effectDistance = m_EffectDistance; base.OnValidate(); } #endif /// <summary> /// Color for the effect /// </summary> public Color effectColor { get { return m_EffectColor; } set { m_EffectColor = value; if (graphic != null) graphic.SetVerticesDirty(); } } /// <summary> /// How far is the shadow from the graphic. /// </summary> public Vector2 effectDistance { get { return m_EffectDistance; } set { Mathf.Clamp(value.x, -kMaxEffectDistance, kMaxEffectDistance); Mathf.Clamp(value.y, -kMaxEffectDistance, kMaxEffectDistance); if (m_EffectDistance == value) return; m_EffectDistance = value; if (graphic != null) graphic.SetVerticesDirty(); } } /// <summary> /// Should the shadow inherit the alpha from the graphic? /// </summary> public bool useGraphicAlpha { get { return m_UseGraphicAlpha; } set { m_UseGraphicAlpha = value; if (graphic != null) graphic.SetVerticesDirty(); } } // 新增4個角的頂點 public override void ModifyMesh(VertexHelper vh) { if (!IsActive()) return; var verts = ListPool<UIVertex>.Get(); vh.GetUIVertexStream(verts); var neededCpacity = verts.Count * 5; if (verts.Capacity < neededCpacity) verts.Capacity = neededCpacity; // 頂點部分 開始 var start = 0; var end = verts.Count; ApplyShadowZeroAlloc(verts, effectColor, start, verts.Count, effectDistance.x, effectDistance.y); start = end; end = verts.Count; ApplyShadowZeroAlloc(verts, effectColor, start, verts.Count, effectDistance.x, -effectDistance.y); start = end; end = verts.Count; ApplyShadowZeroAlloc(verts, effectColor, start, verts.Count, -effectDistance.x, effectDistance.y); start = end; end = verts.Count; ApplyShadowZeroAlloc(verts, effectColor, start, verts.Count, -effectDistance.x, -effectDistance.y); start = end; end = verts.Count; ApplyShadowZeroAlloc(verts, effectColor, start, verts.Count, effectDistance.x, 0); start = end; end = verts.Count; ApplyShadowZeroAlloc(verts, effectColor, start, verts.Count, -effectDistance.x, 0); start = end; end = verts.Count; ApplyShadowZeroAlloc(verts, effectColor, start, verts.Count, 0, effectDistance.y); start = end; end = verts.Count; ApplyShadowZeroAlloc(verts, effectColor, start, verts.Count, 0, -effectDistance.y); // 頂點部分 結束 // 頂點部分 優化寫法 // 參考 https://github.com/n-yoda/unity-vertex-effects /*var original = verts.Count; var count = 0; for (int x = -1; x <= 1; x++) { for (int y = -1; y <= 1; y++) { if (!(x == 0 && y == 0)) { var next = count + original; ApplyShadowZeroAlloc(verts, effectColor, count, next, effectDistance.x * x, effectDistance.y * y); count = next; } } }*/ vh.Clear(); vh.AddUIVertexTriangleStream(verts); ListPool<UIVertex>.Release(verts); } protected void ApplyShadowZeroAlloc(List<UIVertex> verts, Color32 color, int start, int end, float x, float y) { UIVertex vt; var neededCapacity = verts.Count + end - start; if (verts.Capacity < neededCapacity) verts.Capacity = neededCapacity; for (int i = start; i < end; ++i) { vt = verts[i]; verts.Add(vt); Vector3 v = vt.position; v.x += x; v.y += y; vt.position = v; var newColor = color; if (m_UseGraphicAlpha) newColor.a = (byte)((newColor.a * verts[i].color.a) / 255); vt.color = newColor; verts[i] = vt; } } } }
Text擴充套件
建立OutlineText繼承Text,重寫OnPopulateMesh,在內部進行描邊
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class OutLineText : Text { public bool m_OutLine=true; public Color m_OutLineColor=Color.black; public float m_OutLineOffsetX=0f; public float m_OutLineOffsetY=0f; protected override void OnPopulateMesh(VertexHelper toFill) { //這裡是直接複製的UGUI的Text生成定點的程式碼 Vector2 extent=rectTransform.rect.size; var settings= GetGenerationSettings(extent); cachedTextGenerator.Populate(this.text, settings); Rect inputRect = rectTransform.rect; // get the text alignment anchor point for the text in local space Vector2 textAnchorPivot = GetTextAnchorPivot(alignment); Vector2 refPoint = Vector2.zero; refPoint.x = Mathf.Lerp(inputRect.xMin, inputRect.xMax, textAnchorPivot.x); refPoint.y = Mathf.Lerp(inputRect.yMin, inputRect.yMax, textAnchorPivot.y); // Determine fraction of pixel to offset text mesh. Vector2 roundingOffset = PixelAdjustPoint(refPoint) - refPoint; // Apply the offset to the vertices IList<UIVertex> verts = cachedTextGenerator.verts; float unitsPerPixel = 1 / pixelsPerUnit; //Last 4 verts are always a new line... int vertCount = verts.Count - 4; toFill.Clear(); UIVertex[] rVertex=new UIVertex[4]; if (roundingOffset != Vector2.zero) { for (int i = 0; i < vertCount; ++i) { int tempVertsIndex = i & 3; rVertex[tempVertsIndex] = verts[i]; rVertex[tempVertsIndex].position *= unitsPerPixel; rVertex[tempVertsIndex].position.x += roundingOffset.x; rVertex[tempVertsIndex].position.y += roundingOffset.y; if (tempVertsIndex == 3) toFill.AddUIVertexQuad(rVertex); } } else { for (int i = 0; i < verts.Count-4; i++) { int tempVertsIndex = i & 3; rVertex[tempVertsIndex] = verts[i]; rVertex[tempVertsIndex].position.x += roundingOffset.x; rVertex[tempVertsIndex].position.y += roundingOffset.y; rVertex[tempVertsIndex].position *= unitsPerPixel; rVertex[tempVertsIndex].uv1 = Vector2.zero; if (m_OutLine && tempVertsIndex == 3) { ApplyShadowZeroAlloc(ref rVertex, m_OutLineColor, m_OutLineOffsetX, m_OutLineOffsetY, toFill); ApplyShadowZeroAlloc(ref rVertex, m_OutLineColor, m_OutLineOffsetX, -m_OutLineOffsetY, toFill); ApplyShadowZeroAlloc(ref rVertex, m_OutLineColor, -m_OutLineOffsetX, m_OutLineOffsetY, toFill); ApplyShadowZeroAlloc(ref rVertex, m_OutLineColor, -m_OutLineOffsetX, -m_OutLineOffsetY, toFill); toFill.AddUIVertexQuad(rVertex); } } } } private void ApplyShadowZeroAlloc(ref UIVertex[] rVertex, Color rEffectColor, float rEffectDistanceX, float rEffectDistanceY, VertexHelper rHelper) { for (int i = 0; i < rVertex.Length; i++) { Vector3 rPosition = rVertex[i].position; rPosition.x += rEffectDistanceX; rPosition.y += rEffectDistanceY; rVertex[i].position = rPosition; rVertex[i].color = rEffectColor; } rHelper.AddUIVertexQuad(rVertex); for (int i = 0; i < rVertex.Length; i++) { Vector3 rPosition = rVertex[i].position; rPosition.x -= rEffectDistanceX; rPosition.y -= rEffectDistanceY; rVertex[i].color = color; rVertex[i].position = rPosition; } } }
Shader優化
OutlineEx.shader
Shader "TSF Shaders/UI/OutlineEx" { Properties { _MainTex("Main Texture", 2D) = "white" {} _Color("Tint", Color) = (1, 1, 1, 1) // 描邊顏色和寬度 _OutlineColor("Outline Color", Color) = (1, 1, 1, 1) _OutlineWidth("Outline Width", Int) = 1 _StencilComp("Stencil Comparison", Float) = 8 _Stencil("Stencil ID", Float) = 0 _StencilOp("Stencil Operation", Float) = 0 _StencilWriteMask("Stencil Write Mask", Float) = 255 _StencilReadMask("Stencil Read Mask", Float) = 255 _ColorMask("Color Mask", Float) = 15 [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip("Use Alpha Clip", Float) = 0 } SubShader { Tags { "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" "PreviewType" = "Plane" "CanUseSpriteAtlas" = "True" } Stencil { Ref[_Stencil] Comp[_StencilComp] Pass[_StencilOp] ReadMask[_StencilReadMask] WriteMask[_StencilWriteMask] } Cull Off Lighting Off ZWrite Off ZTest[unity_GUIZTestMode] Blend SrcAlpha OneMinusSrcAlpha ColorMask[_ColorMask] Pass { Name "OUTLINE" CGPROGRAM #pragma vertex vert #pragma fragment frag sampler2D _MainTex; fixed4 _Color; fixed4 _TextureSampleAdd; float4 _MainTex_TexelSize; float4 _OutlineColor; int _OutlineWidth; struct appdata { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; float2 texcoord1 : TEXCOORD1; float2 texcoord2 : TEXCOORD2; fixed4 color : COLOR; }; struct v2f { float4 vertex : SV_POSITION; float2 texcoord : TEXCOORD0; float2 uvOriginXY : TEXCOORD1; float2 uvOriginZW : TEXCOORD2; fixed4 color : COLOR; }; v2f vert(appdata IN) { v2f o; o.vertex = UnityObjectToClipPos(IN.vertex); o.texcoord = IN.texcoord; o.uvOriginXY = IN.texcoord1; o.uvOriginZW = IN.texcoord2; o.color = IN.color * _Color; return o; } // 檢查點是否在給定矩形內 fixed IsInRect(float2 pPos, float4 pClipRect) { // step函式a>b返回0,否則返回1 pPos = step(pClipRect.xy, pPos) * step(pPos, pClipRect.zw); return pPos.x * pPos.y; } // 根據圓的引數方程計算取樣座標,使用alpha值進行顏色混合 fixed SampleAlpha(int pIndex, v2f IN) { const fixed sinArray[12] = { 0, 0.5, 0.866, 1, 0.866, 0.5, 0, -0.5, -0.866, -1, -0.866, -0.5 }; const fixed cosArray[12] = { 1, 0.866, 0.5, 0, -0.5, -0.866, -1, -0.866, -0.5, 0, 0.5, 0.866 }; float2 pos = IN.texcoord + _MainTex_TexelSize.xy * float2(cosArray[pIndex], sinArray[pIndex]) * _OutlineWidth; return IsInRect(pos, float4(IN.uvOriginXY, IN.uvOriginZW)) * (tex2D(_MainTex, pos) + _TextureSampleAdd).w * _OutlineColor.w; } fixed4 frag(v2f IN) : SV_Target { fixed4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color; if (_OutlineWidth > 0) { color.w *= IsInRect(IN.texcoord, float4(IN.uvOriginXY, IN.uvOriginZW)); half4 val = half4(_OutlineColor.x, _OutlineColor.y, _OutlineColor.z, 0); val.w += SampleAlpha(0, IN); val.w += SampleAlpha(1, IN); val.w += SampleAlpha(2, IN); val.w += SampleAlpha(3, IN); val.w += SampleAlpha(4, IN); val.w += SampleAlpha(5, IN); val.w += SampleAlpha(6, IN); val.w += SampleAlpha(7, IN); val.w += SampleAlpha(8, IN); val.w += SampleAlpha(9, IN); val.w += SampleAlpha(10, IN); val.w += SampleAlpha(11, IN); val.w = clamp(val.w, 0, 1); color = (val * (1.0 - color.a)) + (color * color.a); color.a = saturate(color.a); color.a *= IN.color.a; } return color; } ENDCG } } }
OutlineEx.cs
//————————————————————————————————————————————
// OutlineEx.cs
//
// Created by Chiyu Ren on 2018/9/12 23:03:51
//————————————————————————————————————————————
using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
namespace TooSimpleFramework.UI
{
/// <summary>
/// UGUI描邊
/// </summary>
public class Outline : BaseMeshEffect
{
public Color OutlineColor = Color.white;
[Range(0, 6)]
public int OutlineWidth = 0;
public Shader OutlineShader;
private static List<UIVertex> m_VetexList = new List<UIVertex>();
protected override void Start()
{
base.Start();
var shader = OutlineShader != null ? OutlineShader : Shader.Find("TSF Shaders/UI/OutlineEx");
base.graphic.material = new Material(shader);
// 修改additionalShaderChannels屬性,將uv1和uv2傳入shader
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()
{
base.graphic.material.SetColor("_OutlineColor", this.OutlineColor);
base.graphic.material.SetInt("_OutlineWidth", this.OutlineWidth);
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 += pUVX / pTriangleX.magnitude * posXOffset * (Vector2.Dot(pTriangleX, Vector2.right) > 0 ? 1 : -1);
uv += pUVY / pTriangleY.magnitude * posYOffset * (Vector2.Dot(pTriangleY, Vector2.up) > 0 ? 1 : -1);
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));
}
}
}
文字漸變
Gradient.cs 由上到下漸變
// 漸變效果
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
[AddComponentMenu("UI/Effects/Gradient", 13)]
public class Gradient : BaseMeshEffect
{
[SerializeField] private Color32 m_TopColor = Color.white;
[SerializeField] private Color32 m_BottomColor = Color.black;
public Color32 topColor
{
get { return m_TopColor; }
set { m_TopColor = value; }
}
public Color32 bottomColor
{
get { return m_BottomColor; }
set { m_BottomColor = value; }
}
public override void ModifyMesh(VertexHelper vh)
{
if (!this.IsActive())
return;
List<UIVertex> vertexList = new List<UIVertex>();
vh.GetUIVertexStream(vertexList);
ModifyVertices(vertexList);
vh.Clear();
vh.AddUIVertexTriangleStream(vertexList);
}
public void ModifyVertices(List<UIVertex> vertexList)
{
if (!IsActive() || vertexList.Count <= 0)
{
return;
}
for (int i = 0; i < vertexList.Count;)
{
float bottomY = vertexList[i].position.y;
float topY = bottomY;
float dis = 1f;
for (int k = 1; k < 6; k++)
{
float y = vertexList[k + i].position.y;
if (y > topY)
{
topY = y;
}
else if (y < bottomY)
{
bottomY = y;
}
}
dis = topY - bottomY;
for (int k = 0; k < 6; k++)
{
UIVertex vertText = vertexList[k + i];
vertText.color = Color32.Lerp(m_BottomColor, m_TopColor, (vertText.position.y - bottomY) / dis);
vertexList[k + i] = vertText;
}
i += 6;
}
}
}
TextGradient.cs 支援橫向,縱向,左上至右下,左下至右上漸變
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
[RequireComponent(typeof(Text))]
public class TextGradient : BaseMeshEffect
{
public enum GradientDirection { Horizontal, Vertical,LeftUpToRightDown,LeftDownToRightUp }
[SerializeField] //定義序列化屬性,一會的Editor中需要通過定義的這個屬性找到該欄位
public Color32 topColor = Color.white;//頂部顏色
[SerializeField]
public Color32 bottomColor = Color.black;//底部顏色
[SerializeField]
public GradientDirection gradientDirection;//漸變方向
[SerializeField]
public bool useEffect = false;//是否使用陰影
[SerializeField]
public Color effectColor = new Color(0f, 0f, 0f, 0.5f);//陰影顏色
[SerializeField]
public Vector2 effectDistance = new Vector2(1f, -1f);//陰影偏移
private const int DefautlVertexNumPerFont = 6;//頂點數
List<UIVertex> vertexBuffers = new List<UIVertex>();
public Mesh mesh = null;
/// <summary>
/// 給頂點著色
/// </summary>
/// <param name="vertexList"></param>
/// <param name="index"></param>
/// <param name="color"></param>
private void ModifyVertexColor(List<UIVertex> vertexList, int index, Color color)
{
UIVertex temp = vertexList[index];
temp.color = color;
vertexList[index] = temp;
}
//修改網格時呼叫
public override void ModifyMesh(VertexHelper vh)
{
if (!IsActive())
{
return;
}
vh.GetUIVertexStream(vertexBuffers);//獲取頂點
Debug.Log(vertexBuffers.Count);
//在Inspector中顯示網格
if (mesh == null)
{
mesh = new Mesh();
}
vh.FillMesh(mesh);
int count = vertexBuffers.Count;
if (count > 0)
{
/**給頂點著色( 這裡需要明白頂點的順序 )
* 5-0 ---- 1
* | \ |
* | \ |
* | \ |
* | \ |
* 4-----3-2
**/
for (int i = 0; i < count; i += DefautlVertexNumPerFont)
{
//分別設定每個頂點的顏色
switch (gradientDirection)
{
case GradientDirection.Horizontal:
ModifyVertexColor(vertexBuffers, i, topColor);
ModifyVertexColor(vertexBuffers, i + 1, topColor);
ModifyVertexColor(vertexBuffers, i + 2, bottomColor);
ModifyVertexColor(vertexBuffers, i + 3, bottomColor);
ModifyVertexColor(vertexBuffers, i + 4, bottomColor);
ModifyVertexColor(vertexBuffers, i + 5, topColor);
break;
case GradientDirection.Vertical:
ModifyVertexColor(vertexBuffers, i, topColor);
ModifyVertexColor(vertexBuffers, i + 1, bottomColor);
ModifyVertexColor(vertexBuffers, i + 2, bottomColor);
ModifyVertexColor(vertexBuffers, i + 3, bottomColor);
ModifyVertexColor(vertexBuffers, i + 4, topColor);
ModifyVertexColor(vertexBuffers, i + 5, topColor);
break;
case GradientDirection.LeftUpToRightDown:
ModifyVertexColor(vertexBuffers, i, topColor);
ModifyVertexColor(vertexBuffers, i + 1, bottomColor);
ModifyVertexColor(vertexBuffers, i + 2, topColor);
ModifyVertexColor(vertexBuffers, i + 3, topColor);
ModifyVertexColor(vertexBuffers, i + 4, bottomColor);
ModifyVertexColor(vertexBuffers, i + 5, topColor);
break;
case GradientDirection.LeftDownToRightUp:
ModifyVertexColor(vertexBuffers, i, bottomColor);
ModifyVertexColor(vertexBuffers, i + 1, topColor);
ModifyVertexColor(vertexBuffers, i + 2, bottomColor);
ModifyVertexColor(vertexBuffers, i + 3, bottomColor);
ModifyVertexColor(vertexBuffers, i + 4, topColor);
ModifyVertexColor(vertexBuffers, i + 5, bottomColor);
break;
default:
break;
}
}
}
if (useEffect)//是否使用陰影(如果不需要陰影功能可以這部分程式碼刪掉)
{
//擴充一倍的頂點容量
var neededCapacity = vertexBuffers.Count * 2;
if (vertexBuffers.Capacity < neededCapacity)
vertexBuffers.Capacity = neededCapacity;
for (int i = 0, cnt = vertexBuffers.Count; i < cnt; ++i)
{
var vt = vertexBuffers[i];
vertexBuffers.Add(vt);
Vector3 v = vt.position;
v.x += effectDistance.x;
v.y += effectDistance.y;
vt.position = v;
vt.color = effectColor;
vertexBuffers[i] = vt;
}
}
vh.Clear();
//這個方法向VertexHelper中批量增加三角形頂點資料,引數的長度必須是三的倍數
vh.AddUIVertexTriangleStream(vertexBuffers);
}
/// <summary>
/// 在Scene中顯示頂點
/// </summary>
void OnDrawGizmos()
{
Gizmos.color = Color.red;//設定顏色
for (int i = 0; i < vertexBuffers.Count; i++)
{
//把mesh頂點轉為世界座標
Vector3 targetPosition = transform.TransformPoint(vertexBuffers[i].position);
Gizmos.DrawSphere(targetPosition, 5f);
}
}
}