2017-11-18 1 views
0

モバイル用の3Dゲームを開発している間にボックスキャストに関する問題が発生しました。BoxCastAllで2つのオブジェクトの間にオブジェクトがあるかどうかを検出します

環境オブジェクトを通過するのを避けるために、自分のプレーヤーとターゲットの間のパスを確認したい(剛体が取り付けられておらず、特定のポイント間での移動のみ可能)。

これは私がチェックするために使用されるコードです:

private bool CheckPath (Vector3 position, Vector3 target) 
{ 
    Vector3 center = Vector3.Lerp(transform.position, target, 0.5f); 
    Vector3 halfExtents = new Vector3(1, 1, (transform.position - target).magnitude)/2; 
    Quaternion rotation = Quaternion.LookRotation((transform.position - target).normalized); 

    RaycastHit[] rhit = Physics.BoxCastAll(center, halfExtents, (transform.position - target).normalized, rotation); 
    bool result = rhit.All(r => r.collider.tag != "Environment"); 

    DebugUtilities.BoxCastDebug.DrawBox(center, halfExtents, rotation, result ? Color.green : Color.red, 3); 

    return result; 
} 

このコードは、ほとんどの場合に動作します:

enter image description here

しかし、失敗した、このような状況のために、たとえば:

enter image description here

ボックスキャストを視覚化するために、私はthis Unity Answersリンクからスクリプトを使用しました。

問題がどこにあるのかわかりませんが、上記のデバッグスクリプトに欠陥があり、ボックスキャストの呼び出しが正しいと思われました。

私はすべてのソリューションに感謝していますが、シンプルな方が高く評価されます。

いくつかのより詳細な情報(必要な場合):私はEnvironmentタグでマークされている通行不能にしたい

  • オブジェクト。
  • 私はデバッグスクリプトを書いた人ではありませんでした。最初はうまくいたようでしたので、うまくいきました。慰めのパラメータから、あなたのコード内の

答えて

1

三つの問題

【選択position変数が使用されていません。代わりにtransform.positionを使用しています。これは、開始点が間違っている可能性があることを意味します。

transform.positionをすべてpositionに置き換えてください。

。あなたはレイキャストを後方に実行しています。 transform.position - targetであってはなりません。それはtarget - transform.positionでなければなりません。

。あなたのPhysics.BoxCastAllは、レイキャストが終了していないため正しく機能しません。開始の背後にあるオブジェクトは、レイキャストによって検出されます。今、問題#2を修正すると、問題は逆転します。レイキャスト距離を提供していないため、ターゲットの背後にあるすべてのオブジェクトも検出されます。 Physics.BoxCastAll関数の最後のパラメータには、Vector3.Distance(position, target)の距離を指定できます。

固定機能:

private bool CheckPath(Vector3 position, Vector3 target) 
{ 
    Vector3 halfExtents = Vector3.one; 

    Quaternion rotation = Quaternion.LookRotation(target - position); 
    Vector3 direction = target - position; 
    float distance = Vector3.Distance(position, target); 

    RaycastHit[] rhit = Physics.BoxCastAll(position, halfExtents, direction, rotation, distance); 
    bool result = rhit.All(r => r.collider.tag != "Environment"); 

    Vector3 center = Vector3.Lerp(position, target, 0.5f); 
    halfExtents = new Vector3(1, 1, (target - position).magnitude)/2; 
    DebugUtilities.DrawBox(center, halfExtents, rotation, result ? Color.green : Color.red); 
    // Debug.DrawRay(position, direction, result ? Color.green : Color.red); 
    return result; 
} 

これは、簡単にこの機能をテストするために3つのオブジェクト(キューブ)を設定する価値があります。最初のものはObject(Player)のものです。真ん中のものは、「環境」タグの障害になります。最後のものは、プレイヤーが移動しているターゲットオブジェクトでなければなりません。

enter image description here

次に、あなたはそれをテストするには、以下のスクリプトを使用することができます。それを実行して、プレーヤーとターゲットの間に障害物を移動させ、それが期待通りに機能するはずです。

public GameObject playerObject; 
public GameObject targetObject; 

void Update() 
{ 
    Debug.Log("Path cleared: " + CheckPath(playerObject.transform.position, targetObject.transform.position)); 
} 

あなたは以下の同様の結果を取得します:今、魔法のように動作

enter image description here

+1

を、ありがとう!あなたは私がボックスキャストコールをついに理解するようにしました。 :) –

+0

問題ありません。この問題を検索する将来の人々にもっと役立つようにタイトルを変更しました – Programmer

+0

私はユニットサイズのプレーヤーを持っている場合、 'halfExtents'は' Vector3.one/2'ですか? –

関連する問題