(Unity)如何传递变量,这些变量没有一堆If Else语句

时间:2017-03-18 22:17:34

标签: c# unity5 unityscript

for (int m = 0; m < materialObjects.Length; m++)
            {
                for (int i = 0; i < materialModifiers.Count; i++)
                {
                    if(materialModifiers[i].valueType == LittleSubstanceModifier.ValueType.Float)
                    {
                        if (materialModifiers[i].valueFloat[0] != materialModifiers[i].oldValueFloat[0])
                        {
                            materialObjects[m].material.SetFloat(materialModifiers[i].identifier, materialModifiers[i].valueFloat[0]);
                            materialModifiers[i].valueFloat = materialModifiers[i].oldValueFloat;
                        }

                    }
                    else if (materialModifiers[i].valueType == LittleSubstanceModifier.ValueType.Float2 || materialModifiers[i].valueType == LittleSubstanceModifier.ValueType.Float3 || materialModifiers[i].valueType == LittleSubstanceModifier.ValueType.Float4)
                    {
                        if (materialModifiers[i].valueFloat != materialModifiers[i].oldValueFloat)
                        {
                            materialObjects[m].material.SetFloatArray(materialModifiers[i].identifier, materialModifiers[i].valueFloat);
                            materialModifiers[i].valueFloat = materialModifiers[i].oldValueFloat;
                        }
                    }                   
                    else if (materialModifiers[i].valueType == LittleSubstanceModifier.ValueType.Int)
                    {
                        if (materialModifiers[i].valueInt != materialModifiers[i].oldValueInt)
                        {
                            materialObjects[m].material.SetInt(materialModifiers[i].identifier, materialModifiers[i].valueInt[0]);
                            materialModifiers[i].valueFloat = materialModifiers[i].oldValueFloat;
                        }
                    }
                    else if (materialModifiers[i].valueType == LittleSubstanceModifier.ValueType.Int2 || materialModifiers[i].valueType == LittleSubstanceModifier.ValueType.Int3 || materialModifiers[i].valueType == LittleSubstanceModifier.ValueType.Int4)
                    {

                    }
                    else if (materialModifiers[i].valueType == LittleSubstanceModifier.ValueType.Bool)
                    {

                    }
                    else if (materialModifiers[i].valueType == LittleSubstanceModifier.ValueType.ColorField)
                    {

                    }
                    else if (materialModifiers[i].valueType == LittleSubstanceModifier.ValueType.Vector2)
                    {

                    }
                    else if (materialModifiers[i].valueType == LittleSubstanceModifier.ValueType.Vector3)
                    {

                    }
                    else if (materialModifiers[i].valueType == LittleSubstanceModifier.ValueType.Vector4)
                    {

                    }
                }
            }

我现在正在制作工具,用户可以选择用户可以在巡视窗口中编辑的变量类型。

要使用Enum选择变量I,然后检查他们选择的变量类型,我使用了一堆Else Ifs。现在要选择变量,它可以用Else If来做,但是当需要更改值时,我每次添加一个字母或更改数字时都可以做10个其他if。

所以我的问题是,我怎样才能传递所选的变量类型,而不会在没有其他ifs的情况下找出他们选择的内容?如果我可以使用var,那将会很好,但它正在从另一个脚本中更改。

对于这篇漫长的帖子感到抱歉,我真的不知道该怎么称呼它以及如何提问。

编辑:这是我的代码,这样做的更好方法是什么?

Edit2:对Robyn的响应 - 我刚刚编写了代码示例,它基本上是我知道如何做到这一点的唯一方法。对不起,我会尽力解释。 在我发布的图像中,有标识符文本框,其中包含不透明度。 然后下拉所有变量类型。然后它有一个文本框。你点击按钮添加Mod,然后弹出一行。您可以选择您的变量类型,放入材料标识符(示例不透明度)。因此,要改变不透明度,它需要是一个浮点数。因此,当您更改浮动框值时,它将更改材质不透明度。 我基本上需要一个值,可以用作float,int,bool等...... 我从来没有使用过Switch或Case,所以我真的不知道它究竟做了什么。但我会仔细查看!那谢谢啦。 我刚刚上传了2张图片,试图直观地解释它。

