如何使用按钮更改枚举项目?

时间:2018-11-11 16:15:56

标签: c# unity3d

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEditor.IMGUI;

public class ChangeShaderRenderingModes : EditorWindow
{
    public enum BlendMode
    {
        Opaque,
        Cutout,
        Fade,
        Transparent
    }

    static Material material;
    static Material objectMat;
    static int modeIndex = 0;

    [MenuItem("Tools/Change Rendering Modes")]
    public static void ShowWindow()
    {
        GetWindow<ChangeShaderRenderingModes>("ChangeRenderingModes");
    }

    private void OnGUI()
    {
        if(GUI.Button(new Rect(50,50,50,50), "Switch Mode"))
        {
            var objects = Selection.objects;

            Shader shader = Shader.Find("Standard");
            material = new Material(shader);

            if (modeIndex == 4)
                modeIndex = 0;

            ChangeRenderMode(material, BlendMode.Opaque);

            GameObject go = GameObject.Find("test");

            objectMat = go.GetComponent<Renderer>().sharedMaterial;
            objectMat = material;
            go.GetComponent<Renderer>().sharedMaterial = material;
        }
    }

    public static void ChangeRenderMode(Material standardShaderMaterial, BlendMode blendMode)
    {
        switch (blendMode)
        {
            case BlendMode.Opaque:
                standardShaderMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                standardShaderMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
                standardShaderMaterial.SetInt("_ZWrite", 1);
                standardShaderMaterial.DisableKeyword("_ALPHATEST_ON");
                standardShaderMaterial.DisableKeyword("_ALPHABLEND_ON");
                standardShaderMaterial.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                standardShaderMaterial.renderQueue = -1;
                break;
            case BlendMode.Cutout:
                standardShaderMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                standardShaderMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
                standardShaderMaterial.SetInt("_ZWrite", 1);
                standardShaderMaterial.EnableKeyword("_ALPHATEST_ON");
                standardShaderMaterial.DisableKeyword("_ALPHABLEND_ON");
                standardShaderMaterial.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                standardShaderMaterial.renderQueue = 2450;
                break;
            case BlendMode.Fade:
                standardShaderMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
                standardShaderMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
                standardShaderMaterial.SetInt("_ZWrite", 0);
                standardShaderMaterial.DisableKeyword("_ALPHATEST_ON");
                standardShaderMaterial.EnableKeyword("_ALPHABLEND_ON");
                standardShaderMaterial.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                standardShaderMaterial.renderQueue = 3000;
                break;
            case BlendMode.Transparent:
                standardShaderMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                standardShaderMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
                standardShaderMaterial.SetInt("_ZWrite", 0);
                standardShaderMaterial.DisableKeyword("_ALPHATEST_ON");
                standardShaderMaterial.DisableKeyword("_ALPHABLEND_ON");
                standardShaderMaterial.EnableKeyword("_ALPHAPREMULTIPLY_ON");
                standardShaderMaterial.renderQueue = 3000;
                break;
        }
    }
}

我希望每次单击按钮时它将切换到下一个模式。不透明,抠图,淡入淡出,透明

在透明之后回到第一个不透明

问题在于方法ChangeRenderMode获得一种特定模式。 我想在单击按钮时,ChangeRenderMode将变为不透明,然后单击它将获得Cutout,然后是Fade和Transparent。

2 个答案:

答案 0 :(得分:2)

enum从默认值0开始,每一项增加1,因此

public enum BlendMode
{
    Opaque,   // = 0
    Cutout,   // = 1
    Fade,     // = 2
    Transparent  // = 3
}

因此您可以将其解析为int,计算下一个值,然后再次将其解析为BlendMode

在您的OnGUI函数中,替换

if (modeIndex == 4)
    modeIndex = 0;
ChangeRenderMode(material, BlendMode.Opaque);

使用

var values = (BlendMode[])Enum.GetValues(typeof(BlendMode))
modeIndex = (BlendMode)((modeIndex+1) % values.Length);
ChangeRenderMode(material, blendMode);

答案 1 :(得分:1)

您可以尝试使用Dictionary键作为当前状态值作为下一状态。

Dictionary<BlendMode, BlendMode> dict = new Dictionary<BlendMode, BlendMode>();
dict.Add(BlendMode.Opaque, BlendMode.Cutout);
dict.Add(BlendMode.Cutout, BlendMode.Fade);
dict.Add(BlendMode.Fade, BlendMode.Transparent);
dict.Add(BlendMode.Transparent, BlendMode.Opaque);

并在类中声明一个值以存储BlendMode状态。

BlendMode currentMode = BlendMode.Cutout;

然后,您可以使用此currentMode(键)获取下一个模式。

currentMode = dict[currentMode];

完整代码就像

public class ChangeShaderRenderingModes : EditorWindow
{
    //store mode
    static BlendMode currentMode = BlendMode.Opaque;

    static Dictionary<BlendMode, BlendMode> dict = new Dictionary<BlendMode, BlendMode>();


    public void Awake()
    {
        dict.Add(BlendMode.Opaque, BlendMode.Cutout);
        dict.Add(BlendMode.Cutout, BlendMode.Fade);
        dict.Add(BlendMode.Fade, BlendMode.Transparent);
        dict.Add(BlendMode.Transparent, BlendMode.Opaque);
    }


    public enum BlendMode
    {
        Opaque,
        Cutout,
        Fade,
        Transparent
    }

    static Material material;
    static Material objectMat;
    static int modeIndex = 0;

    [MenuItem("Tools/Change Rendering Modes")]
    public static void ShowWindow()
    {
        GetWindow<ChangeShaderRenderingModes>("ChangeRenderingModes");
    }

    private void OnGUI()
    {
        if(GUI.Button(new Rect(50,50,50,50), "Switch Mode"))
        {
            var objects = Selection.objects;

            Shader shader = Shader.Find("Standard");
            material = new Material(shader);

            if (modeIndex == 4)
                modeIndex = 0;

            // take out the parameter
            ChangeRenderMode(material);

            GameObject go = GameObject.Find("test");

            objectMat = go.GetComponent<Renderer>().sharedMaterial;
            objectMat = material;
            go.GetComponent<Renderer>().sharedMaterial = material;
        }
    }

    public static void ChangeRenderMode(Material standardShaderMaterial)
    {
        switch (blendMode)
        {
            ....
        }
        // set next mode
        currentMode = dict[currentMode];
    }
}

注意

此解决方案可以灵活地确定下一个模式是什么。