当 isTrigger 为真时,碰撞对象弹开而不是通过
Colliding objects bouncing off when isTrigger is true instead of passing through
我已经遍历了一些游戏对象以在特定碰撞发生之前设置 isTrigger
属性 但是尽管 属性 是真实的,但与对象的碰撞仍然发生。请看下面的相关代码:
void OnCollisionEnter2D(Collision2D col) {
if (col.gameObject.tag == "object1") {
for (int i = 0; i < badGuys.Count; i++) {
badGuys[i].getBadGuyGameObject().GetComponent<Collider2D>().isTrigger = true;
}
}
else if (col.gameObject.tag == "object2") {
// collision with object1 always occurs before object2, though isTrigger is true the colliding object doesn't pass through the badGuys game objects, it bounces off on collision
}
else if (col.gameObject.tag == "object3") {
for (int i = 0; i < badGuys.Count; i++) {
badGuys[i].getBadGuyGameObject().GetComponent<Collider2D>().isTrigger = false;
}
}
else if (col.gameObject.tag == "badGuy") {
}
}
与 object1 的碰撞总是发生在 object2 之前,尽管 isTrigger 为 true 碰撞对象不会穿过 badGuys 游戏对象,它会在碰撞时反弹。我该如何解决?
更新 1
我刚刚意识到检查器中的 isTrigger
值是真还是假取决于我停止游戏的时间。例如,如果我在 Object1 碰撞后停止游戏,isTrigger
为真,而当我在与对象 3 碰撞后停止游戏时,它为假。这种不一致使得调试非常麻烦。这是错误还是什么?
更新 2
根据 Joe Blow 和 Agustin0987 的推荐,我使用 Collider2D
的 enabled
属性 而不是 isTrigger
。我还删除了 OnCollisionEnter2D
中几乎所有的代码以获得一个简单的测试场景。请看下面的代码:
void OnCollisionEnter2D(Collision2D col) {
if (col.gameObject.tag == "object1") {
if (badGuys[4].getBadGuyGameObject().GetComponent<Collider2D>().enabled = false) {
badGuys[4].getBadGuyGameObject().GetComponent<Collider2D>().enabled = true;
Debug.Log ("CHANGED TO TRUE");
Debug.Log ("bad guy collider enabled is " + badGuys[4].getBadGuyGameObject().GetComponent<Collider2D>().enabled);
}
else if (badGuys[4].getBadGuyGameObject().GetComponent<Collider2D>().enabled = true) {
badGuys[4].getBadGuyGameObject().GetComponent<Collider2D>().enabled = false;
Debug.Log ("CHANGED TO FALSE");
Debug.Log ("bad guy collider enabled is " + badGuys[4].getBadGuyGameObject().GetComponent<Collider2D>().enabled);
}
}
else if (col.gameObject.tag == "badGuy") {
Debug.Log("collided with bad guy"); // DOESN'T OCCUR
}
}
这次我没有循环,而是决定测试一个。 else if
是 enabled
是 true
的地方,虽然 Log
打印 false
并且 if
是 enabled
是 false
永不满足。在检查器中,坏人的 Box Collider2D 始终处于未选中状态。永远不会发生与 badGuy 的碰撞。根据我的简单场景代码,我认为它应该可以工作。
似乎您正在尝试 enable/detect badGuys
和 object2
之间的碰撞,仅当 object1
与附加此脚本的任何对象发生碰撞时(似乎是某种 BadGuyManager)。所以我建议不要将 isTrigger
设置为 true 或 false,你应该尝试启用或禁用整个 `Collider2D.
P.S:我同意 Joe Blow 的观点,你应该解释你想要实现的目标。
从来没有,曾经
我的意思是绝对从不
使用“else if”。
简单地说,永远,永远 - 永远 - 在你的余生中输入“else if”,直到你死去。
首先,删除所有代码并将其替换为:
void OnCollisionEnter2D(Collision2D col)
{
Debug.Log("We will deal with this ......... " +col.gameObject.name);
if (col.gameObject.tag == "object1")
{
Debug.Log("\t handling 'object' type issue");
HandleObjectIssue(col)
return; //NOTE HERE
}
if (col.gameObject.tag == "object1")
{
Debug.Log("\t handling 'bad guy' type issue");
HandleBadGuyIssue(col)
return; //NOTE HERE
}
}
private void HandleObjectIssue(Collision2D col)
{
Debug.Log("'\t\t object', I'm dealing with this .. " +col.gameObject.name);
}
private void HandleBadGuyIssue(Collision2D col)
{
Debug.Log("\t\t 'badguy', I'm dealing with this .. " +col.gameObject.name);
}
运行 对它进行广泛的“单元测试”。如果您愿意,可以将(使用该代码)转换回“循环”方法以查看所有项目。无论如何,请广泛测试。
--
其次,添加这个例程..
private void ToggleColliderOnGameObject( GameObject gg )
{
Debug.Log("I'm supposed to toggle the collider on: " +gg.name);
Collider2D { or whatever } col = gg.GetComponent<Collider2D>();
bool currentState = GetComponent<Collider2D>().enabled;
Debug.Log("\t it is currently: " +currentState);
bool newState = ! currentState;
col.enabled = newState;
Debug.Log("\t\t but now it is: " +newState);
}
...并用它开始单元测试。所以你会有这样的代码:
ToggleColliderOnGameObject( badGuys[4].getBadGuyGameObject() );
例如,尝试这样的事情:
void Start()
{
InvokeRepeating("teste", 1f, 1f);
}
private void Teste()
{
ToggleColliderOnGameObject( badGuys[4].getBadGuyGameObject() );
}
经过一段时间的实验和单元测试后,您将能够继续前进。
请注意,除了其他问题,很可能(例如)您的例程“getBadGuyGameObject”返回了错误的东西 - 或者一些类似的问题。
编辑:
从您的 public void createBadGuy(GameObject badGuyPrefab, BadGuyType badGuyType, Vector3 badGuyPosition)
函数中删除 badGuy = badGuyPrefab;
。这是您评论中 link 中程序员代码中的一个错误。
我已经遍历了一些游戏对象以在特定碰撞发生之前设置 isTrigger
属性 但是尽管 属性 是真实的,但与对象的碰撞仍然发生。请看下面的相关代码:
void OnCollisionEnter2D(Collision2D col) {
if (col.gameObject.tag == "object1") {
for (int i = 0; i < badGuys.Count; i++) {
badGuys[i].getBadGuyGameObject().GetComponent<Collider2D>().isTrigger = true;
}
}
else if (col.gameObject.tag == "object2") {
// collision with object1 always occurs before object2, though isTrigger is true the colliding object doesn't pass through the badGuys game objects, it bounces off on collision
}
else if (col.gameObject.tag == "object3") {
for (int i = 0; i < badGuys.Count; i++) {
badGuys[i].getBadGuyGameObject().GetComponent<Collider2D>().isTrigger = false;
}
}
else if (col.gameObject.tag == "badGuy") {
}
}
与 object1 的碰撞总是发生在 object2 之前,尽管 isTrigger 为 true 碰撞对象不会穿过 badGuys 游戏对象,它会在碰撞时反弹。我该如何解决?
更新 1
我刚刚意识到检查器中的 isTrigger
值是真还是假取决于我停止游戏的时间。例如,如果我在 Object1 碰撞后停止游戏,isTrigger
为真,而当我在与对象 3 碰撞后停止游戏时,它为假。这种不一致使得调试非常麻烦。这是错误还是什么?
更新 2
根据 Joe Blow 和 Agustin0987 的推荐,我使用 Collider2D
的 enabled
属性 而不是 isTrigger
。我还删除了 OnCollisionEnter2D
中几乎所有的代码以获得一个简单的测试场景。请看下面的代码:
void OnCollisionEnter2D(Collision2D col) {
if (col.gameObject.tag == "object1") {
if (badGuys[4].getBadGuyGameObject().GetComponent<Collider2D>().enabled = false) {
badGuys[4].getBadGuyGameObject().GetComponent<Collider2D>().enabled = true;
Debug.Log ("CHANGED TO TRUE");
Debug.Log ("bad guy collider enabled is " + badGuys[4].getBadGuyGameObject().GetComponent<Collider2D>().enabled);
}
else if (badGuys[4].getBadGuyGameObject().GetComponent<Collider2D>().enabled = true) {
badGuys[4].getBadGuyGameObject().GetComponent<Collider2D>().enabled = false;
Debug.Log ("CHANGED TO FALSE");
Debug.Log ("bad guy collider enabled is " + badGuys[4].getBadGuyGameObject().GetComponent<Collider2D>().enabled);
}
}
else if (col.gameObject.tag == "badGuy") {
Debug.Log("collided with bad guy"); // DOESN'T OCCUR
}
}
这次我没有循环,而是决定测试一个。 else if
是 enabled
是 true
的地方,虽然 Log
打印 false
并且 if
是 enabled
是 false
永不满足。在检查器中,坏人的 Box Collider2D 始终处于未选中状态。永远不会发生与 badGuy 的碰撞。根据我的简单场景代码,我认为它应该可以工作。
似乎您正在尝试 enable/detect badGuys
和 object2
之间的碰撞,仅当 object1
与附加此脚本的任何对象发生碰撞时(似乎是某种 BadGuyManager)。所以我建议不要将 isTrigger
设置为 true 或 false,你应该尝试启用或禁用整个 `Collider2D.
P.S:我同意 Joe Blow 的观点,你应该解释你想要实现的目标。
从来没有,曾经
我的意思是绝对从不
使用“else if”。
简单地说,永远,永远 - 永远 - 在你的余生中输入“else if”,直到你死去。
首先,删除所有代码并将其替换为:
void OnCollisionEnter2D(Collision2D col)
{
Debug.Log("We will deal with this ......... " +col.gameObject.name);
if (col.gameObject.tag == "object1")
{
Debug.Log("\t handling 'object' type issue");
HandleObjectIssue(col)
return; //NOTE HERE
}
if (col.gameObject.tag == "object1")
{
Debug.Log("\t handling 'bad guy' type issue");
HandleBadGuyIssue(col)
return; //NOTE HERE
}
}
private void HandleObjectIssue(Collision2D col)
{
Debug.Log("'\t\t object', I'm dealing with this .. " +col.gameObject.name);
}
private void HandleBadGuyIssue(Collision2D col)
{
Debug.Log("\t\t 'badguy', I'm dealing with this .. " +col.gameObject.name);
}
运行 对它进行广泛的“单元测试”。如果您愿意,可以将(使用该代码)转换回“循环”方法以查看所有项目。无论如何,请广泛测试。
--
其次,添加这个例程..
private void ToggleColliderOnGameObject( GameObject gg )
{
Debug.Log("I'm supposed to toggle the collider on: " +gg.name);
Collider2D { or whatever } col = gg.GetComponent<Collider2D>();
bool currentState = GetComponent<Collider2D>().enabled;
Debug.Log("\t it is currently: " +currentState);
bool newState = ! currentState;
col.enabled = newState;
Debug.Log("\t\t but now it is: " +newState);
}
...并用它开始单元测试。所以你会有这样的代码:
ToggleColliderOnGameObject( badGuys[4].getBadGuyGameObject() );
例如,尝试这样的事情:
void Start()
{
InvokeRepeating("teste", 1f, 1f);
}
private void Teste()
{
ToggleColliderOnGameObject( badGuys[4].getBadGuyGameObject() );
}
经过一段时间的实验和单元测试后,您将能够继续前进。
请注意,除了其他问题,很可能(例如)您的例程“getBadGuyGameObject”返回了错误的东西 - 或者一些类似的问题。
编辑:
从您的 public void createBadGuy(GameObject badGuyPrefab, BadGuyType badGuyType, Vector3 badGuyPosition)
函数中删除 badGuy = badGuyPrefab;
。这是您评论中 link 中程序员代码中的一个错误。