2017-03-18 65 views
0

(團結)如何傳遞變量,該變量是不一堆如果else語句

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

        } 
       } 
      } 

我正在做一個工具,現在的,並且用戶能夠選擇一個變量類型用戶可以在巡視窗口中進行編輯。

要選擇變量我使用一個枚舉,但然後檢查他們選擇哪種類型的變量,我使用了一堆Else Ifs。現在選擇變量,它可以與Else一起使用If,但是當它改變值時,我不能每次添加一個字母或更改一個數字時再做10個if。

所以我的問題,我怎麼能通過選擇的變量類型,沒有找到他們沒有一堆其他ifs選擇什麼?如果我可以使用var,它會很好,但它正在從另一個腳本中更改。

對不起,我真的不知道該怎麼稱呼這個以及如何問。

編輯:這是我的代碼,這將是一個更好的方式做到這一點?

Edit2:對Robyn的迴應 - 我只是寫了一個例子的代碼,它基本上是唯一的方法,我會知道如何做到這一點。對不起,我會盡力解釋。 在我發佈的圖片中,有標識符文本框,其中包含不透明度。 然後下拉所有變量類型。然後它有一個文本框。你點擊按鈕添加Mod,並彈出一行。你選擇你的變量類型,放入材料標識符(例如不透明度)。所以要改變不透明度,它需要是一個浮動。因此,當您更改浮動框值時,它將更改材質不透明度。 我基本上需要一個值,可以用作一個浮點數,整型,布爾等... 我從來沒有使用開關或案例,所以我真的不知道它究竟做了什麼。但我會試試看!那謝謝啦。 我剛上傳了2張圖片,試圖直觀地解釋一下它。

Tool

Code

+0

你的問題太廣泛了。你需要嘗試_something_,如果你有一些特殊的麻煩,發佈一個問題,包括一個好的[mcve],準確地顯示你所嘗試的內容,並且準確地解釋代碼的作用,你希望它做什麼,以及什麼你無法解決自己的問題。根據你的模糊描述,我會提出多態性,即基本抽象類型(如接口)描述編輯器所需要的類型層次結構,然後具體實現處理用戶輸入和顯示。 –

+0

真的很抱歉,不知道我想要做什麼叫。 我剛剛添加了代碼,也許這會有所幫助。我只需要一個更好的方法來做到這一點。 – LittleRain

+0

你可以嘗試使用工廠模式。這樣你就可以描述傳入工廠的對象中的邏輯。這是我使用的模式,否則邏輯變得更難管理。 http://www.dofactory.com/net/factory-method-design-pattern – Programmer

回答

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(); 
} 
+0

我有一個列表,其中包含與上面的代碼相同的腳本中的自定義類。 當我點擊添加mod它會添加所有這些下拉菜單和文本框。 雖然我會嘗試,但我想我必須拋棄自定義類,但它可能會更好。 編輯:等等,我可以得到一個列表來容納不同類型的變量嗎?或者我應該創建一個浮動列表,bools等列表... 謝謝。 – LittleRain

+0

我在上面的腳本中有一個列表,其中包含一個自定義類。該類持有浮動,float2.34 ...,然後它擁有一個布爾,int等... 當我點擊添加mod它會添加所有這些下拉菜單和文本框。 用戶選擇哪種類型的變量float,int bool,但現在是棘手的部分,當他更改變量(不是類型,值)時,我需要它調用Renderer.material.SetFloat或SetBool等...根據什麼類型的變量,我只是不知道如何做,而不在for循環中做一堆Ifs/elses。 對不起,不讓我編輯5分鐘。 – LittleRain

+0

好的,謝謝,是的,這是我不明白的FindTypeByIndex,並且在網上找不到任何關於它的東西。這將工作,所以再次感謝。 有點希望有一種方式來使用像var這樣的東西,但公開。但是我猜只能編譯,而且你不能在運行時改變它。 – LittleRain

0

你可以使用交換機和foreach語句如果並報表,而不是使代碼更容易一些閱讀,是這樣的:

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; 

等等等等

 } 
    } 
} 

(你的代碼看起來可能不會完全符合你的要求......但我沒有改變它的功能,因爲我不知道你想要它做什麼)

+0

我在主帖中留下了回覆,沒有足夠的空間。感謝您的回覆,雖然我不確定Switch/Case是做什麼的,但我會研究這一點。 – LittleRain

+0

是的,閱讀關於網絡上的開關/外殼是個好主意。它很像很多if/else語句,它們都檢查相同的值。如果真的很長,它有時也會快一點點。 – Robyn

+0

看着它,很好,很容易。得到了代碼工作,但仍然是減緩所有Ifs/elses的原因。謝謝你的幫助。 – LittleRain