如何避免多次硬编码方法调用

时间:2018-07-17 11:10:30

标签: c# unity3d

我目前正在开发一个我用Unity创建的小游戏。在提出问题之前,让我先概述一下情况:
目前,有两个玩家,每个玩家都有相同的组(五个类型,但总共十个)。在构建场景之前,每个玩家都选择一种颜色(以后将等于作品的某种“种族”)。目前共有三种颜色,因此总共有15种不同的预制件,因为假设“蓝色苹果”和“红色苹果”的网眼会有所不同。
此刻我有这样的东西:

using UnityEngine;
using System.Collections;

public class Board : MonoBehavior
{
public Piece[,] pieces = new Piece[5,5];
public GameObject redApplePrefab;
public GameObject redBananaPrefab;
public GameObject redBerryPrefab;

public GameObject blueApplePrefab;
public GameObject blueBananaPrefab;
public GameObject blueBerryPrefab;

public GameObject whiteApplePrefab;
public GameObject whiteBananaPrefab;
public GameObject whiteBerryPrefab;


private void GenerateBoard()
{
    if(white) //don't let the missing declaration of the if statement bother you, just wanted to keep it short here)
    {
        GeneratePiece(whiteApplePrefab, 0, 0);
        GeneratePiece(whiteApplePrefab, 0, 1);
        GeneratePiece(whiteApplePrefab, 0, 2);
        GeneratePiece(whiteBananaPrefab, 1, 0);
        GeneratePiece(whiteBananaPrefab, 1, 1);
        GeneratePiece(whiteBananaPrefab, 2, 0);
        GeneratePiece(whiteBerryPrefab, 2, 2);
    }
    if(blue) //don't let the missing declaration of the if statement bother you, just wanted to keep it short here)
    {
        GeneratePiece(blueApplePrefab, 0, 0);
        GeneratePiece(blueApplePrefab, 0, 1);
        GeneratePiece(blueeApplePrefab, 0, 2);
        GeneratePiece(blueeBananaPrefab, 1, 0);
        GeneratePiece(blueeBananaPrefab, 1, 1);
        GeneratePiece(blueeBananaPrefab, 2, 0);
        GeneratePiece(blueeBerryPrefab, 2, 2);
    }
    if(red) //don't let the missing declaration of the if statement bother you, just wanted to keep it short here)
    {
        GeneratePiece(redApplePrefab, 0, 0);
        GeneratePiece(redApplePrefab, 0, 1);
        GeneratePiece(redApplePrefab, 0, 2);
        GeneratePiece(redBananaPrefab, 1, 0);
        GeneratePiece(redBananaPrefab, 1, 1);
        GeneratePiece(redBananaPrefab, 2, 0);
        GeneratePiece(redBerryPrefab, 2, 2);
    }
}

GeneratePiece(Gameobject prefab, int x, int y)
{
    GameObject go = Instantiate(prefab) as GameObject;
    go.transform.SetParent(transform);
    Piece p = go.getComponent<Piece>();
    pieces[x, y] = p;
}
}

直言不讳。有点丑。我真的想避免手动一次又一次地使用不同的值来调用同一方法。但是我目前对实现此工作的一种优雅方式有些犹豫。我只想用颜色和样片来称呼预制件,如果不需要,我不想更改GeneratePiece()方法。在GenerateBoard()方法中,所有关于哪个预制件以及在哪里发生的计算。
我想有一个回圈,我可以给它选择两种颜色,然后用正确的预制件对它们进行配属,然后将它们放在适当的领域。

我在想像双键字典

Dictionary<string colour, Dictionary<string kindOfPiece, GameObject prefab>>

或者像这样具有某种二维的预制件阵列会更好:

GameObject[numberOfColours, numberOfPieces] prefabs;

,然后有某种映射器,可以将颜色“白色”转换为0,将“蓝色”转换为1,依此类推,所以我可以访问数组中的特定预制件吗?

GameObject prefabToGenerate = prefabs[colourPlay1.ColourToNumber(), pieceToBeCreated.PieceToNumber()];

3 个答案:

答案 0 :(得分:5)

使用枚举表示颜色:

