In Unity C# deactivates a gameObjects collider upon collision, reactivating that collider but now the collision code is not working

huangapple go评论103阅读模式
英文:

In Unity C# deactivates a gameObjects collider upon collision, reactivating that collider but now the collision code is not working

问题

在Unity中使用C#编写代码,为一个游戏对象编写代码,当与玩家的投射物发生碰撞时,禁用对象的碰撞器,该碰撞器位于一个单独的子对象上。然后在计时器延迟后重新激活游戏对象的碰撞器。这一切都有效,但是当我再次尝试向对象发射投射物时,用于销毁对象的碰撞代码不再起作用,我不知道为什么。

以下是我尝试的代码:

这是我想要禁用碰撞器的对象的代码:

public GameObject blockCollider;
public bool blockDestroyed = false;
float respawnTimer = 0f;
public float timeToRes = 2f;

// Update is called once per frame
void Update()
{
    //计时器用于重新生成的时间
    if (blockDestroyed == true)
    {
        blockCollider.SetActive(false);
        gameObject.GetComponent<SpriteRenderer>().enabled = false;
        Debug.Log("计时器激活");
        respawnTimer += Time.deltaTime;
        Debug.Log(respawnTimer);

        if (respawnTimer >= timeToRes)
        {
            Debug.Log("开始重新生成");
            Respawn();
        }
    }
}

public void Respawn()
{
    gameObject.GetComponent<SpriteRenderer>().enabled = true;
    blockCollider.SetActive(true);
    Debug.Log("方块重新生成");
    blockDestroyed = false;
}

这是包含碰撞器和碰撞代码的子对象的代码:

public BreakableBlock bBlock;

void OnTriggerEnter2D(Collider2D other)
{
    GameObject whatCol = other.gameObject;
    if (whatCol.CompareTag("Projectile"))
    {
        bBlock.blockDestroyed = true;
        Debug.Log("方块被击中");
    }
}

这是玩家投射物的代码:

Rigidbody2D rB;
public float bulletSpeed = 10f;
public float damage = -2.5f;

// Start is called before the first frame update
void Start()
{
    rB = GetComponent<Rigidbody2D>();
    Vector2 force = transform.right * bulletSpeed;
    rB.AddForce(force, ForceMode2D.Impulse);
}
英文:

So in Unity using C# I'm writing code for a gameObject that upon collision with a player projectile deactivates the objects collider which is on a separate child object. Then on a timer delay reactivates the gameObjects collider this all works however when I try to fire the projectile at the object again the collision code to destroy the object no longer works and I do not know why.

Here is the code I tried so far:

Here is the code for the object I want the collider to be deactivated of:

    public GameObject blockCollider;
    public bool blockDestroyed = false;
    float respawnTimer = 0f;
    public float timeToRes = 2f;

    // Update is called once per frame
    void Update()
    {
        //Timer for how long to respawn
        if (blockDestroyed == true)
        {
            blockCollider.SetActive(false);
            gameObject.GetComponent&lt;SpriteRenderer&gt;().enabled = false;
            Debug.Log(&quot;Timer activated&quot;);
            respawnTimer += Time.deltaTime;
            Debug.Log(respawnTimer);

            if (respawnTimer &gt;= timeToRes)
            {
                Debug.Log(&quot;Begin Respawn&quot;);
                Respawn();
            }
        }
    }

    public void Respawn()
    {
        gameObject.GetComponent&lt;SpriteRenderer&gt;().enabled = true;
        blockCollider.SetActive(true);
        Debug.Log(&quot;block respawned&quot;);
        blockDestroyed = false;
    }

Here is the code of the child object which contains the collider and the collision code:

    public BreakableBlock bBlock;

    void OnTriggerEnter2D(Collider2D other)
    {
        GameObject whatCol = other.gameObject;
        if (whatCol.CompareTag(&quot;Projectile&quot;))
        {
           
            bBlock.blockDestroyed = true;
            Debug.Log(&quot;Block Hit&quot;);
          
        }
    }

Here is the code of the player projectile:

    Rigidbody2D rB;
    public float bulletSpeed = 10f;
    public float damage = -2.5f;

    // Start is called before the first frame update
    void Start()
    {
        rB = GetComponent&lt;Rigidbody2D&gt;();
        Vector2 force = transform.right * bulletSpeed;
        rB.AddForce(force, ForceMode2D.Impulse);
    }

答案1

得分: 0

你在重生后(或者碰撞后)忘记重置计时器了。

public void Respawn()
{
    gameObject.GetComponent<SpriteRenderer>().enabled = true;
    blockCollider.SetActive(true);
    Debug.Log("block respawned");
    blockDestroyed = false;
    respawnTimer = 0f; // 重置计时器以进行下一次销毁。
}

另外,在你的update函数中,你不需要不断地重新禁用游戏对象/碰撞器,你只需要在碰撞时执行一次即可:

void OnTriggerEnter2D(Collider2D other)
{
    GameObject whatCol = other.gameObject;
    if (whatCol.CompareTag("Projectile"))
    {
        // 在这里禁用它一次,它将保持禁用状态
        // 直到你再次启用它。
        bBlock.blockDestroyed = true;
        bBlock.gameObject.GetComponent<SpriteRenderer>().enabled = false;
        bBlock.gameObject.SetActive(false);
        Debug.Log("Block Hit");
        // 理想情况下,你应该调用`bBlock`的一个函数,
        // 通知它与子弹发生了碰撞,
        // 以便让它自行禁用。
    }
}
英文:

You have forgotten to reset the timer after respawning (or on collision)

public void Respawn()
{
    gameObject.GetComponent&lt;SpriteRenderer&gt;().enabled = true;
    blockCollider.SetActive(true);
    Debug.Log(&quot;block respawned&quot;);
    blockDestroyed = false;
    respawnTimer = 0f; // Reset the timer for the next destruction.
}

Also, in your update, you do not have to constantly re-disable the gameobject/collider, you just have to do it once on collision:

void OnTriggerEnter2D(Collider2D other)
{
    GameObject whatCol = other.gameObject;
    if (whatCol.CompareTag(&quot;Projectile&quot;))
    {
        // Disable it once here, and it will remain disabled
        // Until you re-enable it again.
        bBlock.blockDestroyed = true;
        bBlock.gameObject.GetComponent&lt;SpriteRenderer&gt;().enabled = false;
        bBlock.gameObject.setActive(false);
        Debug.Log(&quot;Block Hit&quot;);
        // Ideally, you should do a function call to `bBlock`
        // that notifies that it has collided with a bullet,
        // to let it disable itself.
    }
}

huangapple
  • 本文由 发表于 2023年8月9日 17:54:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/76866575.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定