2016-12-22 18 views
1

私は、別のオブジェクトに向かって移動して物理的に衝突するオブジェクトを持っています。衝突/衝突イベントが1回だけ発生します。私はboolを使ってみましたが、意図したとおりに動作しませんでした。私は何か間違っているようだ。一度だけ衝突/衝突を検出する

bool doDamage = true; 
void OnCollisionEnter2D(Collision2D other) 
{ 
    if (other.gameObject.tag == "Target" && doDamage) 
    { 
     doDamage = false; 
     // damage code 
    } 
} 

void OnCollisionExit2D(Collision2D other) 
{ 
    if (other.gameObject.tag == "Target") 
    { 
     doDamage = true; 
    } 
} 

編集:

は、私が「ダメージコードが」2つの物体が接触して残っている場合でも、一度だけ実行したいです。このスクリプトは1つのオブジェクトにのみ割り当てられ、両方には割り当てられません。

+0

あなたは全体の衝突が一度だけ起こるべきであることを意味します、そして、このオブジェクトは衝突者のように振る舞うべきですか? –

+0

私は全体の衝突が一度だけ起こることを望みます。 – Abdou023

+0

ゲームオブジェクトのさまざまなレイヤーを準備します。物理設定では、これらの2つのレイヤのレイヤコリジョンマトリックスのチェックを外します。衝突後に、両方のオブジェクトに同じレイヤーを設定し、いずれかのレイヤーを変更します。彼らはもはや衝突しません。また、衝突後に衝突者の1人をトリガに変えることもできます。 –

答えて

2

コードが機能しない理由を説明する最も簡単な方法はわかりませんが、私は試してみます。

  1. ゲームオブジェクトA変数doDamageと:

    次の2つのゲームオブジェクトを持っています。

  2. ゲームオブジェクトBdoDamageが可変です。

    ゲームオブジェクトBゲームオブジェクトA衝突

選択図OnCollisionEnter2D機能をゲームオブジェクトAで呼び出されます。 doDamageがtrueであるため、 if(other.gameObject.tag == "Target" && doDamage)が実行されます。 ゲームオブジェクトAから

B選択図doDamage変数は、次にfalseに設定されています。

これは、doDamageの変数GameObject Bには影響しません。

そして

C選択図OnCollisionEnter2D機能ゲームオブジェクトBで呼び出されます。 doDamageがtrueであるため、 if(other.gameObject.tag == "Target" && doDamage)が実行されます。 ゲームオブジェクトBから

D選択図doDamage変数は、次にfalseに設定されています。

それぞれOnCollisionEnter2DコールでdoDamageが常にtrueであるため、被害コードが両方とも実行されます。あなたが現在行っていることは、それぞれ個の個の変数にのみ影響しています。スクリプト。あなたが現在をやっている

は:

地元の場合はチェックしながらfalseローカル/このスクリプトでdoDamageを設定

/このdoDamageを設定したり、されていません。 falseスクリプトで

設定doDamageそれが設定されているかどうか確認するために/このdoDamage地元を読む:

あなたがを行うために必要なもの

。一度コードのスニペットを実行したい場合は、あなたのコードをトリガーするコールバックイベントにコードを直接実行

public class DamageStatus : MonoBehaviour 
{ 
    bool detectedBefore = false; 

    void OnCollisionEnter2D(Collision2D other) 
    { 
     if (other.gameObject.CompareTag("Target")) 
     { 
      //Exit if we have already done some damage 
      if (detectedBefore) 
      { 
       return; 
      } 

      //Set the other detectedBefore variable to true 
      DamageStatus dmStat = other.gameObject.GetComponent<DamageStatus>(); 
      if (dmStat) 
      { 
       dmStat.detectedBefore = true; 
      } 

      // Put damage/or code to run once below 

     } 
    } 

    void OnCollisionExit2D(Collision2D other) 
    { 
     if (other.gameObject.tag == "Target") 
     { 
      //Reset on exit? 
      detectedBefore = false; 
     } 
    } 
} 
+0

申し訳ありませんが、私は以前これを指摘していませんでしたが、このスクリプトは1つのゲームオブジェクトにのみ割り当てられています。 – Abdou023

+0

それを一度検出するとどういう意味ですか? – Programmer

+0

最初のオブジェクトが第2のオブジェクトに当たったとき、衝突はアクティブのままであり、第1のオブジェクトはダメージを受け続けます。衝突イベントの被害コードを1回だけ実行したい。 – Abdou023

0

これは、それがどのように見えるかです。

void OnCollisionEnter2D(Collision2D other) 
{ 
    DoSomeDamageTo(other.gameObject); 
} 

これは、衝突時に1回だけトリガする必要があります。

あなたは今まで起こる度にこれをしたい場合(例:スクリプトを保持しているオブジェクトが再び何かをヒットした場合)、あなたは被害がすでに行われていると言うことでフラグをする必要があります:

bool hasHitSomething = false; 
void OnCollisionEnter2D(Collision2D other) 
{ 
    if (!hasHitSomething) 
    { 
     DoSomeDamageTo(other.gameObject); 
     hasHitSomething = true; 
    } 
} 

私はあなたが共有したコードを与えられたと考えています。オブジェクトがエンジン内で複数回衝突しているか(固体で物理的に制御されている場合は非常に可能です)、複数回呼び出されるOnCollisionEnterにつながります。 OnCollisionEnter should only be called once per collision.複数回呼び出されているのを観測している場合は、実際に複数の衝突を観察しているか、あいまいなUnityバグが見つかりました。前者は多く、多くはそうです。

+0

コードの最初の部分は、私がやっていることと変わりません。 – Abdou023