[英]C# Unity 3D - Is there a way to make custom raycast shapes?
我有一艘可以射擊目標的船,但右側的大炮永遠不應該嘗試向船左側的目標射擊。 因此,我使用SignedAngle
function 創建了扇區,這可以很好地進行測試,但從下面的可視化中可以看出,它也有點損壞。 我嘗試過使用boxcast
,但可惜它也不適用於這個用例。
上圖可視化了我的腳本的作用,但這不是我的問題的解決方案。 由於靠近船側和前部的目標將位於該區域之外,為了澄清我的意思,請參見圖 3。
第二張圖顯示了當我們增加角度時會發生什么,我們現在可以檢測到更多目標,但是我們有 2 個大的錯誤扇區,用紅色標記,它們不應該存在。
最后,這就是我認為它應該看起來的樣子,它仍然是一個圓錐體,但最大的不同是它從一個寬底部開始,因此它解決了我在當前 SignedAngle function 中遇到的問題,它從單點確定一切中間。
這是根據目標所在的扇區將目標分配到正確列表的腳本:
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");
}
}
}
任何幫助將不勝感激如何解決這個問題!
謝謝你。
我能想到幾個選擇。
你的代碼,對於右舷,會更像(我認為,我傾向於航海,所以我可能對標簽有誤,哈哈):
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;
}
但同樣,它只是用一種計算換另一種計算。
OnColliderEnter
(我認為是 OnColliderEnter ?)您可以將它們添加到該方向的列表並在它們退出時刪除(可能是OnColliderExit
? )。 你可能需要做更多的檢查,當它完全進入圓錐圓柱體時,因為我認為當 model 停止與實際網格碰撞時會觸發OnColliderExit
(或任何它的名稱),無論它是在內部還是外部object。我不太確定我是否喜歡其中任何一個,但我很驚訝沒有可以采用近平面和遠平面尺寸的原生“ConeCast”......但我想我只是對 Unity 說“我不想這樣做,你來做”大聲笑。
這里有一些隨機的想法。 我會嘗試用 2 個不同直徑的球體鑄件丟棄不需要的扇區。 ( https://docs.unity3d.com/ScriptReference/Physics.SphereCast.html )。 請參見下圖中的 beam2 和 beam1 以及 。
您可以使用球體投射的maxDistance
參數設置檢測長度。 這將確定圓錐體的長度,即右舷瞄准扇區長度。 帶綠線的區域用於由 beam2 但不是 beam1 檢測到的點。
這些點怎么辦? 有些在錐體內,有些不在。 錐體只是無數個圓,其大小由一個線性方程定義,該方程取該點的距離。 因此,通過在光束方向上與光線原點的距離,您知道圓錐體該部分的圓大小。 然后,您應該能夠輕松地知道您的點是否在該圓圈內/外,因此在圓錐內/外。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.