我正在制作一個氣球戰斗風格的游戲,但我遇到了物體碰撞的問題。每個角色的頭頂都有兩個氣球,每個氣球都有一個觸發盒對撞機。我想讓它一次只能擊中一個氣球,這樣你就不能同時摧毀兩個氣球。為了做到這一點,我添加了一個名為 isAttacking 的布林值,以防止它同時破壞多個氣球。
您好,我正在制作一款氣球大戰風格的游戲,但遇到了物體碰撞問題。每個角色的頭頂都有兩個氣球,每個氣球都有一個觸發盒對撞機。我想讓它一次只能擊中一個氣球,這樣你就不能同時摧毀兩個氣球。為了做到這一點,我添加了一個名為 isAttacking 的布林值,以防止它同時破壞多個氣球。
public bool isAttacking = false;
private void OnTriggerEnter(Collider collision)
{
if (collision.GetComponent<Collider>().gameObject.layer == 7 && collision.GetComponent<Collider>().gameObject.tag != this.gameObject.tag)
{
if (!isAttacking)
{
Destroy(collision.GetComponent<Collider>().transform.parent.gameObject);
transform.parent.gameObject.GetComponent<Jump>().jump = true;
isAttacking = true;
}
}
}
void LateUpdate()
{
if (isAttacking)
{
isAttacking = false;
}
}
雖然它確實可以防止記錄兩次碰撞,但我仍然發現這個解決方案是不夠的,因為被摧毀的氣球不一定是最接近摧毀它的角色的氣球。我怎樣才能改進碰撞代碼,以便它只記錄靠近角色發生的碰撞?
uj5u.com熱心網友回復:
在 afaik 的一幀內,沒有可靠的OnTriggerEnter呼叫順序(它在某種程度上基于物件的 instanceID,但這不會真正幫助您)。
你可以做的是比較距離,有點像例如
private readonly HashSet<GameObject> hittingObjects = new();
[SerializeField] private Jump jump;
private void Awake()
{
if(!jump) jump = GetComponentInParent<Jump>(true);
}
private void OnTriggerEnter(Collider collision)
{
if (collision.layer == 7 && !collision.CompareTag(gameObject.tag))
{
hittingObjects.Add(collision.transform.parent.gameObject);
}
}
private void LateUpdate()
{
if (hittingObjects.Count > 0)
{
var closestHit = hittingObjects.OrderBy(hit => (transform.posiion - hit.transform.position).sqrMagnitude).First();
Destroy(closestHit);
jump.jump = true;
hittingObjects.Clear();
}
}
注意:這仍然不能阻止該物件在下一次物理更新中與另一個氣球相撞。如果您也想跟蹤它,您可以使其稍微復雜一些,并且僅在您新進入觸發器時才允許碰撞=>您必須再次退出物件才能再次擊中它。
有點像也許
private readonly HashSet<GameObject> hastoExitFirstObjects = new();
private readonly HashSet<GameObject> newHittingObjects = new();
[SerializeField] private Jump jump;
private void Awake()
{
if(!jump) jump = GetComponentInParent<Jump>(true);
}
private void OnTriggerEnter(Collider collision)
{
if (collision.layer == 7 && !collision.CompareTag(gameObject.tag))
{
var hit = collision.transform.parent.gameObject;
if(!hastoExitFirstObjects.Contains(hit))
{
newHittingObjects.Add();
}
}
}
private void OnTriggerExit(Collider collision)
{
if (collision.layer == 7 && !collision.CompareTag(gameObject.tag))
{
var hit = collision.transform.parent.gameObject;
hastoExitFirstObjects.Remove(hit);
}
}
private void LateUpdate()
{
if (newHittingObjects.Count > 0)
{
var closestHit = newHittingObjects.OrderBy(hit => (transform.posiion - hit.transform.position).sqrMagnitude).First();
newHittingObjects.Remove(closestHit);
Destroy(closestHit);
jump.jump = true;
foreach(var hit in newHittingObjects)
{
hastoExitFirstObjects.Add(hit);
}
newHittingObjects.Clear();
}
}
uj5u.com熱心網友回復:
首先,檢查您OnTriggerEnter是否正在為兩個氣球執行。大概是吧?
然后在執行的那一刻OnTriggerEnter,比較collision你的氣球的位置,看看哪個是最近的,然后銷毀最近的氣球,也許設定一個變數isInvulnerable為真,這樣如果為真,里面就沒有氣球可以被破壞OnTriggerEnter.
uj5u.com熱心網友回復:
我一次只啟用一個氣球盒對撞機,當它彈出時,在 1 秒延遲后啟用另一個氣球。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/533281.html
標籤:C#unity3d
上一篇:C#串列的問題-RemoveAt
