特定のコンテキストでいくつかのオブジェクトとの衝突を無視する


14

私はUnityで車を使ってレースゲームを作っています。車にはブースト/ニトロパワーアップがあります。ブースト中、ゾンビと衝突するときは逸脱したくありませんが、壁と衝突するときは逸脱したいと思います。

一方、私はゾンビとの衝突を無視したくありません。なぜなら、私はゾンビを衝突時にヒットさせたいからです。

これをどのように処理すればよいですか?基本的に、特定のオブジェクトと衝突したときに車が回転しないようにしたいです。

回答:


7

実行時にレイヤーを操作することを検討してください。

特定のオブジェクトとレイヤー全体の衝突の有効化/無効化

Physics.IgnoreCollisionおよびPhysics.IgnoreLayerCollisionを使用すると、2つのコライダー間、および2つのレイヤー間の衝突をそれぞれ無効にすることができます。

特定のコライダーを衝突から除外したい場合、それを行う方法は組み込まれていません。非トリガーコライダーで非キネマティックリジッドボディを使用している場合、タグで応答を除外しようとしても、常に応答があります。

プロジェクトでこれを達成する方法は、「Void」という名前のレイヤーを作成することでした。Voidはまったく衝突しません。

これで、レイヤーを「無効」に設定してコライダーのコリジョンを一時的に無効にし、古いレイヤーを復元してコライダーを再度有効にすることができます。

ここに要点があります:

int oldLayer = -1;
int voidLayer;

void Start()
{
    voidLayer = LayerMask.NameToLayer("Void");
}

void DisableCollider(Collider col)
{
    oldLayer = col.gameObject.layer;
    col.gameObject.layer = voidLayer;
}

void EnableCollider(Collider col)
{
    col.gameObject.layer = oldLayer;
}

剛体の子であるコライダーを有効または無効にすると、状況によっては実際に問題が発生する可能性があるため、これを具体的に行いました。そのため、複合剛体コライダーの一部を確実に無効にすることはできませんが、複合コライダーパーツの1つのレイヤーを確実に交換することはできます。

今、あなたの特定の状況

ゾンビの衝突があなたの車に与える影響を減らすには、ゾンビをキネマティックリジッドボディトリガーにするか、質量を非常に小さくして(float.Epsilonのように)、車の勢いに影響を与えないようにします。衝突時には、このレイヤー切り替えを行うこともできます。これにより、最初の衝突が車体に無視できるほどの力を加えた場合でも、後続の衝突はトリガーされません。

車と衝突しないレイヤーに切り替えることもできます。

また、ランオーバーでアクティブになるゾンビに別のコライダーを置くこともできます。これにより、OnTriggerEnterの衝撃力を偽造できます。これほど正確に取得することはできませんが、接触法線がゾンビをどこかに面白くするのに十分であった場所を概算することができます。

自問する必要があります:

  • 車で走り回ったゾンビをノックしたいのですか、それとも死のアニメーションを再生するだけですか?

  • 車の速度と角速度がゾンビを打つことにより小さな影響を受けるかどうか気にしますか?


1

車がブーストを開始したら、すべてのゾンビでPhysics.IgnoreCollisionを呼び出し、関数にプレイヤーオブジェクトも渡します。これにより、Unityはプレイヤーとゾンビとの衝突に反応しなくなります。車のブーストが終了したら、Physics.IgnoreCollisionゾンビごとに再度呼び出して、プレーヤーオブジェクトを渡し、false衝突応答を再び開始します。


しかし、それは彼らが他の何とも衝突しないことを意味します。
ポールマンタ

さらに調査します。私が考えることができる唯一のものは次のとおりです。おそらく、OnCollisionEnterからfalseを返すことで衝突を無視できますか?
ワキデフ

@Wackidevこれはそうではありません。
リス・ファン・デル・ワーデン

@ポール回答を編集しました。
ワキデフ

0

オブジェクトの名前を確認したり、オブジェクトクラスに名前の値を追加して確認したりできると思いますか?

bool boosting = false; //need a trigger in the game to set this to true.

function OnCollisionEnter(theCollision : Collision)
{   
    if (boosting == true)
    {
        if(theCollision.gameObject.name == "Zombie")
        {
              Debug.Log("Zombie hit during boost");              
        }
        else if(theCollision.gameObject.name == "Wall")
        {
              Debug.Log("Wall hit during boost");            
        }
    }
    else 
    {
        if(theCollision.gameObject.name == "Zombie")
        {
              Debug.Log("Zombie hit not in boost");              
        }
        else if(theCollision.gameObject.name == "Wall")
        {
              Debug.Log("Wall hit not in boost");                
        }
    }
}

次に、ブーストのチェックに使用できる別の変数を用意し、それをチェックに追加します。

編集:この変数を追加しました。


彼は衝突の通知方法を知っています。彼は結果として何らかのアクションが取られることを望んでいません。彼は、特定の場合に組み込みの衝突応答を無効にしたいと考えています。
ワキデフ

衝突がトリガーされたときに何が起こるかは確かに括弧の間にありますか?以前は単一性を使用したことがないので、わかりませんが、cocos2dでXNAはそのように実行されます。
ルイス

実際、UnityはPhysXを介して衝突自体を処理します。OnCollisionEnterは単なる通知メソッドです。実際の衝突応答を処理するようには設計されていません。
ワキデフ

0

物理エンジンを使用して、物が衝突したときに形状/質量に基づいて自動的に「偏差」を行っていると思いますか?その場合は、ゾンビの質量を最小限の値に変更すると、車に影響を与えません。


0

ここには2つのクラスの回答があります。

  1. 衝突の無視または無効化
    • これらの解決策は問題を解決するものではありません。彼はゾンビが命中したときに飛行することを望んでいます。
  2. 変化する質量:
    • これは良いアプローチです。それに応じてイナーシャも変更することを忘れないでください。
      • 代わりに、ブースト時に車の質量と慣性を変更することもできます(これは、ブースト時に車上のすべての非運動物体の影響を減らすために行います)
      • これは、運動学的であると仮定して、道路や壁に影響を与えてはなりません。

お役に立てれば!


6年前の既存の回答のうち2つは、ここで提案している質量ベースのアプローチを既に推奨しています。追加したい新しい戦略はありますか?
DMGregory

申し訳ありませんが、私はまだ賛成票を投じることができません。ポール・マンタが道に迷わないようにしたかったのです。
dwuLive
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.