Unity - 使用枚举属性检测碰撞的对象

时间:2017-11-17 16:06:39

标签: c# unity3d enums collision collider

昨晚我正在研究一个C-Sharp项目,试图围绕GameObjects进行相互编码。我想要不同的门类型(例如木头,石头,金​​属)可以用不同的武器(例如棍棒,剑,斧头)分解。

为了检测GateManager上的碰撞,我使用了每个门的标签。例如:

    void OnTriggerEnter(Collider collider) {
       switch (gameObject.tag) {
         case "WoodenGate":
             ...
         case "StoneGate":
             ...

上面的代码不准确,但应该提出一个想法。将每个门类型设置为不同的标签是错误的(如果每个门类型都有不同的标签,并且每种材料类型都有不同的标签等,那么我最终会得到数百个标签)。

所以我提出了另一种选择。我设置了一个GateType枚举并创建了3个值(WoodenGate,StoneGate,MetalGate)。然后我将一个公共GateType属性附加到GateManager类。这使我能够在“督察”统一窗口中选择与每个预制件相关的枚举。它非常整洁,我真的很开心。

然后出现了一个问题:我在列表中间添加了第4个枚举(例如GlassGate)。因为枚举只是int值,所以第3项不再是MetalGate,而是现在的StoneGate。这意味着金属门预制件突然有一个Gategate的石门。这打破了我的比赛。

道歉,对于罗嗦的问题,但我的问题是,我应该如何最好地标记和识别许多不同类型的物品?我不想使用标签(因为我需要太多)并且我不想使用枚举(因为它们与统一检查员一起使用时会形成脆弱的问题。

我认为这必须是许多游戏的常见要求(例如,在游戏中你可以使用你的镐在很多不同的游戏对象上收集不同的资源)所以只是想知道最佳做法?

3 个答案:

答案 0 :(得分:4)

1 。您可以声明并使用许多接口来完成此操作,但缺点是您需要声明其中许多接口并在附加到每个对象的许多脚本中实现它们:

public interface IDestroyable { }

public interface IOpenable { }

然后你从脚本继承它:

public class MyScript : MonoBehaviour, IDestroyable{}

public class MyOtherScript : MonoBehaviour, IOpenable{}

检查碰撞过程中它是哪一个:

void OnTriggerEnter(Collider collider)
{
    if (collider.GetComponent<IOpenable>() != null)
    {

    }

    else if (collider.GetComponent<IDestroyable>() != null)
    {

    }
}

2 。您也可以使用您提到的枚举。

public enum GateType
{
    WoodenGate,
    StoneGate,
    MetalGate
}

将描述此对象的门类型的单个脚本附加到所有Gate对象预制件,然后从编辑器或脚本中为每个选择枚举

public class GateDescription : MonoBehaviour
{
    public GateType gateType;
}

检查碰撞过程中它是哪一个:

void OnTriggerEnter(Collider collider)
{
    GateDescription gateType = collider.GetComponent<GateDescription>();

    if (gateType != null)
    {
        switch (gateType.gateType)
        {
            case GateType.StoneGate:
                break;

            case GateType.WoodenGate:
                break;

            case GateType.MetalGate:
                break;
        }
    }
}

答案 1 :(得分:1)

枚举是最方便的方法。为枚举值添加索引并手动递增。

public GateType gateType;

public enum GateType
{
    Wood = 0,
    Stone = 1,
    Brick = 2
}

现在,如果您想在“列表”中间添加另一个,请执行以下操作:

public GateType gateType;

public enum GateType
{
    Wood = 0,
    Metall = 3,
    Stone = 1,
    Brick = 2
}

Unity应该在对象上保留正确的值,因为您添加了索引。

答案 2 :(得分:0)

您可以根据spawn / init事件进行设置。如果您要使用枚举方法,则可以在生成对象时定义它。这显然取决于你的游戏机制。但是,我可能会将此外包给专门针对您想要的物质行为的单一行为。这样,如果你想改变木拱的行为方式,你只需要更新一个脚本,它就是自包含的。这将有助于您的代码库变得更大,并且如果您使用2017.3的功能允许您定义哪些文件进入哪些程序集

,这将有助于改善编译和加载时间