//---------------------------------------------- // NGUI: Next-Gen UI kit // Copyright © 2011-2015 Tasharen Entertainment //---------------------------------------------- #define FUNCELL_MODIFIED using UnityEngine; using System.Collections.Generic; /// /// If you don't have or don't wish to create an atlas, you can simply use this script to draw a texture. /// Keep in mind though that this will create an extra draw call with each UITexture present, so it's /// best to use it only for backgrounds or temporary visible widgets. /// [ExecuteInEditMode] [AddComponentMenu("NGUI/UI/NGUI Texture")] public class UITexture : UIBasicSprite { [HideInInspector][SerializeField] Rect mRect = new Rect(0f, 0f, 1f, 1f); [HideInInspector][SerializeField] Texture mTexture; [HideInInspector][SerializeField] Material mMat; #if FUNCELL_MODIFIED //这里把Shader不进行序列化处理,也没必要进行Shader的缓存 [HideInInspector] Shader mShader; #else [HideInInspector][SerializeField] Shader mShader; #endif [HideInInspector][SerializeField] Vector4 mBorder = Vector4.zero; [HideInInspector][SerializeField] bool mFixedAspect = false; [System.NonSerialized] int mPMA = -1; /// /// Texture used by the UITexture. You can set it directly, without the need to specify a material. /// public override Texture mainTexture { get { if (mTexture != null) return mTexture; if (mMat != null) return mMat.mainTexture; return null; } set { if (mTexture != value) { if (drawCall != null && drawCall.widgetCount == 1 && mMat == null) { mTexture = value; drawCall.mainTexture = value; } else { RemoveFromPanel(); mTexture = value; mPMA = -1; MarkAsChanged(); } } } } /// /// Material used by the widget. /// public override Material material { get { return mMat; } set { if (mMat != value) { RemoveFromPanel(); mShader = null; mMat = value; mPMA = -1; MarkAsChanged(); } } } /// /// Shader used by the texture when creating a dynamic material (when the texture was specified, but the material was not). /// public override Shader shader { get { if (mMat != null) return mMat.shader; #if NGUI_USE_RGB if (mShader == null) mShader = Shader.Find("Unlit/Transparent Colored");//_RGB 这里不使用RGB,因为纹理图片暂时先不做区分,以后可以做进一步的处理 #else if (mShader == null) mShader = Shader.Find("Unlit/Transparent Colored"); #endif return mShader; } set { if (mShader != value) { if (drawCall != null && drawCall.widgetCount == 1 && mMat == null) { mShader = value; drawCall.shader = value; } else { RemoveFromPanel(); mShader = value; mPMA = -1; mMat = null; MarkAsChanged(); } } } } /// /// Whether the texture is using a premultiplied alpha material. /// public override bool premultipliedAlpha { get { if (mPMA == -1) { Material mat = material; mPMA = (mat != null && mat.shader != null && mat.shader.name.Contains("Premultiplied")) ? 1 : 0; } return (mPMA == 1); } } /// /// Sprite's border. X = left, Y = bottom, Z = right, W = top. /// public override Vector4 border { get { return mBorder; } set { if (mBorder != value) { mBorder = value; MarkAsChanged(); } } } /// /// UV rectangle used by the texture. /// public Rect uvRect { get { return mRect; } set { if (mRect != value) { mRect = value; MarkAsChanged(); } } } /// /// Widget's dimensions used for drawing. X = left, Y = bottom, Z = right, W = top. /// This function automatically adds 1 pixel on the edge if the texture's dimensions are not even. /// It's used to achieve pixel-perfect sprites even when an odd dimension widget happens to be centered. /// public override Vector4 drawingDimensions { get { Vector2 offset = pivotOffset; float x0 = -offset.x * mWidth; float y0 = -offset.y * mHeight; float x1 = x0 + mWidth; float y1 = y0 + mHeight; if (mTexture != null && mType != UISprite.Type.Tiled) { int w = mTexture.width; int h = mTexture.height; int padRight = 0; int padTop = 0; float px = 1f; float py = 1f; if (w > 0 && h > 0 && (mType == UISprite.Type.Simple || mType == UISprite.Type.Filled)) { if ((w & 1) != 0) ++padRight; if ((h & 1) != 0) ++padTop; px = (1f / w) * mWidth; py = (1f / h) * mHeight; } if (mFlip == UISprite.Flip.Horizontally || mFlip == UISprite.Flip.Both) { x0 += padRight * px; } else x1 -= padRight * px; if (mFlip == UISprite.Flip.Vertically || mFlip == UISprite.Flip.Both) { y0 += padTop * py; } else y1 -= padTop * py; } float fw, fh; if (mFixedAspect) { fw = 0f; fh = 0f; } else { Vector4 br = border; fw = br.x + br.z; fh = br.y + br.w; } float vx = Mathf.Lerp(x0, x1 - fw, mDrawRegion.x); float vy = Mathf.Lerp(y0, y1 - fh, mDrawRegion.y); float vz = Mathf.Lerp(x0 + fw, x1, mDrawRegion.z); float vw = Mathf.Lerp(y0 + fh, y1, mDrawRegion.w); return new Vector4(vx, vy, vz, vw); } } /// /// Whether the drawn texture will always maintain a fixed aspect ratio. /// This setting is not compatible with drawRegion adjustments (sliders, progress bars, etc). /// public bool fixedAspect { get { return mFixedAspect; } set { if (mFixedAspect != value) { mFixedAspect = value; mDrawRegion = new Vector4(0f, 0f, 1f, 1f); MarkAsChanged(); } } } /// /// Adjust the scale of the widget to make it pixel-perfect. /// public override void MakePixelPerfect () { base.MakePixelPerfect(); if (mType == Type.Tiled) return; Texture tex = mainTexture; if (tex == null) return; if (mType == Type.Simple || mType == Type.Filled || !hasBorder) { if (tex != null) { int w = tex.width; int h = tex.height; if ((w & 1) == 1) ++w; if ((h & 1) == 1) ++h; width = w; height = h; } } } /// /// Adjust the draw region if the texture is using a fixed aspect ratio. /// protected override bool OnUpdate () { var result = base.OnUpdate(); if (mFixedAspect) { Texture tex = mainTexture; if (tex != null) { int w = tex.width; int h = tex.height; if ((w & 1) == 1) ++w; if ((h & 1) == 1) ++h; float widgetWidth = mWidth; float widgetHeight = mHeight; float widgetAspect = widgetWidth / widgetHeight; float textureAspect = (float)w / h; if (textureAspect < widgetAspect) { float x = (widgetWidth - widgetHeight * textureAspect) / widgetWidth * 0.5f; drawRegion = new Vector4(x, 0f, 1f - x, 1f); } else { float y = (widgetHeight - widgetWidth / textureAspect) / widgetHeight * 0.5f; drawRegion = new Vector4(0f, y, 1f, 1f - y); } } } return result; } /// /// Virtual function called by the UIPanel that fills the buffers. /// public override void OnFill(BetterList verts, BetterList uvs, BetterList cols) { Texture tex = mainTexture; #if FUNCELL_MODIFIED if (tex == null && mMat == null) return; int texW = 1; int texH = 1; if (tex != null) { texW = tex.width; texH = tex.height; } Rect outer = new Rect(mRect.x * texW, mRect.y * texH, texW * mRect.width, texH * mRect.height); #else if (tex == null) return; Rect outer = new Rect(mRect.x * tex.width, mRect.y * tex.height, tex.width * mRect.width, tex.height * mRect.height); #endif Rect inner = outer; Vector4 br = border; inner.xMin += br.x; inner.yMin += br.y; inner.xMax -= br.z; inner.yMax -= br.w; #if FUNCELL_MODIFIED float w = 1f / texW; float h = 1f / texH; #else float w = 1f / tex.width; float h = 1f / tex.height; #endif outer.xMin *= w; outer.xMax *= w; outer.yMin *= h; outer.yMax *= h; inner.xMin *= w; inner.xMax *= w; inner.yMin *= h; inner.yMax *= h; int offset = verts != null ? verts.size : 0; Fill(verts, uvs, cols, outer, inner); if (onPostFill != null) //优化NGUI GC //because we might change geometry's verts uvs cols value in Fill onPostFill(this, offset, geometry.verts, geometry.uvs, geometry.cols); //#else //onPostFill(this, offset, verts, uvs, cols); //优化NGUI GC } }