簡體   English   中英

如何使用按鈕更改枚舉項目?

[英]How can I change enum items using a button?

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。

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);

您可以嘗試使用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];
    }
}

注意

該解決方案可以靈活地確定下一個模式是什么。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM