using System; using System.Collections.Generic; using UnityEngine; [ExecuteInEditMode] [AddComponentMenu("NGUI/Internal/Draw Call")] public class UIDrawCall : MonoBehaviour { public enum Clipping { None = 0, TextureMask = 1, SoftClip = 3, ConstrainButDontClip = 4 } public delegate void OnRenderCallback(Material mat); private static BetterList mActiveList = new BetterList(); private static BetterList mInactiveList = new BetterList(); [NonSerialized] [HideInInspector] public int widgetCount; [NonSerialized] [HideInInspector] public UIPanel manager; [NonSerialized] [HideInInspector] public UIPanel panel; private Material mMaterial; private Texture mTexture; private Shader mShader; private int mClipCount; private MeshRenderer mRenderer; private Material mDynamicMat; private bool mRebuildMat = true; private bool mLegacyShader; private int mRenderQueue = 3000; [NonSerialized] public bool isDirty; [NonSerialized] private bool mTextureClip; private static List mCache = new List(10); private static int[] ClipRange = null; private static int[] ClipArgs = null; public int renderQueue { get { return mRenderQueue; } set { if (mRenderQueue != value) { mRenderQueue = value; if (mDynamicMat != null) { mDynamicMat.renderQueue = value; } } } } public int sortingOrder { get { if (!(mRenderer != null)) { return 0; } return mRenderer.sortingOrder; } set { if (mRenderer != null && mRenderer.sortingOrder != value) { mRenderer.sortingOrder = value; } } } public Material baseMaterial { get { return mMaterial; } set { if (mMaterial != value) { mMaterial = value; mRebuildMat = true; } } } public Texture mainTexture { get { return mTexture; } set { mTexture = value; if (mDynamicMat != null) { mDynamicMat.mainTexture = value; } } } public Shader shader { get { return mShader; } set { if (mShader != value) { mShader = value; mRebuildMat = true; } } } public bool isClipped => mClipCount != 0; private void CreateMaterial() { mTextureClip = false; mLegacyShader = false; mClipCount = ((panel != null) ? panel.clipCount : 0); string text = ((mShader != null) ? mShader.name : ((mMaterial != null) ? mMaterial.shader.name : "Unlit/Transparent Colored")); text = text.Replace("GUI/Text Shader", "Unlit/Text"); if (text.Length > 2 && text[text.Length - 2] == ' ') { int num = text[text.Length - 1]; if (num > 48 && num <= 57) { text = text.Substring(0, text.Length - 2); } } if (text.StartsWith("Hidden/")) { text = text.Substring(7); } text = text.Replace(" (SoftClip)", ""); text = text.Replace(" (TextureClip)", ""); if (panel != null && panel.clipping == Clipping.TextureMask) { mTextureClip = true; shader = Shader.Find("Hidden/" + text + " (TextureClip)"); } else if (mClipCount != 0) { shader = Shader.Find("Hidden/" + text + " " + mClipCount); if (shader == null) { shader = Shader.Find(text + " " + mClipCount); } if (shader == null && mClipCount == 1) { mLegacyShader = true; shader = Shader.Find(text + " (SoftClip)"); } } else { shader = Shader.Find(text); } if (shader == null) { shader = Shader.Find("Unlit/Transparent Colored"); } if (mMaterial != null) { if (IsWizardMaterial()) { mDynamicMat = new Material(mMaterial); mDynamicMat.EnableKeyword("USE_VERTEX_COLOR"); mDynamicMat.SetFloat("_SleeveSrcFactor", 5f); mDynamicMat.SetFloat("_SleeveDstFactor", 10f); mDynamicMat.SetFloat("_CullMode", 0f); mDynamicMat.SetFloat("_ZWriteMode", 0f); mLegacyShader = false; if (isClipped) { mDynamicMat.EnableKeyword("USE_CLIP"); } if (IsSleeveMaterial()) { mDynamicMat.EnableKeyword("USE_SLEEVE"); } mDynamicMat.shader = Shader.Find(mMaterial.shader.name); } else { mDynamicMat = new Material(mMaterial); mDynamicMat.name = "[NGUI] " + mMaterial.name; mDynamicMat.hideFlags = HideFlags.DontSave | HideFlags.NotEditable; mDynamicMat.CopyPropertiesFromMaterial(mMaterial); string[] shaderKeywords = mMaterial.shaderKeywords; for (int i = 0; i < shaderKeywords.Length; i++) { mDynamicMat.EnableKeyword(shaderKeywords[i]); } if (shader != null) { mDynamicMat.shader = shader; } else if (mClipCount != 0) { Debug.LogError(text + " shader doesn't have a clipped shader version for " + mClipCount + " clip regions"); } } } else { mDynamicMat = new Material(shader); mDynamicMat.name = "[NGUI] " + shader.name; mDynamicMat.hideFlags = HideFlags.DontSave | HideFlags.NotEditable; } } private bool IsWizardMaterial() { if (mMaterial.shader.name == "Wizard/VariantSleeveShader") { return true; } return false; } private bool IsSleeveMaterial() { if (mMaterial.name.Contains("sleeve")) { return true; } return false; } private Material RebuildMaterial() { NGUITools.DestroyImmediate(mDynamicMat); CreateMaterial(); mDynamicMat.renderQueue = mRenderQueue; if (mTexture != null) { mDynamicMat.mainTexture = mTexture; } if (mRenderer != null) { mRenderer.sharedMaterials = new Material[1] { mDynamicMat }; } return mDynamicMat; } private void Awake() { if (ClipRange == null) { ClipRange = new int[4] { Shader.PropertyToID("_ClipRange0"), Shader.PropertyToID("_ClipRange1"), Shader.PropertyToID("_ClipRange2"), Shader.PropertyToID("_ClipRange4") }; } if (ClipArgs == null) { ClipArgs = new int[4] { Shader.PropertyToID("_ClipArgs0"), Shader.PropertyToID("_ClipArgs1"), Shader.PropertyToID("_ClipArgs2"), Shader.PropertyToID("_ClipArgs3") }; } } private static UIDrawCall Create(string name) { if (mInactiveList.size > 0) { UIDrawCall uIDrawCall = mInactiveList.Pop(); mActiveList.Add(uIDrawCall); if (name != null) { uIDrawCall.name = name; } NGUITools.SetActive(uIDrawCall.gameObject, state: true); return uIDrawCall; } GameObject obj = new GameObject(name); UnityEngine.Object.DontDestroyOnLoad(obj); UIDrawCall uIDrawCall2 = obj.AddComponent(); mActiveList.Add(uIDrawCall2); return uIDrawCall2; } public static void ReleaseInactive() { int num = mInactiveList.size; while (num > 0) { UIDrawCall uIDrawCall = mInactiveList[--num]; if ((bool)uIDrawCall) { NGUITools.DestroyImmediate(uIDrawCall.gameObject); } } mInactiveList.Clear(); } }