为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
烙印99 2021-08-22 15:35:11
我不确定这样做的最佳方法是什么,但我想要两个enums我可以比较的方法。所以当一个单位进入当前单位的触发器时,该单位可以通过比较两者来检测进入的单位是否可攻击enums。我知道enums不能像下面的例子那样比较两个不同的东西,那么当我不None接受什么unit type但None可以接受时,最好的方法是什么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        }    }}
查看完整描述

3 回答

?
牧羊人nacy

TA贡献1862条经验 获得超7个赞

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

if (unit.unitType == attackType)

只是使用

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


查看完整回答
反对 回复 2021-08-22
?
蛊毒传说

TA贡献1895条经验 获得超3个赞

这从根本上是行不通的。

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


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


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

和字段:


public UnitType unitType;

public UnitType attackType;

None对 没有意义unitType,但没关系!重要的是这两个领域有一个共同的关系,这个关系就是他们是什么类型的单位,他们可以攻击什么类型的单位。


我们可以更进一步:


[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

}

瞧,制作可以攻击不止一种类型的东西不需要魔法!或单位认为是多种类型的!(气垫船是Ground 和 Water)


查看完整回答
反对 回复 2021-08-22
?
忽然笑

TA贡献1806条经验 获得超5个赞

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


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


查看完整回答
反对 回复 2021-08-22
  • 3 回答
  • 0 关注
  • 193 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信