Ejemplo n.º 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);
        }