As you might have been introduced to Incremental, Idle and Clicker games, you should have an idea what I mean. Like in Cookie Clicker. You buy first building, and the numbers start visibly going up every 1000th of a second or even smaller fractions. Like 123456789 instantly.
I have started making an Incremental game for educational purpose and I can’t simply make it go up visibly every 1000th of a second. It only goes up once a second (tick size is 1 second but I cannot seemly modify it.) In example if you buy a building that generates 10 Bones Per Second, it shows 10 Bones in the total count, waits a second, then shows 20 Bones and goes on like that. I would want it to be rather interactive than go up like a lagging pc, 1 number by second.
If the generator gives ie. 10 Bones Per Second, I’d want it to show the numbers go up faster than once a second, in other words update the total Bones display more often than once a second. But only increment the 10 Bones per second. No more or less.
using UnityEngine;
using System.Collections;
public class BonesPerSec : MonoBehaviour {
public UnityEngine.UI.Text BPS;
public Click click;
public ItemManager[] items;
public int GetBonesPerSec()
{
int tick = 0;
foreach(ItemManager item in items)
{
tick += item.count * item.tickValue;
}
return tick;
}
public void AutoBonesPerSec()
{
click.bones += GetBonesPerSec();
}
IEnumerator AutoTick()
{
while (true)
{
AutoBonesPerSec();
yield return new WaitForSeconds(1);
}
}
void Start () {
StartCoroutine(AutoTick());
}
void Update () {
BPS.text = GetBonesPerSec() + " bones/sec";
}
}
First off, even an incremental “game” like Cookie Clicker is limited by framerate… It doesn’t actually process everything at 1000 frames per second. In fact, Cookie Clicker runs at a default of 30 frames per second.
Anyway, there are two ways you can approach this. You can put the main number generation in the active updates or you can keep the coroutine and make the smooth increase superficial.
In the case of active generation, rather than using a coroutine, increment the value every frame by the amount per second scaled to the framerate. For example, this would be something like:
The rate of gain would remain constant and, in this case, unchanged from what you currently have anyway. The only difference is that the rate that gain is applied is performed gradually rather than on one-second intervals.
Alternatively, you can keep the actual rate of gain limited to 1-second intervals and make it appear to be gradual, but there’s one fatal flaw in that design without making fairly complex accommodations. WaitForSeconds() waits for a specified duration, but due to timing of frames, will very unlikely trigger again exactly when you want it to.
If your first frame after a second has passed occurs 1.03178 seconds after the previous one, then you’ve missed more than 3% of what you should have gained from that cycle.
I don’t think you can go that fast. You are limited by the Update function that is called every frame, hence you’re limited by the hardware (frame computation) … and i don’t know any device refreshing at 1000Hz.
It’s not a scripting problem, it’s a hardware problem.
Edit: use a debug.log and time.deltaTime to see how much time elapsed between the last frame and the current frame, you’ll see how fast your device(s) can go.
You can’t. You won’t get that degree of accuracy. You can proportionally increment 1000ths of seconds collectively based on how much time has passed though.
To go up in 1/1000s increments you would need a guaranteed 1000FPS.
As others have said, running at 1000frames per second is impractical, if not impossible. However the solution is trivial as you don’t need to run something 1000 times a second to calculate what would happen if you did. Smoothing by delta time (for Unity this is Time.deltaTime) is the way here as it will work in any case, no matter how fast the device runs (even if it only runs at 1fps).
Use Update or FixedUpdate (or lower the WaitForSeconds Value (but I wouldn’t recommend that)). Update is probably what you should be using here though.
Within Update, use delta time (i.e. the time passed since the method was last called) to work out how many items should be added.
So, if you want to add 10 items a second, and if you’re update was running at say 2 frames a second (obviously it’ll be a lot faster), the deltaTime would be given you as 0.5, so 10*0.5 = 5, so 5 items per every half second. If you were running at 100 frames a second, you would get 0.01 items per frame, so over 100 frames it would be 1 item.
This will give you some rounding issues, so make sure your numItemsToAddThisTick is a float, and cast numItems to a float, then when it comes to displaying the number on screen, round to an int.