There are many solutions here! Depends a bit on your needs. Among the favorites for your situation would probably be
you can either use a Coroutine
public void OnCollisionEnter2D(Collision2D col) //player collide with bonus
{
if (col.gameObject.name == "Cube")
{
StartCoroutine (Timer());
}
}
private IEnumerator Timer()
{
yield return new WaitForSeconds (3f);
// Something that happens after 3 seconds
}
You can directly turn the collision message itself into a Coroutine
public IEnumerator OnCollisionEnter2D(Collision2D col) //player collide with bonus
{
if (col.gameObject.name == "Cube")
{
yield return new WaitForSeconds (3f);
// Something happens after 3 seconds
}
}
Or you can use Invoke
in order to execute a method after a delay
public void OnCollisionEnter2D(Collision2D col) //player collide with bonus
{
if (col.gameObject.name == "Cube")
{
Invoke(nameof(AfterDelay), 3f);
}
}
public void AfterDelay()
{
// Something happens after 3 seconds
}
For more options and detailed information checkout How make the script wait/sleep in a simple way in unity
If by start a timer you mean e.g. a countdown display then you should definitely go with a Coroutine like e.g.
public Text text;
private Coroutine timer;
public void OnCollisionEnter2D(Collision2D col) //player collide with bonus
{
if (col.gameObject.name == "Cube")
{
if(timer == null) timer = StartCoroutine (Timer(3f));
}
}
public void OnCollisionExit2D(Collision2D col) //player left bonus before timer passed
{
if (col.gameObject.name == "Cube")
{
if(timer == null) StopCoroutine (timer);
timer = null;
}
}
private IEnumerator Timer(float durationInSeconds)
{
var timeLeft = duration;
while(timeLeft >= 0)
{
Text.text = timeLeft.ToString(F2);
yield return null;
}
// Something that happens after the timer reached 0
Debug.Log("Hello!");
}