首页 > 解决方案 > 如何比较两个不同类型的项目

问题描述

我不确定最好的方法是什么,但我想有两个enums我可以比较。所以当一个单位进入当前单位的触发器时,该单位可以通过比较两者来检测进入的单位是否可攻击enums

我知道enums无法像下面的示例中那样比较两种不同的方法,那么当我不可以None接受unit typeNone可以接受时,最好的方法是什么attack type

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

public class Unit : MonoBehaviour {
    public UnitType unitType;
    public AttackType attackType;

    void OnTriggerEnter(Collider other) {
        Unit unit = other.GetComponent<Unit>();
        if(unit.unitType == attackType) {
            // Send current unit to attack here
        }
    }
}

标签: c#unity3d

解决方案


这是我将采取的方法:设置有效攻击列表,然后简单地与该列表进行比较。尝试这个:

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). 代码变得非常简洁明了。


推荐阅读