コード例 #1
0
        /// <summary>
        /// Populate the MaterialEditor UI
        /// </summary>
        /// <param name="go">GameObject for which to read the renderers and materials</param>
        /// <param name="data">Object that will be passed through to the get/set/reset events</param>
        /// <param name="filter">Comma separated list of text to filter the results</param>
        protected void PopulateList(GameObject go, object data, string filter = "")
        {
            MaterialEditorWindow.gameObject.SetActive(true);
            MaterialEditorWindow.GetComponent <CanvasScaler>().referenceResolution = new Vector2(1920f / UIScale.Value, 1080f / UIScale.Value);
            SetMainRectWithMemory(0.05f, 0.05f, UIWidth.Value * UIScale.Value, UIHeight.Value * UIScale.Value);
            FilterInputField.Set(filter);

            CurrentGameObject = go;
            CurrentData       = data;
            CurrentFilter     = filter;

            if (go == null)
            {
                return;
            }

            List <Renderer>               rendList     = new List <Renderer>();
            IEnumerable <Renderer>        rendListFull = GetRendererList(go);
            List <string>                 filterList   = new List <string>();
            List <ItemInfo>               items        = new List <ItemInfo>();
            Dictionary <string, Material> matList      = new Dictionary <string, Material>();

            if (!filter.IsNullOrEmpty())
            {
                filterList = filter.Split(',').ToList();
            }
            filterList.RemoveAll(x => x.IsNullOrWhiteSpace());

            //Get all renderers and materials matching the filter
            if (filterList.Count == 0)
            {
                rendList = rendListFull.ToList();
            }
            else
            {
                foreach (var rend in rendListFull)
                {
                    for (var j = 0; j < filterList.Count; j++)
                    {
                        var filterWord = filterList[j];
                        if (rend.NameFormatted().ToLower().Contains(filterWord.Trim().ToLower()) && !rendList.Contains(rend))
                        {
                            rendList.Add(rend);
                        }
                    }

                    foreach (var mat in GetMaterials(go, rend))
                    {
                        for (var k = 0; k < filterList.Count; k++)
                        {
                            var filterWord = filterList[k];
                            if (mat.NameFormatted().ToLower().Contains(filterWord.Trim().ToLower()))
                            {
                                matList[mat.NameFormatted()] = mat;
                            }
                        }
                    }
                }
            }

            for (var i = 0; i < rendList.Count; i++)
            {
                var rend = rendList[i];
                //Get materials if materials list wasn't previously built by the filter
                if (filterList.Count == 0)
                {
                    foreach (var mat in GetMaterials(go, rend))
                    {
                        matList[mat.NameFormatted()] = mat;
                    }
                }

                var rendererItem = new ItemInfo(ItemInfo.RowItemType.Renderer, "Renderer")
                {
                    RendererName     = rend.NameFormatted(),
                    ExportUVOnClick  = () => Export.ExportUVMaps(rend),
                    ExportObjOnClick = () => Export.ExportObj(rend)
                };
                items.Add(rendererItem);

                //Renderer Enabled
                bool valueEnabledOriginal = rend.enabled;
                var  temp = GetRendererPropertyValueOriginal(data, rend, RendererProperties.Enabled, go);
                if (!temp.IsNullOrEmpty())
                {
                    valueEnabledOriginal = temp == "1";
                }
                var rendererEnabledItem = new ItemInfo(ItemInfo.RowItemType.RendererEnabled, "Enabled")
                {
                    RendererEnabled         = rend.enabled ? 1 : 0,
                    RendererEnabledOriginal = valueEnabledOriginal ? 1 : 0,
                    RendererEnabledOnChange = value => SetRendererProperty(data, rend, RendererProperties.Enabled, value.ToString(), go),
                    RendererEnabledOnReset  = () => RemoveRendererProperty(data, rend, RendererProperties.Enabled, go)
                };
                items.Add(rendererEnabledItem);

                //Renderer ShadowCastingMode
                var valueShadowCastingModeOriginal = rend.shadowCastingMode;
                temp = GetRendererPropertyValueOriginal(data, rend, RendererProperties.ShadowCastingMode, go);
                if (!temp.IsNullOrEmpty())
                {
                    valueShadowCastingModeOriginal = (UnityEngine.Rendering.ShadowCastingMode) int.Parse(temp);
                }
                var rendererShadowCastingModeItem = new ItemInfo(ItemInfo.RowItemType.RendererShadowCastingMode, "Shadow Casting Mode")
                {
                    RendererShadowCastingMode         = (int)rend.shadowCastingMode,
                    RendererShadowCastingModeOriginal = (int)valueShadowCastingModeOriginal,
                    RendererShadowCastingModeOnChange = value => SetRendererProperty(data, rend, RendererProperties.ShadowCastingMode, value.ToString(), go),
                    RendererShadowCastingModeOnReset  = () => RemoveRendererProperty(data, rend, RendererProperties.ShadowCastingMode, go)
                };
                items.Add(rendererShadowCastingModeItem);

                //Renderer ReceiveShadows
                bool valueReceiveShadowsOriginal = rend.receiveShadows;
                temp = GetRendererPropertyValueOriginal(data, rend, RendererProperties.ShadowCastingMode, go);
                if (!temp.IsNullOrEmpty())
                {
                    valueReceiveShadowsOriginal = temp == "1";
                }
                var rendererReceiveShadowsItem = new ItemInfo(ItemInfo.RowItemType.RendererReceiveShadows, "Receive Shadows")
                {
                    RendererReceiveShadows         = rend.receiveShadows ? 1 : 0,
                    RendererReceiveShadowsOriginal = valueReceiveShadowsOriginal ? 1 : 0,
                    RendererReceiveShadowsOnChange = value => SetRendererProperty(data, rend, RendererProperties.ReceiveShadows, value.ToString(), go),
                    RendererReceiveShadowsOnReset  = () => RemoveRendererProperty(data, rend, RendererProperties.ReceiveShadows, go)
                };
                items.Add(rendererReceiveShadowsItem);
            }

            foreach (var mat in matList.Values)
            {
                string materialName = mat.NameFormatted();
                string shaderName   = mat.shader.NameFormatted();

                var materialItem = new ItemInfo(ItemInfo.RowItemType.Material, "Material")
                {
                    MaterialName    = materialName,
                    MaterialOnCopy  = () => MaterialCopyEdits(data, mat, go),
                    MaterialOnPaste = () =>
                    {
                        MaterialPasteEdits(data, mat, go);
                        PopulateList(go, data, filter);
                    }
                };
                materialItem.MaterialOnCopyRemove = () =>
                {
                    CopyMaterial(go, materialName);
                    PopulateList(go, data, filter);
                };
                items.Add(materialItem);

                //Shader
                string shaderNameOriginal = shaderName;
                var    temp = GetMaterialShaderNameOriginal(data, mat, go);
                if (!temp.IsNullOrEmpty())
                {
                    shaderNameOriginal = temp;
                }
                var shaderItem = new ItemInfo(ItemInfo.RowItemType.Shader, "Shader")
                {
                    ShaderName         = shaderName,
                    ShaderNameOriginal = shaderNameOriginal,
                    ShaderNameOnChange = value =>
                    {
                        SetMaterialShaderName(data, mat, value, go);
                        StartCoroutine(PopulateListCoroutine(go, data, filter));
                    },
                    ShaderNameOnReset = () =>
                    {
                        RemoveMaterialShaderName(data, mat, go);
                        StartCoroutine(PopulateListCoroutine(go, data, filter));
                    }
                };
                items.Add(shaderItem);

                //Shader RenderQueue
                int renderQueueOriginal     = mat.renderQueue;
                int?renderQueueOriginalTemp = GetMaterialShaderRenderQueueOriginal(data, mat, go);
                renderQueueOriginal = renderQueueOriginalTemp ?? renderQueueOriginal;
                var shaderRenderQueueItem = new ItemInfo(ItemInfo.RowItemType.ShaderRenderQueue, "Render Queue")
                {
                    ShaderRenderQueue         = mat.renderQueue,
                    ShaderRenderQueueOriginal = renderQueueOriginal,
                    ShaderRenderQueueOnChange = value => SetMaterialShaderRenderQueue(data, mat, value, go),
                    ShaderRenderQueueOnReset  = () => RemoveMaterialShaderRenderQueue(data, mat, go)
                };
                items.Add(shaderRenderQueueItem);

                foreach (var property in XMLShaderProperties[XMLShaderProperties.ContainsKey(shaderName) ? shaderName : "default"].OrderBy(x => x.Value.Type).ThenBy(x => x.Key))
                {
                    string propertyName = property.Key;
                    if (Instance.CheckBlacklist(materialName, propertyName))
                    {
                        continue;
                    }

                    if (property.Value.Type == ShaderPropertyType.Texture)
                    {
                        if (mat.HasProperty($"_{propertyName}"))
                        {
                            var textureItem = new ItemInfo(ItemInfo.RowItemType.TextureProperty, propertyName)
                            {
                                TextureChanged  = !GetMaterialTextureValueOriginal(data, mat, propertyName, go),
                                TextureExists   = mat.GetTexture($"_{propertyName}") != null,
                                TextureOnExport = () => ExportTexture(mat, propertyName)
                            };
                            textureItem.TextureOnImport = () =>
                            {
                                OpenFileDialog.Show(OnFileAccept, "Open image", Application.dataPath, FileFilter);

                                void OnFileAccept(string[] strings)
                                {
                                    if (strings == null || strings.Length == 0 || strings[0].IsNullOrEmpty())
                                    {
                                        textureItem.TextureChanged = !GetMaterialTextureValueOriginal(data, mat, propertyName, go);
                                        textureItem.TextureExists  = mat.GetTexture($"_{propertyName}") != null;
                                        return;
                                    }
                                    string filePath = strings[0];

                                    SetMaterialTexture(data, mat, propertyName, filePath, go);

                                    TexChangeWatcher?.Dispose();
                                    if (WatchTexChanges.Value)
                                    {
                                        var directory = Path.GetDirectoryName(filePath);
                                        if (directory != null)
                                        {
                                            TexChangeWatcher          = new FileSystemWatcher(directory, Path.GetFileName(filePath));
                                            TexChangeWatcher.Changed += (sender, args) =>
                                            {
                                                if (WatchTexChanges.Value && File.Exists(filePath))
                                                {
                                                    SetMaterialTexture(data, mat, propertyName, filePath, go);
                                                }
                                            };
                                            TexChangeWatcher.Deleted            += (sender, args) => TexChangeWatcher?.Dispose();
                                            TexChangeWatcher.Error              += (sender, args) => TexChangeWatcher?.Dispose();
                                            TexChangeWatcher.EnableRaisingEvents = true;
                                        }
                                    }
                                }
                            };
                            textureItem.TextureOnReset = () => RemoveMaterialTexture(data, mat, propertyName, go);
                            items.Add(textureItem);

                            Vector2 textureOffset             = mat.GetTextureOffset($"_{propertyName}");
                            Vector2 textureOffsetOriginal     = textureOffset;
                            Vector2?textureOffsetOriginalTemp = GetMaterialTextureOffsetOriginal(data, mat, propertyName, go);
                            if (textureOffsetOriginalTemp != null)
                            {
                                textureOffsetOriginal = (Vector2)textureOffsetOriginalTemp;
                            }

                            Vector2 textureScale             = mat.GetTextureScale($"_{propertyName}");
                            Vector2 textureScaleOriginal     = textureScale;
                            Vector2?textureScaleOriginalTemp = GetMaterialTextureScaleOriginal(data, mat, propertyName, go);
                            if (textureScaleOriginalTemp != null)
                            {
                                textureScaleOriginal = (Vector2)textureScaleOriginalTemp;
                            }

                            var textureItemOffsetScale = new ItemInfo(ItemInfo.RowItemType.TextureOffsetScale)
                            {
                                Offset         = textureOffset,
                                OffsetOriginal = textureOffsetOriginal,
                                OffsetOnChange = value => SetMaterialTextureOffset(data, mat, propertyName, value, go),
                                OffsetOnReset  = () => RemoveMaterialTextureOffset(data, mat, propertyName, go),
                                Scale          = textureScale,
                                ScaleOriginal  = textureScaleOriginal,
                                ScaleOnChange  = value => SetMaterialTextureScale(data, mat, propertyName, value, go),
                                ScaleOnReset   = () => RemoveMaterialTextureScale(data, mat, propertyName, go)
                            };
                            items.Add(textureItemOffsetScale);
                        }
                    }
                    else if (property.Value.Type == ShaderPropertyType.Color)
                    {
                        if (mat.HasProperty($"_{propertyName}"))
                        {
                            Color valueColor         = mat.GetColor($"_{propertyName}");
                            Color valueColorOriginal = valueColor;
                            Color?c = GetMaterialColorPropertyValueOriginal(data, mat, propertyName, go);
                            if (c != null)
                            {
                                valueColorOriginal = (Color)c;
                            }
                            var contentItem = new ItemInfo(ItemInfo.RowItemType.ColorProperty, propertyName)
                            {
                                ColorValue         = valueColor,
                                ColorValueOriginal = valueColorOriginal,
                                ColorValueOnChange = value => SetMaterialColorProperty(data, mat, propertyName, value, go),
                                ColorValueOnReset  = () => RemoveMaterialColorProperty(data, mat, propertyName, go)
                            };
                            items.Add(contentItem);
                        }
                    }
                    else if (property.Value.Type == ShaderPropertyType.Float)
                    {
                        if (mat.HasProperty($"_{propertyName}"))
                        {
                            float valueFloat             = mat.GetFloat($"_{propertyName}");
                            float valueFloatOriginal     = valueFloat;
                            float?valueFloatOriginalTemp = GetMaterialFloatPropertyValueOriginal(data, mat, propertyName, go);
                            if (valueFloatOriginalTemp != null)
                            {
                                valueFloatOriginal = (float)valueFloatOriginalTemp;
                            }
                            var contentItem = new ItemInfo(ItemInfo.RowItemType.FloatProperty, propertyName)
                            {
                                FloatValue         = valueFloat,
                                FloatValueOriginal = valueFloatOriginal
                            };
                            if (property.Value.MinValue != null)
                            {
                                contentItem.FloatValueSliderMin = (float)property.Value.MinValue;
                            }
                            if (property.Value.MaxValue != null)
                            {
                                contentItem.FloatValueSliderMax = (float)property.Value.MaxValue;
                            }
                            contentItem.FloatValueOnChange = value => SetMaterialFloatProperty(data, mat, propertyName, value, go);
                            contentItem.FloatValueOnReset  = () => RemoveMaterialFloatProperty(data, mat, propertyName, go);
                            items.Add(contentItem);
                        }
                    }
                }
            }

            VirtualList.SetList(items);
        }
