2017-11-17 14 views
1

昨夜私はC-Sharpプロジェクトで、GameObjectsが互いに衝突するようにコーディングしようとしていました。私は、異なる武器(クラブ、剣、斧など)によって分解される可能性のあるさまざまなゲートタイプ(たとえば、木、石、金属)が必要でした。Unity - enumプロパティを使用してオブジェクトが衝突するのを検出する

GateManagerの衝突を検出するために、私は各ゲートにタグを使用していました。したがって、たとえば:

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

上記のコードは正確ではありませんが、アイデアを与える必要があります。各ゲートタイプを異なるタグとして設定するのは間違っていました(ゲートタイプごとに異なるタグがあり、すべてのマテリアルタイプに異なるタグがある場合は、何百ものタグが使用されます)。

私は別の方法を思いついた。私はGateTypeのenumを設定し、3つの値(WoodenGate、StoneGate、MetalGate)を作成しました。その後、公開GateTypeプロパティをGateManagerクラスにアタッチしました。これにより、「インスペクタ」ウインドウ内の各プレハブに関連する列挙型を選択することができました。とても素敵で、本当に嬉しかったです。

問題が発生しました。リストの途中に4番目の列挙型を追加しました(GlassGateなど)。列挙型は単純にint型の値なので、3番目のアイテムはMetalGateでなくStoneGateになりました。これは、メタルゲートのプレハブが突然Gategate of stonegateを持っていることを意味していました。それは私のゲームを壊した。

ご迷惑をおかけして申し訳ありませんが、私の質問では、さまざまな種類の商品をたくさんラベル付けして識別するにはどうすればよいですか?私はタグを使用したくないので(私はあまりにも多くを必要とするだろうから)、私は列挙体を使用したくない(単一性検査官と一緒に使用すると壊れやすい問題を形成するので)。

多くのゲームの共通の要件(例えば、ゲームではさまざまなゲームオブジェクトのたくさんのもので異なるリソースを集めるためにあなたのピッカックスを使用することができます)を使用してベストプラクティスを疑問に思っているのですか?

+0

各ゲートタイプでどのようなやり取りをしていますか? GateManagerスクリプトにすべてのロジックを用意するのではなく、それぞれが反応を指示するMonoBehaviourクラスのセットを作成し、必要に応じて各ゲートにアタッチし、ゲートとの衝突時に盲目的に呼び出すことができますか? (同じクラスから継承して、同じインタフェースを実装して簡単に呼び出すことができます。) – Serlite

+0

ロジックは、単にゲートと衝突する武器が十分高いレベルであれば、ゲートをアクティブにしないでくださいそれを破壊する)。だから剣は木製の門を破壊することができますが、金属の門は破壊することはできません。だから、非常にシンプルなロジックは、実際には複数のクラスを持つことはおそらく過剰ですか? –

+2

その場合、各オブジェクト(またはそれが構成するマテリアル)に強さの値を割り当てるだけでなく、各武器に対応する強さを割り当てるのはなぜですか?次に、衝突時の2つの値を比較します。すべての種類のゲートについてenumを作成しなければならない場合、あらゆる種類のバリケード/家具アイテム/ブロック/ etc ...は、プロジェクトが成長するにつれてますます多くの列挙値になります。 – Serlite

答えて

1

enum値を手動でインクリメントしてください。

public GateType gateType; 

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

ここで、「リスト」の真ん中に別のものを追加したい場合はこれはインデックスを追加したので、オブジェクトに正しい値を保持する必要があります。

3

。あなたが宣言し、これを達成するために、多くのインターフェースを使用しますが、欠点は、あなたがそれらの多く宣言し、各オブジェクトに添付されたスクリプトの多くでそれらを実装する必要がありますということですできる1

public interface IDestroyable { } 

public interface IOpenable { } 

は、あなたのスクリプトをITIN継承:

:それは衝突時で1

public class MyScript : MonoBehaviour, IDestroyable{} 

public class MyOtherScript : MonoBehaviour, IOpenable{} 

チェック


。あなたも、あなたが言及した列挙型を使用することができます。

public enum GateType 
{ 
    WoodenGate, 
    StoneGate, 
    MetalGate 
} 

はそれがある1エディタまたはスクリプト

public class GateDescription : MonoBehaviour 
{ 
    public GateType gateType; 
} 

チェックから各1について列挙を選んだこのオブジェクトはすべてのゲートオブジェクトのプレハブにあるゲートの種類を説明し、単一のスクリプトを添付します衝突時:

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

私はインターフェイスが行く方法だと思います。 –

+0

@AdamBインターフェイスを使用する唯一の欠点は、異なるインターフェイスから継承する各ゲート用のスクリプトを多数作成する必要があることです。それ以外は大丈夫です。 – Programmer

+0

はい、でも長期的に見るとコードははるかに読みやすくなります。設定には少し時間がかかりますが、最終的には無限に理解しやすく使いやすくなります。 –

0

spawn/initイベントごとに設定できます。 enumメソッドを使用する場合は、オブジェクトが生成されたときに定義することができます。明らかにあなたのゲームのメカニックに依存します。しかし、私はおそらくあなたが必要とする物質的な振る舞いのために、これをモノオーバーヘッドに外注するでしょう。そうすれば、木のアーチがどのように動作するかを変更したい場合は、1つのスクリプトを更新するだけで、自己完結型です。これはあなたのコードベースが大きくなるのに役立ち、2017.3の機能を使用してどのファイルをどのアセンブリに入れるかを定義すると、コンパイルとロード時間が向上します

関連する問題