Boxes aren't falling correctly. Help!

Hello! I’m working on a 2D tower defense game where you protect a nexus by placing towers such as boxes and turrets. However, there’s an issue in the box behavior. What’s supposed to happen is the box should fall down if there is nothing to block its path, however, it seems that when a box gets destroyed by an enemy, the boxes above will not fall down no matter what.

You can see it in this video:

The enemies have a rigidbody attached to them and a 2d collider with the isTrigger enabled, tho I don’t think the enemies are causing this since sometimes the boxes get stuck in the air by themselves.

Here’s the script that handles the box logic

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BoxLogic : MonoBehaviour
{
    public float fallSpeed = 1.0f;
    private float timer = 0f;
    private Vector3 targetPos;
    private bool isFalling = true;

    // Start is called before the first frame update
    void Start()
    {
        targetPos = transform.position;
    }

    // Update is called once per frame
    void Update()
    {
        Vector3 rayOrigin = transform.position + Vector3.down * 0.5f;
        RaycastHit2D hit = Physics2D.Raycast(rayOrigin, Vector3.down, 0.1f);

        if (hit.collider == null)
        {
            isFalling = true;
        }

        if(isFalling)
        {
            timer += Time.deltaTime;

            if(timer > 1.0f / fallSpeed)
            {
                timer = 0f;
                Vector3 potentialPos = targetPos + Vector3.down;
                if (CheckCollision(potentialPos))
                {
                    isFalling = false;
                }
                else
                {
                    targetPos = potentialPos;
                    transform.position = targetPos;
                }
            }
        }
    }

    private bool CheckCollision(Vector3 position)
    {
        RaycastHit2D hit = Physics2D.Raycast(position, Vector2.zero);
        return hit.collider != null;
    }

}

Here’s my health script

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class Health : MonoBehaviour
{
    public int maxHealth = 50;
    private int currentHealth;
    public bool isNexus;

    public GameObject particles;

    void Start()
    {
        currentHealth = maxHealth;
    }

    public void TakeDamage(int damage)
    {
        currentHealth -= damage;

        if (currentHealth <= 0)
        {
            GameObject tempParticles = Instantiate(particles, transform.position, Quaternion.identity);
            Die();
            Destroy(tempParticles, 5f);
        }
    }

    void Die()
    {
        if(isNexus)
        {
            ReloadScene();
        }

        Destroy(gameObject);
    }

    public int GetCurrentHealth()
    {
        return currentHealth;
    }

    public void ReloadScene()
    {
        SceneManager.LoadScene(0);
    }
}

If you’re relying on Rigidbody physics, perhaps the boxes above are falling asleep.

Some cures:

  • set them to not fall asleep
  • wake them up when the boxes below goes away.

I’m not using rigidbodies because I don’t want to have to deal with mass. Instead, I’m moving the box by 1 tile downwards by adding to the transform’s position

Have you tried debugging anything yet? For instance, does your CheckCollision function work as expected? Is the box falling = true but not moving? Is the potential position what is expected?

Debug various things until you find unexpected results, then correct it.

Then as LaneFox hints at, it’s likely just a bug you wrote, and that means… time to start debugging!

By debugging you can find out exactly what your program is doing so you can fix it.

Use the above techniques to get the information you need in order to reason about what the problem is.

You can also use Debug.Log(...); statements to find out if any of your code is even running. Don’t assume it is.

Once you understand what the problem is, you may begin to reason about a solution to the problem.

Remember with Unity the code is only a tiny fraction of the problem space. Everything asset- and scene- wise must also be set up correctly to match the associated code and its assumptions.