Ok, so i’m trying to display a countdown timer onscreen from my Coroutine’s “yield return new WaitForSeconds”. The code works but the timer is erratic, goes fast then slow then fast. I’m new to C# so I don’t know much, but if I had to guess I think the problem is it’s counting down on every frame and not in real time. I know this means i should use “Time.deltaTime”, but i’m just not sure how to impermanent it into my script.
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class PickupManager : MonoBehaviour
{
public GameObject _camara;
public Image tripIcon;
public Image shieldIcon;
public Image speedIcon;
public Text tripTimer;
public float tripTime = 10f;
private SENaturalBloomAndDirtyLens bloomScript;
public void Start()
{
bloomScript = _camara.GetComponent("SENaturalBloomAndDirtyLens") as SENaturalBloomAndDirtyLens;
}
public void IsTripping()
{
StartCoroutine(Tripping());
}
public IEnumerator Tripping()
{
while (tripTime > 0f)
{
yield return new WaitForSeconds(1f);
tripTimer.enabled = true;
tripTimer.text = tripTime.ToString();
bloomScript.bloomIntensity = 0.3f;
bloomScript.lensDirtIntensity = 0.8f;
tripIcon.color = new Color32(0, 33, 255, 255);
tripTime -= 1f;
}
bloomScript.bloomIntensity = 0.05f;
bloomScript.lensDirtIntensity = 0.05f;
tripIcon.color = new Color32(0, 33, 255, 100);
tripTimer.enabled = false;
}
}
Moving it would not affect the countdown…it just results in behavior that is expected. Your previous code was waiting 1 second before even showing the first number of the countdown. It should follow that the first number should be displayed before waiting a second, then the countdown can continue.
Place a debug.log in the OnTriggerEnter event. I have a feeling that IsTripping() is called multiple times. This may explain the counter behavior. Short of this, the code looks correct. I don’t see why timer should not work as expected.
You are absolutely correct, it was getting triggered twice. The problem was
void Update()
{
if (isTriggered && !tripSound.isPlaying)
Destroy(gameObject);
}
the delay from waiting for the audio to finish before destroying, was causing multiple collisions. So I rewrote the script using a different approach.
using UnityEngine;
using System.Collections;
//Make sure there is always an spherecollider and audiosource component on the GameObject where this script is added.
[RequireComponent(typeof(SphereCollider), typeof(AudioSource))]
public class TripPickup : MonoBehaviour
{
public GameObject tripParticleEffect;
public PickupManager pickupManager;
public AudioClip tripSound;
// Prevent audio from auto playing.
void Start()
{
GetComponent<AudioSource>().playOnAwake = false;
}
IEnumerator OnTriggerEnter(Collider col)
{
if (col.gameObject.name == "Player")
{
//The script that we are calling it from.
pickupManager.IsTripping();
Instantiate(tripParticleEffect, gameObject.transform.position, Quaternion.LookRotation(Vector3.up));
//Prevent furthur collisions & make invisible.
GetComponent<Collider>().enabled = false;
GetComponent<Renderer>().enabled = false;
//Play the audio clip & wait before destroying it.
GetComponent<AudioSource>().PlayOneShot(tripSound);
yield return new WaitForSeconds(tripSound.length);
//Destroy it after the audio clip is done.
Destroy(this.gameObject);
}
}
}
Now it’s smooth as butter, thanks for pointing me in the right direction.