我不确定执行此操作的最佳方法是什么,但是我想比较两个enums
。因此,当一个单位进入当前单位的触发器时,该单位可以通过比较两个enums
来检测进入单位是否受到攻击。
我知道无法像下面的示例中那样比较两个不同的enums
,所以当我不是None
而是{{ 1}}是可以接受的unit type
吗?
None
答案 0 :(得分:2)
您有两个枚举,它们由整数支持。第一个以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
}
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.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)
相关联的动作。代码变得非常简洁明了。
答案 2 :(得分:1)
尽管枚举是不同的类型,并且可能具有不同的整数值,但是您仍然可以使用ToString()
通过其符号名称来比较它们。所以代替
if (unit.unitType == attackType)
只需使用
if (unit.unitType.ToString() == attackType.ToString())