public enum PieceColor
{
    white, blue, red
}

然后使用Dictionary枚举和Action作为键和值来表示要调用的函数:

Dictionary<PieceColor, Action> colorToAction = new Dictionary<PieceColor, Action>();

将颜色枚举映射到函数。您应该手动映射它们而不是循环,因为x,y值存在一些不一致。将来尝试使用for循环映射它会导致混乱。

void Init()
{
    colorToAction.Add(PieceColor.white,
    delegate
    {
        GeneratePiece(whiteApplePrefab, 0, 0);
        GeneratePiece(whiteApplePrefab, 0, 1);
        GeneratePiece(whiteApplePrefab, 0, 2);
        GeneratePiece(whiteBananaPrefab, 1, 0);
        GeneratePiece(whiteBananaPrefab, 1, 1);
        GeneratePiece(whiteBananaPrefab, 2, 0);
        GeneratePiece(whiteBerryPrefab, 2, 2);
    });

    colorToAction.Add(PieceColor.blue,
    delegate
    {
        GeneratePiece(blueApplePrefab, 0, 0);
        GeneratePiece(blueApplePrefab, 0, 1);
        GeneratePiece(blueApplePrefab, 0, 2);
        GeneratePiece(blueBananaPrefab, 1, 0);
        GeneratePiece(blueBananaPrefab, 1, 1);
        GeneratePiece(blueBananaPrefab, 2, 0);
        GeneratePiece(blueBerryPrefab, 2, 2);
    });

    colorToAction.Add(PieceColor.red,
    delegate
    {
        GeneratePiece(redApplePrefab, 0, 0);
        GeneratePiece(redApplePrefab, 0, 1);
        GeneratePiece(redApplePrefab, 0, 2);
        GeneratePiece(redBananaPrefab, 1, 0);
        GeneratePiece(redBananaPrefab, 1, 1);
        GeneratePiece(redBananaPrefab, 2, 0);
        GeneratePiece(redBerryPrefab, 2, 2);
    });
}

下面是您的新GenerateBoard函数。每次您需要调用一个函数时,获取颜色并使用TryGetValue来检索适当的函数,然后使用Invoke函数来调用这些函数。

PieceColor color = PieceColor.white;

private void GenerateBoard()
{
    Action action;
    if (colorToAction.TryGetValue(color, out action))
        action.Invoke();
}

答案 1 :(得分:1)

您可以尝试以这种方式避免所有复制和粘贴代码...

GenerateBoard内,您可以在appleWithColor内有类似的内容,而在其他public GameObject[] appleWithCOlor内,您可以有for(int color = 0;color < MAX_COLORS; color++) { GameObject Apple = appleWithColor[color];//set depeding on color GameObject Bannana = bannanaWithColor[color]; GameObject Berry = berryWithColor[color]; for(int i = 0; i <3;i++) { GeneratePiece(Apple, 0,i); } for(int i = 0; i <2;i++) { GeneratePiece(Bannana, 1,i); } GeneratePiece(Bannana, 2,0); GeneratePiece(Berry,2,2); } 并用颜色填充检查人员的内容。其他水果也一样

myregistry.mysite.com.crt

答案 2 :(得分:1)

...
    if(red) //don't let the missing declaration of the if statement bother you, just wanted to keep it short here)
    {
        GeneratePieces(redApplePrefab, new List<Vector2>() { new Vector2(0,0), new Vector2(0,1), new Vector2(0,2)});
        GeneratePieces(redBananaPrefab, new List<Vector2>() { new Vector2(1,0), new Vector2(1,1), new Vector2(2,0)});
        GeneratePiece(redBerryPrefab, 2, 2);
    }
}

GeneratePieces(Gameobject prefab, List<Vector2> coords) 
{
    foreach (Vector2 vec in coords) 
    {
        GeneratePiece(prefab, vec.X, vec.Y);
    }
}

GeneratePiece(Gameobject prefab, int x, int y)
{
    GameObject go = Instantiate(prefab) as GameObject;
    go.transform.SetParent(transform);
    Piece p = go.getComponent<Piece>();
    pieces[x, y] = p;
}
}