El título no es muy descriptivo, lo sé, pero no se me ocurrió otra forma de explicarlo. Básicamente, tengo un script que controla la fecha de algo y quiero aumentar los días en 1 cada dos segundos, según la velocidad. Básicamente hay 5 velocidades, 1-5 por supuesto, y en la velocidad 1, quiero que aumente los días en uno cada 2,5 segundos, en la velocidad 2 cada 1,5, en la velocidad 3 cada 0,5, en la velocidad 4 cada 0,09 y en la velocidad 5 cada 0.04.
Escribí un código hace un rato, pero lo borré y no recuerdo cómo fue, y lo que tengo es lo que recuerdo.
Mi código actual es:
public class Date : MonoBehaviour { public TextMeshProUGUI dateText; static DateTime date = new DateTime(1, 1, 1); public static int speed = 1; public static int year; public static int month; public static int day; public static bool isPaused = false; private void Update() { if (isPaused == false) { if (speed == 1) { //first number is seconds per day //second is frames per second (default 60 because vsync) //third is hours in a day date = date.AddHours(2.5 * 60 / 24); } else if (speed == 2) { date = date.AddHours(1.5 * 60 / 24); } else if (speed == 3) { date = date.AddHours(0.5 * 60 / 24); } else if (speed == 4) { date = date.AddHours(0.09 * 60 / 24); } else if (speed == 5) { date = date.AddHours(0.04 * 60 / 24); } } year = date.Year; month = date.Month; day = date.Day; dateText.text = year.ToString() + "." + month.ToString() + "." + day.ToString(); } }pero en lugar de volverse más rápido a medida que sube, se vuelve más lento, y en la velocidad 5 tarda como 3 segundos, y la velocidad 1 va demasiado rápido. ¿Alguien puede ayudarme? Intenté mover los números, dividir, multiplicar por Time.deltaTime, pero nada funciona.
Estás multiplicando por segundos reales por día cuando deberías estar dividiendo. Además, su intuición de multiplicar por Time.deltaTime fue correcta pero, como puede ver, no es suficiente. Además, debes multiplicar por 24, no dividir. Además, multiplicar por 60 no es correcto, es lo opuesto a multiplicar por Time.deltaTime .
Esencialmente, estás agregando el recíproco de lo que deberías estar agregando.
Caminando por:
// one frame passes for each call to Update float deltaFrames = 1f; // Convert to real seconds float deltaRealSeconds = deltaFrames * Time.deltaTime; // Convert to game days float realSecondsPerDay = 2.5f; switch (speed) // this should probably be an enum, but int is fine for now { default: case 1: realSecondsPerDay = 2.5f; break; case 2: realSecondsPerDay = 1.5f; break; case 3: realSecondsPerDay = 0.5f; break; case 4: realSecondsPerDay = 0.09f; break; case 5: realSecondsPerDay = 0.04f; } float deltaGameDays = deltaRealSeconds / realSecondsPerDay; // Convert to game hours float deltaGameHours = deltaGameDays * 24f; date = date.AddHours(deltaGameHours);O simplemente:
float realSecondsPerDay = 2.5f; switch (speed) // this should probably be an enum, but int is fine for now { default: case 1: realSecondsPerDay = 2.5f; break; case 2: realSecondsPerDay = 1.5f; break; case 3: realSecondsPerDay = 0.5f; break; case 4: realSecondsPerDay = 0.09f; break; case 5: realSecondsPerDay = 0.04f; } date = date.AddHours(24f * Time.deltaTime / realSecondsPerDay);En lugar de pensar en este problema como un aumento del valor en cada iteración, le sugiero que lo piense de otra manera. Si conoce la hora en que comenzó la animación y conoce la hora actual del sistema, su código puede calcular el valor para mostrar, independientemente de cualquier noción de iteración.
Este tipo de enfoque es generalmente más estable ya que corrige los errores de redondeo y/o las iteraciones que se retrasan por alguna razón (por ejemplo, si su juego está haciendo otra cosa en paralelo).
Esencialmente, calcula cuánto tiempo ha transcurrido y lo multiplica por algún valor mágico que convierte los segundos transcurridos reales en días mostrados transcurridos. Luego agrega esto a la fecha y hora inicial que se mostró al comienzo de la animación. La fórmula para el valor mágico es simple:
real seconds per day / seconds between day increasesDado que el cálculo no se basa en el número de iteraciones, puede establecer el retardo de bucle en cualquier valor que desee, dependiendo de la frecuencia con la que desee actualizar la pantalla.
var multipliers = new Dictionary<int, float> { { 1, 2.5F }, { 2, 1.5F }, { 3, 0.5F }, { 4, 0.9F }, { 5, 0.4F } }; var initialDisplayedDate = DateTime.Parse( dateText.Text ); var animationStartTime = DateTime.Now; const float secondsPerDay = (24 * 60 * 60); var multiplier = secondsPerDay / multipliers[speed]; while (!canceled) { TimeSpan elapsed = DateTime.Now - animationStartTime; int millisecondsToAdd = elapsed.TotalMilliseconds * multiplier; DateTime dateToShow = initialDisplayedDate.AddMilliseconds( millisecondsToAdd ); dateText.Text = string.Format("{0:yyyy-MM-dd HH:mm:ss}", dateToShow); await Task.Delay(100); //You can set this to any value. A value of 100 will update the display every 100 milliseconds. This will have no effect on the value that is displayed. }