【问题标题】:Is there a way to make something take a set amount of time c#有没有办法让某事花费一定的时间c#
【发布时间】:2021-03-17 15:05:39
【问题描述】:

我知道,标题并不是真正的描述性,但我想不出另一种方式来解释它。基本上,我有一个控制某事日期的脚本,我想每隔几秒将天数增加 1,具体取决于速度。基本上有 5 种速度,当然是 1-5,在速度 1 上,我希望它每 2.5 秒增加一天,速度 2 每 1.5 秒,速度 3 每 0.5,速度 4 每 0.09,速度 5 每0.04.

我前段时间写了一些代码,但我删除了它,我不记得它是怎么回事,我所拥有的就是我记得的。

我当前的代码是:

    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();
        }

    }

但它不是随着上升而变得更快,而是变得更慢,在速度 5 上大约需要 3 秒,而速度 1 变得更快。谁能帮我?尝试移动数字,除以 Time.deltaTime,但没有任何效果。

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    当你应该除法时,你每天乘以实际秒数。此外,您乘以 Time.deltaTime 的直觉是正确的,但正如您所见,这还不够。此外,您应该乘以 24,而不是除以。另外,乘以 60 是不正确的,它与乘以 Time.deltaTime 正好相反。

    本质上,您正在添加您应该添加的内容的倒数。

    走过:

    // 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);
    

    或者,简单地说:

    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);
    

    【讨论】:

    • 尝试在某一点分割,猜猜可能不是按正确的顺序?无论如何,我稍后会尝试这个。感谢您的帮助
    • @Endergaming2546 如果它适合你,请考虑accepting这个答案。
    【解决方案2】:

    与其把这个问题想成每次迭代都会增加值,我建议你换一种方式去想。如果您知道动画开始的时间,并且您知道当前系统时间,那么您的代码可以计算要显示的值,而与任何迭代概念无关。

    这种方法通常更稳定,因为它可以纠正舍入错误和/或由于某种原因(例如,如果您的游戏并行执行其他操作)而延迟的迭代。

    本质上,您计算已经过去了多少时间,并将其乘以某个神奇值,该值将实际经过的秒数转换为经过的显示天数。然后将其添加到动画开始时显示的初始日期时间。魔法值的公式很简单:

    real seconds per day / seconds between day increases
    

    由于计算不依赖于迭代次数,您可以将循环延迟设置为所需的任何值,具体取决于您希望刷新显示的频率。

    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.
    }
    

    【讨论】:

      猜你喜欢
      • 2019-08-14
      • 1970-01-01
      • 2019-03-31
      • 2020-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多