如何比较两个不同类型的项目

时间:2018-06-20 02:40:35

标签: c# unity3d

我不确定执行此操作的最佳方法是什么,但是我想比较两个enums。因此,当一个单位进入当前单位的触发器时,该单位可以通过比较两个enums来检测进入单位是否受到攻击。

我知道无法像下面的示例中那样比较两个不同的enums,所以当我不是None而是{{ 1}}是可以接受的unit type吗?

None

3 个答案:

答案 0 :(得分:2)

从根本上说,这是行不通的。

您有两个枚举,它们由整数支持。第一个以Ground开头,第二个以None开头,这意味着UnitType.Ground == AttackType.None,行!

您应该做的是使用单个枚举:

public enum UnitType { None, Ground, Air, Water }

和字段:

public UnitType unitType;
public UnitType attackType;

NoneunitType毫无意义,但是没关系!重要的是,这两个字段彼此之间具有共同关系,并且该关系是它们是什么类型的以及它们可以进攻的类型的单元

我们可以再走一步:

[Flags]
public enum UnitType {
    None =   0,
    Ground = 1, // 1<<0
    Air =    2, // 1<<1
    Water =  4  // 1<<2
}

现在我们可以这样做:

this.attackType = UnitType.Ground|UnitType.Air;
//...
if(unit.unitType & attackType > 0) {
    // Send current unit to attack here
}

Voila,不需要魔法就能制造出可以攻击多种类型的东西!或一种以上的单位! (Ground Water的气垫船)

答案 1 :(得分:2)

这是我要采取的方法:建立有效攻击列表,然后将其与该列表进行比较。试试这个:

var validAttacks = new (UnitType, AttackType)[]
{
    (UnitType.Air, AttackType.Air),
    (UnitType.Air, AttackType.Ground),
    (UnitType.Ground, AttackType.Ground),
    (UnitType.Water, AttackType.Water),
    (UnitType.Water, AttackType.Air),
};

使用这种列表,您可以创建自己喜欢的任何组合。您甚至可以在运行时进行设置以使其变得灵活。

现在,要使用它,只需执行以下操作:

var unit = UnitType.Water;
var attack = AttackType.Air;

var attackable = validAttacks.Contains((unit, attack));

Console.WriteLine(attackable);

这会产生True,因为列表中包含UnitType.WaterAttackType.Air的组合。


现在,您可以再进一步一步,进行设置:

public class Unit
{
    private Dictionary<(UnitType, AttackType), Action<Unit, Unit>> _validAttacks;

    public Unit()
    {
        _validAttacks = new Dictionary<(UnitType, AttackType), Action<Unit, Unit>>()
        {
            { (UnitType.Air, AttackType.Air), (s, o) => MissleAttack(s, o) },
            { (UnitType.Air, AttackType.Ground), (s, o) => MissleAttack(s, o) },
            { (UnitType.Ground, AttackType.Ground), (s, o) => TankAttack(s, o) },
            { (UnitType.Water, AttackType.Water), (s, o) => TorpedoAttack(s, o) },
            { (UnitType.Water, AttackType.Air), (s, o) => IcbmAttack(s, o) },
        };
    }

    public UnitType unitType;
    public AttackType attackType;

    void OnTriggerEnter(Collider other)
    {
        Unit unit = other.GetComponent<Unit>();
        if (_validAttacks.ContainsKey((unit.unitType, attackType)))
        {
            _validAttacks[(unit.unitType, attackType)].Invoke(this, unit);
        }
    }

    public void TankAttack(Unit self, Unit other) { ... }
    public void MissleAttack(Unit self, Unit other) { ... }
    public void TorpedoAttack(Unit self, Unit other) { ... }
    public void IcbmAttack(Unit self, Unit other) { ... }
}

现在,我可以合并与一对(UnitType, AttackType)相关联的动作。代码变得非常简洁明了。

答案 2 :(得分:1)

尽管枚举是不同的类型,并且可能具有不同的整数值,但是您仍然可以使用ToString()通过其符号名称来比较它们。所以代替

if (unit.unitType == attackType) 

只需使用

if (unit.unitType.ToString() == attackType.ToString())