Help with code to make falling tiles stop

So, not exactly within the confines of the lesson itself, but I’ve been using this opportunity to experiment with learning and developing other forms of coding for this project, namely Flying Enemies (basically C&P of regular enemies with 0 gravity and an invisible floating collider that only interacts with them), Parallax Backgrounds, and Rising/Falling platforms. It’s all pretty satisfactory, however I’m running into an issue with the platforms that I’m hoping someone could help me with. When falling, they ignore all other colliders, so I cannot get them to either stop(land on the ground) or reset (which means if you miss a falling platform jump you have to die and start over). I read online that this was due to them being Kinematic objects, and changed them to dynamic with 0 gravity, massive mass, and x/z constraints so they can only fall downwards at the programmed speed. If I set them to interact with the background in project settings, they are forced upwards, resting outside of and on top of the map as soon as I press play, indicating that they are indeed interacting with colliders. However, when I disable the background interaction, they resume their behavior of falling while ignoring every single other collider, despite being dynamic and only unable to interact with the background and water tiles. Here is the code I have so far for my platforms:

public class FallingPlatform : MonoBehaviour
{
    [SerializeField] float fallSpeed = -1f;
    Rigidbody2D myRigidBody;
    void Start()
    {
        myRigidBody = GetComponent<Rigidbody2D>();
    }

    void Update()
    {
        
    }

    void OnCollisionEnter2D(Collision2D other) 
    {
        Vector2 fallVelocity = new Vector2(0f, fallSpeed);

        if(other.gameObject.tag == "Player")
        {
            myRigidBody.velocity = fallVelocity;
        }
    }

    void OnCollisionEnter2D(Collider2D other) 
    {
        Vector2 stop = new Vector2(0f, 0f);
        
        if(myRigidBody.IsTouchingLayers(LayerMask.GetMask("Ground")))
        {
            myRigidBody.velocity = stop;
        }
    }
    
}

I also tried "other.tag == “Ground” instead of the “IsTouchingLayers” code, with all of the proper layers selected, but that did not work either.
It functions for when the player touches it, and begins moving. I’m just not understanding why it ignores the ground. Any help is greatly appreciated!

1 Like

Just realized, I should probably add the info in my inspector for Ground and MovingGround as well.
Moving Platform:



Ground:

Hi,

Maybe the layer-based collision detection could be a solution for this problem. Look for it in the manual if you don’t know this feature yet.

As I said in the paragraph above my code, I have already implimented the layer-based collision detection. Not in those words, but that’s what I meant when I was talking about enabling/disabling the interactions with the background. The layer interactions. On the Physics 2D Project Settings. That ultimately isn’t what’s causing the issue as the falling layer tiles are designated to interact with the ground layer tiles.

Have you already tried to add Debug.Logs to your code to see what is going on during runtime? If not, do that to figure out if your tile colliders are interacting with other colliders and with which colliders.

If you implemented the cinemachine and used a collider with it, make sure that is has got “Is Trigger” ticket. Otherwise, it might push other colliders around.

So I figured out how to make the tiles reset. After some searching online I found a solution and adapted it to my code that I had written above. It required me to learn a bit about creating an IEnumerator Coroutine, using the waitforseconds command, and calling said coroutine within a method. Using these, as well as transform.position to establish an initial position within my start method, I reset the tiles to the initial position after an amount of seconds determined by a serialized field. Here’s the code, if anyone is interested:

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

public class FallingPlatform : MonoBehaviour
{
    [SerializeField] float fallSpeed = -1f;
    [SerializeField] float resetTimer = 5f;
    Rigidbody2D myRigidBody;
    Vector2 stop = new Vector2(0f, 0f);
    Vector3 initialPosition;
    void Start()
    {
        myRigidBody = GetComponent<Rigidbody2D>();
        initialPosition = transform.position;
    }

    void OnCollisionEnter2D(Collision2D other) 
    {
        if(other.gameObject.tag == "Player")
        {
            StartCoroutine(Falling());
        } 
    }

    IEnumerator Falling()
    {
        Vector2 fallVelocity = new Vector2(0f, fallSpeed);
    myRigidBody.velocity = fallVelocity;
    yield return new WaitForSeconds(resetTimer);
    myRigidBody.velocity = stop;
    transform.position = initialPosition;
    }
}
1 Like

Good for you on learning something new on your own. I find the best way to learn is to try - and fail - until you succeed.

You can now make a ‘Reset()’ coroutine to slowly move the tiles back to their original position, or have them shrink out of existence and then grow back at their initial positions. You know, instead of just suddenly teleporting back to where they started

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms