我有一艘可以射擊目標的船,但右側的大炮永遠不應該嘗試向船左側的目標射擊。因此,我使用該SignedAngle函式創建了扇區,這可以很好地用于測驗,但正如您從下面的可視化中看到的那樣,它也有點損壞。我嘗試過使用boxcast,但可惜它也不適用于這個用例。

上圖可視化了我的腳本的作用,但這不是我的問題的解決方案。由于靠近船側和前部的目標將位于該區域之外,為了澄清我的意思,請參見圖 3。

第二張圖顯示了當我們增加角度時會發生什么,我們現在可以檢測到更多目標,但是我們有 2 個大的錯誤扇區,用紅色標記,它們不應該存在。

最后,這就是我認為它應該看起來的樣子,它仍然是一個圓錐體,但最大的不同是它從寬底開始,因此它解決了我在當前 SignedAngle 函式中遇到的問題,該函式從單點確定所有內容中間。
這是根據目標所在的扇區將目標分配到正確串列的腳本:
foreach (Transform target in EnemyListManager.instance.enemyShips.ToArray())
{
if (Vector3.Distance(transform.position, target.position) > ship.mainGunCaliber.range)
continue;
Vector3 toTarget = target.position - transform.position;
print(Vector3.SignedAngle(hullParent.forward, toTarget, Vector3.up));
if (Vector3.SignedAngle(hullParent.forward, toTarget, Vector3.up) >= bowMinAngle &&
Vector3.SignedAngle(hullParent.forward, toTarget, Vector3.up) <= bowMaxAngle)
{
if (!bowTargets.Contains(target))
{
RemoveFromOthers(target);
bowTargets.Add(target);
print("added target to Bow");
}
continue;
}
if (Vector3.SignedAngle(hullParent.forward, toTarget, Vector3.up) >= sbMinAngle &&
Vector3.SignedAngle(hullParent.forward, toTarget, Vector3.up) <= sbMaxAngle)
{
if (!sbTargets.Contains(target))
{
RemoveFromOthers(target);
sbTargets.Add(target);
print("added target to SB");
}
continue;
}
if (Vector3.SignedAngle(-hullParent.forward, toTarget, Vector3.up) >= aftMinAngle &&
Vector3.SignedAngle(-hullParent.forward, toTarget, Vector3.up) <= aftMaxAngle)
{
if (!aftTargets.Contains(target))
{
RemoveFromOthers(target);
aftTargets.Add(target);
print("added target to Aft");
}
continue;
}
if (Vector3.SignedAngle(hullParent.forward, toTarget, Vector3.up) >= psMinAngle &&
Vector3.SignedAngle(hullParent.forward, toTarget, Vector3.up) <= psMaxAngle)
{
if (!psTargets.Contains(target))
{
RemoveFromOthers(target);
psTargets.Add(target);
print("added target to PS");
}
}
}
任何幫助將不勝感激如何解決這個問題!
謝謝你。
uj5u.com熱心網友回復:
我能想到幾個選擇。
- 您可以使用 4 個(或更多,也適用于上下范圍)點來測量角度,而不是我之前建議的中心的單個點。

你的代碼,對于右舷,會更像(我認為,我傾向于航海,所以我可能對標簽有誤,哈哈):
if (Vector3.SignedAngle(markerBowStarboard.right, toTarget, Vector3.up) >= sbMinAngle &&
Vector3.SignedAngle(markerAftStarboard.right, toTarget, Vector3.up) <= sbMaxAngle)
{
if (!sbTargets.Contains(target))
{
RemoveFromOthers(target);
sbTargets.Add(target);
print("added target to SB");
}
continue;
}
- 您可以嘗試從某人制作的
但同樣,它只是用一種計算換另一種計算。
- 您可以創建一個圓錐圓柱體模型,不渲染它,而是給它一個 MeshCollider,然后當物件進入物件時(
OnColliderEnter我認為?),您可以將它們添加到該方向的串列中,并在它們退出時洗掉(OnColliderExit也許?)。你可能需要做更多檢查,當它完全進入圓錐圓柱體時,因為我認為OnColliderExit(或任何它被稱為)當模型停止與實際網格碰撞時觸發,無論它是在內部還是外部目的。
我不太確定我是否喜歡其中任何一個,但我很驚訝沒有可以采用近平面和遠平面尺寸的原生“ConeCast”......但我想我只是對 Unity 說“我不想這樣做,你來做”大聲笑。
uj5u.com熱心網友回復:
這里有一些隨機的想法。我會嘗試用 2 個不同直徑的球體鑄件丟棄不需要的扇區。(

maxDistance您可以使用球體投射的引數設定檢測長度。這將確定圓錐體的長度,即右舷瞄準扇區長度。帶綠線的區域用于由 beam2 但不是 beam1 檢測到的點。這些點怎么辦?有些在錐體內,有些不在。錐體只是無數個圓,其大小由一個線性方程定義,該方程取該點的距離。因此,通過在光束方向上與光線原點的距離,您知道圓錐體該部分的圓大小。然后,您應該能夠輕松地知道您的點是否在該圓圈內/外,因此在圓錐內/外。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/508673.html - 您可以創建一個圓錐圓柱體模型,不渲染它,而是給它一個 MeshCollider,然后當物件進入物件時(