コード例 #2
0
        protected void PopulateList(GameObject gameObject, ObjectType objectType, int coordinateIndex = 0, int slot = 0, FilterType filterType = FilterType.All)
        {
            MaterialEditorWindow.gameObject.SetActive(true);
            MaterialEditorWindow.GetComponent <CanvasScaler>().referenceResolution = new Vector2(1920f / UIScale.Value, 1080f / UIScale.Value);
            MaterialEditorMainPanel.transform.SetRect(0.05f, 0.05f, UIWidth.Value * UIScale.Value, UIHeight.Value * UIScale.Value);

            if (gameObject == null)
            {
                return;
            }
            if (objectType == ObjectType.Hair || objectType == ObjectType.Character)
            {
                coordinateIndex = 0;
            }

            List <Renderer> rendList = new List <Renderer>();
            List <string>   mats     = new List <string>();

            Dictionary <string, Material> matList = new Dictionary <string, Material>();

            var chaControl = gameObject.GetComponent <ChaControl>();

            if (chaControl == null)
            {
                rendList   = GetRendererList(gameObject);
                filterType = FilterType.All;
            }
            else
            {
                if (filterType == FilterType.Body)
                {
                    matList[chaControl.customMatBody.NameFormatted()] = chaControl.customMatBody;
                    rendList.Add(chaControl.rendBody);
                }
                else if (filterType == FilterType.Face)
                {
                    matList[chaControl.customMatFace.NameFormatted()] = chaControl.customMatFace;
                    rendList.Add(chaControl.rendFace);
                }
                else
                {
                    rendList = GetRendererList(gameObject);
                }
            }
            List <ItemInfo> items = new List <ItemInfo>();

            foreach (var rend in rendList)
            {
                foreach (var mat in rend.sharedMaterials)
                {
                    matList[mat.NameFormatted()] = mat;
                }

                var rendererItem = new ItemInfo(ItemInfo.RowItemType.Renderer, "Renderer");
                rendererItem.RendererName = rend.NameFormatted();
                items.Add(rendererItem);

                //Renderer Enabled
                bool valueEnabledOriginal = rend.enabled;
                var  temp = GetRendererPropertyValueOriginal(objectType, coordinateIndex, slot, rend.NameFormatted(), RendererProperties.Enabled);
                if (!temp.IsNullOrEmpty())
                {
                    valueEnabledOriginal = temp == "1";
                }
                var rendererEnabledItem = new ItemInfo(ItemInfo.RowItemType.RendererEnabled, "Enabled");
                rendererEnabledItem.RendererEnabled         = rend.enabled ? 1 : 0;
                rendererEnabledItem.RendererEnabledOriginal = valueEnabledOriginal ? 1 : 0;
                rendererEnabledItem.RendererEnabledOnChange = delegate(int value) { AddRendererProperty(objectType, coordinateIndex, slot, rend.NameFormatted(), RendererProperties.Enabled, value.ToString(), valueEnabledOriginal ? "1" : "0", gameObject); };
                rendererEnabledItem.RendererEnabledOnReset  = delegate { RemoveRendererProperty(objectType, coordinateIndex, slot, rend.NameFormatted(), RendererProperties.Enabled, gameObject); };
                items.Add(rendererEnabledItem);

                //Renderer ShadowCastingMode
                var valueShadowCastingModeOriginal = rend.shadowCastingMode;
                temp = GetRendererPropertyValueOriginal(objectType, coordinateIndex, slot, rend.NameFormatted(), RendererProperties.ShadowCastingMode);
                if (!temp.IsNullOrEmpty())
                {
                    valueShadowCastingModeOriginal = (UnityEngine.Rendering.ShadowCastingMode) int.Parse(temp);
                }
                var rendererShadowCastingModeItem = new ItemInfo(ItemInfo.RowItemType.RendererShadowCastingMode, "Shadow Casting Mode");
                rendererShadowCastingModeItem.RendererShadowCastingMode         = (int)rend.shadowCastingMode;
                rendererShadowCastingModeItem.RendererShadowCastingModeOriginal = (int)valueShadowCastingModeOriginal;
                rendererShadowCastingModeItem.RendererShadowCastingModeOnChange = delegate(int value) { AddRendererProperty(objectType, coordinateIndex, slot, rend.NameFormatted(), RendererProperties.ShadowCastingMode, value.ToString(), ((int)valueShadowCastingModeOriginal).ToString(), gameObject); };
                rendererShadowCastingModeItem.RendererShadowCastingModeOnReset  = delegate { RemoveRendererProperty(objectType, coordinateIndex, slot, rend.NameFormatted(), RendererProperties.ShadowCastingMode, gameObject); };
                items.Add(rendererShadowCastingModeItem);

                //Renderer ReceiveShadows
                bool valueReceiveShadowsOriginal = rend.receiveShadows;
                temp = GetRendererPropertyValueOriginal(objectType, coordinateIndex, slot, rend.NameFormatted(), RendererProperties.ShadowCastingMode);
                if (!temp.IsNullOrEmpty())
                {
                    valueReceiveShadowsOriginal = temp == "1";
                }
                var rendererReceiveShadowsItem = new ItemInfo(ItemInfo.RowItemType.RendererReceiveShadows, "Receive Shadows");
                rendererReceiveShadowsItem.RendererReceiveShadows         = rend.receiveShadows ? 1 : 0;
                rendererReceiveShadowsItem.RendererReceiveShadowsOriginal = valueReceiveShadowsOriginal ? 1 : 0;
                rendererReceiveShadowsItem.RendererReceiveShadowsOnChange = delegate(int value) { AddRendererProperty(objectType, coordinateIndex, slot, rend.NameFormatted(), RendererProperties.ReceiveShadows, value.ToString(), valueReceiveShadowsOriginal ? "1" : "0", gameObject); };
                rendererReceiveShadowsItem.RendererReceiveShadowsOnReset  = delegate { RemoveRendererProperty(objectType, coordinateIndex, slot, rend.NameFormatted(), RendererProperties.ReceiveShadows, gameObject); };
                items.Add(rendererReceiveShadowsItem);
            }

            foreach (var mat in matList.Values)
            {
                string materialName = mat.NameFormatted();
                string shaderName   = mat.shader.NameFormatted();

                var materialItem = new ItemInfo(ItemInfo.RowItemType.Material, "Material");
                materialItem.MaterialName = materialName;
                items.Add(materialItem);

                //Shader
                string shaderNameOriginal = shaderName;
                var    temp = GetMaterialShaderNameOriginal(objectType, coordinateIndex, slot, materialName);
                if (!temp.IsNullOrEmpty())
                {
                    shaderNameOriginal = temp;
                }
                var shaderItem = new ItemInfo(ItemInfo.RowItemType.Shader, "Shader");
                shaderItem.ShaderName         = shaderName;
                shaderItem.ShaderNameOriginal = shaderNameOriginal;
                shaderItem.ShaderNameOnChange = delegate(string value)
                {
                    AddMaterialShaderName(objectType, coordinateIndex, slot, materialName, value, shaderNameOriginal, gameObject);
                    StartCoroutine(PopulateListCoroutine(gameObject, objectType, coordinateIndex, slot, filterType: filterType));
                };
                shaderItem.ShaderNameOnReset = delegate
                {
                    RemoveMaterialShaderName(objectType, coordinateIndex, slot, materialName, gameObject);
                    StartCoroutine(PopulateListCoroutine(gameObject, objectType, coordinateIndex, slot, filterType: filterType));
                };
                items.Add(shaderItem);

                //Shader RenderQueue
                int renderQueueOriginal     = mat.renderQueue;
                int?renderQueueOriginalTemp = GetMaterialShaderRenderQueueOriginal(objectType, coordinateIndex, slot, materialName);
                renderQueueOriginal = renderQueueOriginalTemp == null ? mat.renderQueue : (int)renderQueueOriginalTemp;
                var shaderRenderQueueItem = new ItemInfo(ItemInfo.RowItemType.ShaderRenderQueue, "Render Queue");
                shaderRenderQueueItem.ShaderRenderQueue         = mat.renderQueue;
                shaderRenderQueueItem.ShaderRenderQueueOriginal = renderQueueOriginal;
                shaderRenderQueueItem.ShaderRenderQueueOnChange = delegate(int value) { AddMaterialShaderRenderQueue(objectType, coordinateIndex, slot, materialName, mat.renderQueue, renderQueueOriginal, gameObject); };
                shaderRenderQueueItem.ShaderRenderQueueOnReset  = delegate { RemoveMaterialShaderRenderQueue(objectType, coordinateIndex, slot, materialName, gameObject); };
                items.Add(shaderRenderQueueItem);

                foreach (var property in XMLShaderProperties[XMLShaderProperties.ContainsKey(shaderName) ? shaderName : "default"].OrderBy(x => x.Value.Type).ThenBy(x => x.Key))
                {
                    string propertyName = property.Key;
                    if (CheckBlacklist(objectType, propertyName))
                    {
                        continue;
                    }

                    if (property.Value.Type == ShaderPropertyType.Texture)
                    {
                        if (mat.HasProperty($"_{propertyName}"))
                        {
                            var textureItem = new ItemInfo(ItemInfo.RowItemType.TextureProperty, propertyName);
                            textureItem.TextureChanged  = !GetMaterialTextureValueOriginal(objectType, coordinateIndex, slot, materialName, propertyName);
                            textureItem.TextureExists   = mat.GetTexture($"_{propertyName}") != null;
                            textureItem.TextureOnExport = delegate { ExportTexture(mat, propertyName); };
                            textureItem.TextureOnImport = delegate
                            {
                                OpenFileDialog.Show(strings => OnFileAccept(strings), "Open image", Application.dataPath, FileFilter, FileExt);

                                void OnFileAccept(string[] strings)
                                {
                                    if (strings == null || strings.Length == 0 || strings[0].IsNullOrEmpty())
                                    {
                                        textureItem.TextureChanged = !GetMaterialTextureValueOriginal(objectType, coordinateIndex, slot, materialName, propertyName);
                                        textureItem.TextureExists  = mat.GetTexture($"_{propertyName}") != null;
                                        return;
                                    }
                                    string filePath = strings[0];

                                    AddMaterialTexture(objectType, coordinateIndex, slot, materialName, propertyName, filePath, gameObject);

                                    TexChangeWatcher?.Dispose();
                                    if (WatchTexChanges.Value)
                                    {
                                        var directory = Path.GetDirectoryName(filePath);
                                        if (directory != null)
                                        {
                                            TexChangeWatcher          = new FileSystemWatcher(directory, Path.GetFileName(filePath));
                                            TexChangeWatcher.Changed += (sender, args) =>
                                            {
                                                if (WatchTexChanges.Value && File.Exists(filePath))
                                                {
                                                    AddMaterialTexture(objectType, coordinateIndex, slot, materialName, propertyName, filePath, gameObject);
                                                }
                                            };
                                            TexChangeWatcher.Deleted            += (sender, args) => TexChangeWatcher?.Dispose();
                                            TexChangeWatcher.Error              += (sender, args) => TexChangeWatcher?.Dispose();
                                            TexChangeWatcher.EnableRaisingEvents = true;
                                        }
                                    }
                                }
                            };
                            textureItem.TextureOnReset = delegate { RemoveMaterialTexture(objectType, coordinateIndex, slot, materialName, propertyName); };
                            items.Add(textureItem);

                            Vector2 textureOffset             = mat.GetTextureOffset($"_{propertyName}");
                            Vector2 textureOffsetOriginal     = textureOffset;
                            Vector2?textureOffsetOriginalTemp = GetMaterialTextureOffsetOriginal(objectType, coordinateIndex, slot, materialName, propertyName);
                            if (textureOffsetOriginalTemp != null)
                            {
                                textureOffsetOriginal = (Vector2)textureOffsetOriginalTemp;
                            }

                            Vector2 textureScale             = mat.GetTextureScale($"_{propertyName}");
                            Vector2 textureScaleOriginal     = textureScale;
                            Vector2?textureScaleOriginalTemp = GetMaterialTextureScaleOriginal(objectType, coordinateIndex, slot, materialName, propertyName);
                            if (textureScaleOriginalTemp != null)
                            {
                                textureScaleOriginal = (Vector2)textureScaleOriginalTemp;
                            }

                            var textureItemOffsetScale = new ItemInfo(ItemInfo.RowItemType.TextureOffsetScale);
                            textureItemOffsetScale.Offset         = textureOffset;
                            textureItemOffsetScale.OffsetOriginal = textureOffsetOriginal;
                            textureItemOffsetScale.OffsetOnChange = delegate(Vector2 value) { AddMaterialTextureOffset(objectType, coordinateIndex, slot, materialName, propertyName, value, textureOffsetOriginal, gameObject); };
                            textureItemOffsetScale.OffsetOnReset  = delegate { RemoveMaterialTextureOffset(objectType, coordinateIndex, slot, materialName, propertyName, gameObject); };
                            textureItemOffsetScale.Scale          = textureScale;
                            textureItemOffsetScale.ScaleOriginal  = textureScaleOriginal;
                            textureItemOffsetScale.ScaleOnChange  = delegate(Vector2 value) { AddMaterialTextureScale(objectType, coordinateIndex, slot, materialName, propertyName, value, textureScaleOriginal, gameObject); };
                            textureItemOffsetScale.ScaleOnReset   = delegate { RemoveMaterialTextureScale(objectType, coordinateIndex, slot, materialName, propertyName, gameObject); };
                            items.Add(textureItemOffsetScale);
                        }
                    }
                    else if (property.Value.Type == ShaderPropertyType.Color)
                    {
                        if (mat.HasProperty($"_{propertyName}"))
                        {
                            Color valueColor         = mat.GetColor($"_{propertyName}");
                            Color valueColorOriginal = valueColor;
                            Color?c = GetMaterialColorPropertyValueOriginal(objectType, coordinateIndex, slot, materialName, propertyName);
                            if (c != null)
                            {
                                valueColorOriginal = (Color)c;
                            }
                            var contentItem = new ItemInfo(ItemInfo.RowItemType.ColorProperty, propertyName);
                            contentItem.ColorValue         = valueColor;
                            contentItem.ColorValueOriginal = valueColorOriginal;
                            contentItem.ColorValueOnChange = delegate(Color value) { AddMaterialColorProperty(objectType, coordinateIndex, slot, materialName, propertyName, value, valueColorOriginal, gameObject); };
                            contentItem.ColorValueOnReset  = delegate { RemoveMaterialColorProperty(objectType, coordinateIndex, slot, materialName, propertyName, gameObject); };
                            items.Add(contentItem);
                        }
                    }
                    else if (property.Value.Type == ShaderPropertyType.Float)
                    {
                        if (mat.HasProperty($"_{propertyName}"))
                        {
                            float  valueFloat             = mat.GetFloat($"_{propertyName}");
                            float  valueFloatOriginal     = valueFloat;
                            string valueFloatOriginalTemp = GetMaterialFloatPropertyValueOriginal(objectType, coordinateIndex, slot, materialName, propertyName);
                            if (!valueFloatOriginalTemp.IsNullOrEmpty() && float.TryParse(valueFloatOriginalTemp, out float valueFloatOriginalTempF))
                            {
                                valueFloatOriginal = valueFloatOriginalTempF;
                            }
                            var contentItem = new ItemInfo(ItemInfo.RowItemType.FloatProperty, propertyName);
                            contentItem.FloatValue         = valueFloat;
                            contentItem.FloatValueOriginal = valueFloatOriginal;
                            if (property.Value.MinValue != null)
                            {
                                contentItem.FloatValueSliderMin = (float)property.Value.MinValue;
                            }
                            if (property.Value.MaxValue != null)
                            {
                                contentItem.FloatValueSliderMax = (float)property.Value.MaxValue;
                            }
                            contentItem.FloatValueOnChange = delegate(float value) { AddMaterialFloatProperty(objectType, coordinateIndex, slot, materialName, propertyName, value, valueFloatOriginal, gameObject); };
                            contentItem.FloatValueOnReset  = delegate { RemoveMaterialFloatProperty(objectType, coordinateIndex, slot, materialName, propertyName, gameObject); };
                            items.Add(contentItem);
                        }
                    }
                }
            }

            virtualList.SetList(items);
        }