Tool

Code

2 个答案:

答案 0 :(得分:1)

您只需要在所选元素发生变化时检查类型。

enum SupportedTypes
{
    Color,
    Int
}
SupportedTypes selectedType;

void OnEnable()
{
    // If the user still didn't select anything, select Int
    selectedType = SupportedTypes.Int;
    // See below to know what this is
    methodUsedToDrawTheLastPart = DrawIntChooser;
}

// One field for each type
// Not elegant but we don't know the type beforehand
Color colorValue;
int intValue;
// ...

// Delegate defining a method signature: in this case "void XXX(string)"
delegate void SetValue(string propertyId);
// Instance of the delegate: think of it as a pointer to a method
//   with the signature defined earlier
// You can set this field to any method being "void XXX(string)"
SetValue methodUsedToDrawTheLastPart;

// Then One method to draw each property chooser
// They will just draw the last part of the modifier
void DrawColorChooser(string propertyId)
{
    Color newColorValue = EditorGUILayout.ColorField(colorValue);
    if (newColorValue != colorValue)
    {
        colorValue = newColorValue;
        // Replace this with a call to the renderer
        Debug.Log("Set color to " + colorValue);
    }
}
void DrawIntChooser(string propertyId)
{
    int newIntValue = EditorGUILayout.IntField(intValue);
    if (newIntValue != intValue)
    {
        intValue = newIntValue;
        Debug.Log("Set int to " + intValue);
    }
}
// All the other types choosers ...


// Finally, the method to put pieces together
void DrawModifier()
{
    EditorGUILayout.BeginHorizontal();
    string propertyId = "propId";
    EditorGUILayout.TextField(propertyId);
    SupportedTypes newModifierType = (SupportedTypes)EditorGUILayout.EnumPopup(selectedType);
    // We only do if-else statements if the type changed
    // So when the user changes only the value, this will be skipped
    if (newModifierType != selectedType)
    {
        // Here, based on the chosen type, we set the delegate
        if (newModifierType == SupportedTypes.Int)
        {
            methodUsedToDrawTheLastPart = DrawIntChooser;
        }
        else if (newModifierType == SupportedTypes.Color)
        {
            methodUsedToDrawTheLastPart = DrawColorChooser;
        }
        selectedType = newModifierType;
    }
    // And then we call it
    methodUsedToDrawTheLastPart(propertyId);
    EditorGUILayout.EndHorizontal();
}
public override void OnInspectorGUI()
{
    DrawModifier();
}

答案 1 :(得分:0)

您可以使用Switch和Foreach语句而不是If和For语句来使代码更容易阅读,如下所示:

StringBuilder

等等

foreach (var materialObject in materialObjects)
{
    foreach (var materialModifier in materialModifiers)
    {
        switch (materialModifier.valueType)
        {
            case LittleSubstanceModifier.ValueType.Float:
                if (materialModifier.valueFloat[0] != materialModifier.oldValueFloat[0])
                {
                     materialObject.material.SetFloat(materialModifier.identifier, materialModifier.valueFloat[0]);
                     materialModifier.valueFloat = materialModifier.oldValueFloat;
                }
                break;
            case LittleSubstanceModifier.ValueType.Float2:
            case LittleSubstanceModifier.ValueType.Float3:
            case LittleSubstanceModifier.ValueType.Float4:
                if (materialModifier.valueFloat != materialModifier.oldValueFloat)
                {
                    materialObject.material.SetFloatArray(materialModifier.identifier, materialModifier.valueFloat);
                    materialModifier.valueFloat = materialModifier.oldValueFloat;
                }
                break;

(你的代码看起来可能不会完全符合你想要的......但我还没有改变它的作用,因为我不知道你想要它做什么)