I have seen a few more complicated timers when i looked it up, but i just need something that will show a bar that goes down for 30 seconds or so. then i can have an action happen at the end of the timer. what do you think would be the best method to get this done?
Morning @Sylvir ,
you can create a new Slider UI element in scene.
create a new C# script called countdown, and copy this script into it. and drag onto Slider gameobject.
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class countdown : MonoBehaviour {
public float counter = 10.0f; // declare a float and et to 30 to begin with for the max values
private Slider mySlider; // declare a slider object
// Use this for initialization
void Start () {
// set reference to slider
mySlider = GetComponent<Slider>();
mySlider.maxValue = counter;
mySlider.value = counter;
}
// Update is called once per frame
void Update () {
// decrement counter float with time it takes to draw each frame if its above 0;
if (counter > float.Epsilon)
{
counter-= Time.deltaTime;
}
else
{
// if the values so low, just set to 0
counter = 0;
}
// set the sliders value to counter value
mySlider.value = counter;
if (counter == 0)
{
Debug.Log("do something cos counter is 0");
}
}
}
change the slders starting value in public variable in inspector on countdown script.
just done it this morning to see, just creates a simple countdown to get you started
good morning oboshape!
thank you for the help! this will defiantly help me get going with it. I am still learning both unity and C# but with the great people on here i am picking up the basics and more every day as i keep trying to learn more! hope you have a great day!
then just calling under one of my if statements should make it so that if conditions are met, then the timer will go, then after it ends i can put the action i want associated with it. (if i understand right) will get working on it in just a bit now thanks again!
No worries, glad to give a hand.
basically the IF checks conditions, and if those conditions are met then do what i put here… (ie in the brackets)
you can create a function, and call it from there, or if its something small, just pop it in there.
yea its a brill forum, ive learned soo much from here on my travels, im still learning too…
could you explain what the float.epsilon is? trying to work with the script now, but unsure what that is effecting
time.delta time i think i understand that is the seconds that it counts down by, but i am not quiet understand what the float.epsilon effects.
time.deltatime is the time it takes in between frame draws.
float.epsilon was just put in there since the float timer value counts down/reduces, when it gets to a small enough number, just make it 0 (i think lol)
oh okay, thanks!
hmm, i am getting an error trying to set up my script with the timer… would you mind taking a quick look and seeing if you know what this error means?
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class BuildVirus : BaseVariables {
private float counter = 30.00f;
void Start(){
// set reference to slider
mySlider = GetComponent<Slider>();
mySlider.maxValue = counter;
mySlider.value = counter;
}
void Update(){
VirusCount.text = "Virus Count: " + virus;
// TechPoints.text = "Tech Points: " + techPoints;
// vpc.text = "VPC: " + virusPerClick;
Debug.Log ("techPoints:" + techPoints);
}
public void Clicked(){
VirusCost = 50;
// Debug.Log("techPoints before:"+techPoints);
if(techPoints >= VirusCost){
TimeCountDown();
techPoints -= VirusCost;
virus += 1;
}
// Debug.Log("techPoints after:"+techPoints);
}
public void TechPointsClicked(){
techPoints += techPointsPerClick;
{
}
}
void TimeCountDown () {
// decrement counter float with time it takes to draw each frame if its above 0;
if (counter > float.Epsilon)
{
counter-= Time.deltaTime;
}
else
{
// if the values so low, just set to 0
counter = 0;
}
// set the sliders value to counter value
mySlider.value = counter;
if (counter == 0)
{
}
}
}
the error says…
NullReferenceException: Object reference not set to an instance of an object
BuildVirus.TimeCountDown () (at Assets/Scripts/BuildVirus.cs:60)
BuildVirus.Clicked () (at Assets/Scripts/BuildVirus.cs:29)
UnityEngine.Events.InvokableCall.Invoke (System.Object[ ] args) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:110)
UnityEngine.Events.InvokableCallList.Invoke (System.Object[ ] parameters) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:574)
UnityEngine.Events.UnityEventBase.Invoke (System.Object[ ] parameters) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:716)
UnityEngine.Events.UnityEvent.Invoke () (at C:/buildslave/unity/build/Runtime/Export/UnityEvent_0.cs:53)
UnityEngine.UI.Button.Press () (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:35)
UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:44)
UnityEngine.EventSystems.ExecuteEvents.Execute (IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:52)
UnityEngine.EventSystems.ExecuteEvents.Execute[IPointerClickHandler] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.EventFunction`1 functor) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:269)
UnityEngine.EventSystems.EventSystem:Update()
i am trying to work out what is not set… i have the script i just shared on the button that i click when i have 50 tech points, and then it gets that error…
i dont know what you have in your base class, as in what variables are inhereted
but for a starter for 10.
on 17 you have
VirusCount.text = "Virus Count: " + virus;
you need to make a public reference to VirusCount, i take it that its a UI element. as it wont know what this is.
i just had the slider in there as an example, how are you actually implementing the timer?
kind of sounds like your needing a coroutine at first glance
oh,
my base is this right now…
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class BaseVariables : MonoBehaviour {
public Slider mySlider;
public float counter = 10.0f;
public int virusPerClick = 1;
public float virus = 0.00f;
public int VirusCost ;
public int click;
public float techPointsPerClick = 1;
public static float techPoints = 0.00f;
private float baseCost;
public string itemName;
public int clickPower;
public int count = 0;
public float cost;
public int SofwareCost = 50;
public UnityEngine.UI.Text VirusCount;
public UnityEngine.UI.Text TechPoints;
public UnityEngine.UI.Text itemInfo;
public UnityEngine.UI.Text money;
public static float Money = 0.00f;
public int moneyPerSoftware = 10;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}
the virus count is a text that shows the # of viruses you have, it was working before i tried adding the time element lol
seems to be having trouble in 2 places with this line mySlider.maxValue = counter;
ah ok, remember when in the example i done the script was attached to the slider, so the getComponent would find the attached Slider component.
in your case, you have dragged the slider object to the public reference slot, as opposed to what was in the example.
so comment out line 11 that has the following, thats the line number shown above in your buildvirus script.
mySlider = GetComponent<Slider>();
see how that goes
okay, thanks ill try that… sorry i got it all mixed up, i thought that that was there to make it be able to be slotted in in the interface… lol ill try that.
so now the virus gets bought using the tech points, but the slider doesnt do anything.
just noticed another thing, your declaring counter in your base class, and your inherited class, comment out the one on your BuildVirus.
ok ive just had a play and try and build something.
as it stands, this will only go through the timer check once each click, ie lowering by roughly 0.1 each time, you can see this in the inspector value for counter…
what it sounds like you might be after is a coroutine as this will run through all iterations and yield back to the main code, until exit conditions are met and the routine completes, to implement this try the following…
replace the TimeCountdown function with the following
IEnumerator TimeCountDown () {
while (counter > float.Epsilon)
{
counter-= Time.deltaTime;
mySlider.value = counter;
yield return null;
}
Debug.Log ("timer reached 0 and resetting!");
mySlider.value = mySlider.maxValue;
}
then you will need to put the following where you would have normally called the function, as what you want is the coroutine to carry on through all the iterations until complete.
so where you have
TimeCountDown ();
replace that with the following
StartCoroutine( TimeCountDown());
again this is only for example sake, you will have to ammend and change it to suit your situation by putting a flag in the coroutine somewere to check that its running so you cant call it twice…
hope that helps a bit more, its hard to give you exact code, as i dont understand how its used in your scene, thats for you to implement, but this should show you results
Rgds
DaZ
awesome, thanks for checking into it for me, ill do some reading up on the documentation on coroutines as i am not fermillier with them yet, and then ill give this code structure a try, and tweak it to fit me scene. thanks again for all the help it is very much apreciaited