Recognising collisions after a certain time

Hiya all,

I recently started getting into game dev as a hobby (so that means I am a total noob, please be patient with me).

I am in the process of building a 2nd Level for my online coursework-game and I am trying to achieve the following:

  1. A second platform to appear after X time (which is a public variable). The code is attached to the second platform and it works.

  2. The barrier in front of the second platform to be destructible by shooting at it, but ONLY after the second platform appears. The script is attached to the barrier and it doesn’t work. What happens is that the barrier can be destroyed from the moment the game starts, so it seems that the system doesn’t check for the other requirement.

Also I get the following error on the Unity code:
“UnityException: FindGameObjectWithTag is not allowed to be called from a MonoBehaviour constructor (or instance field initializer), call it in Awake or Start instead. Called from MonoBehaviour ‘DeactivateBarrier’.
See “Script Serialization” page in the Unity Manual for further details.
DeactivateBarrier…ctor () (at Assets/Scripts/DeactivateBarrier.cs:9)”

I have tried a few iterations of the code, trying to get the code to look for the time the second platform appears, or looking for if the platform appears. I also tried to move whatever code has the FindGameObjectWithTag inside the Start class but without any luck.

Below I have attached two variations of the same code. Any help will be appreciated. Thanks!

Variation No. 1

public class DeactivateBarrier : MonoBehaviour
{
    private GameObject movingPlatform = GameObject.FindGameObjectWithTag("MovingPlatform");

    public void Update()
    {
        if (movingPlatform == true)
        {
            Invoke("OnCollisionEnter", 0);
        }
     
    }

    void OnCollisionEnter(Collision collision)
        {
            if(GameObject.FindGameObjectWithTag("Projectile"))
            {
            Destroy(gameObject, 0);
            }
        }
}

Variation No. 2

public class DeactivateBarrier : MonoBehaviour
{
    //reference for the time variable from the MoveToNextPlatform Script
    private float timeForDestruction = GameObject.Find("Second Platform").GetComponent<MoveToNextPlatform>().secondsToAppear;

    public void Update()
    {
        if (Time.timeSinceLevelLoad >= timeForDestruction)
        {
            Invoke("OnCollisionEnter", 0);
        }
     
    }

    void OnCollisionEnter(Collision collision)
        {
            if(GameObject.FindGameObjectWithTag("Projectile"))
            {
            Destroy(gameObject, 0);
            }
        }
}

You are not trying to find a gameobject because you know it is collision.
collision.tag == “Projectile”?

Don’t call OnCollisionEnter manually. You can flip a switch on collide when it collides instead of calling it manually. Then count time in Update.

bool collide = false;
float timer = 0;
readonly float duration = 1; //one second
void OnCollisionEnter(Collision collision)
{
   if(!collide && collision.tag == "Projectile")
   collide = true;
   timer = 0;
}
void Update()
{
   if(collide)
   {
     timer+=Time.deltaTime;
     if(timer>=duration)
      {
          //a second has passed so do something
      }
   }
}

Hi adehm, many thanks you for your reply. I would really appreciate if you could clarify the following things

  1. What does the !collide part do

  2. Why did you have to specify a readonly variable and why did it have to be readonly.

I have pasted your code in a new script in Unity but I get the following error shown in the screenshot.

  1. collide is a boolean so asking ‘if(collide)’ would mean bool == true so it means bool != true or bool == false.

  2. If duration is a fixed amount of time there is no need for it not to be readonly but not a requirement.

You will have to find out how to check the tag of an object; I’m not sure how to but wanted to clarify to you that you are not Finding it because you already know who is colliding with you because “void OnCollisionEnter(Collision collision)” collision is the collider colliding or maybe collision.gameObject.tag would work but I’m not sure.

A good way to check the tag on the object from the collision is like this:

if (collision.collider.CompareTag("Projectile")) {
  // Whatever you want to do if the tag is "Projectile"
}