unity游戏引擎-在C#中格式化大数字

本文关键字:格式化 数字 游戏 引擎 unity | 更新日期: 2023-09-27 17:59:08

我正在使用Unity制作一个"增量游戏",也称为"空闲游戏",我正在尝试格式化大数字。例如,当gold达到1000或更多时,它将显示为Gold: 1k而不是Gold: 1000

using UnityEngine;
using System.Collections;
public class Click : MonoBehaviour {
    public UnityEngine.UI.Text GoldDisplay;
    public UnityEngine.UI.Text GPC;
    public double gold = 0.0;
    public int gpc = 1;
    void Update(){
        GoldDisplay.text = "Gold: " +  gold.ToString ("#,#");
        //Following is attempt at changing 10,000,000 to 10.0M
        if (gold >= 10000000) {
        GoldDisplay.text = "Gold: " + gold.ToString ("#,#M");
        }
        GPC.text = "GPC: " + gpc;
    }
    public void Clicked(){
            gold += gpc;
    }
}

我在网上搜索时尝试过其他例子,这就是gold.ToString ("#,#");的来源,但都不起作用。

unity游戏引擎-在C#中格式化大数字

轻微重构:

public static string KMBMaker( double num )
{
    double numStr;
    string suffix;
    if( num < 1000d )
    {
        numStr = num;
        suffix = "";
    }
    else if( num < 1000000d )
    {
        numStr = num/1000d;
        suffix = "K";
    }
    else if( num < 1000000000d )
    {
        numStr = num/1000000d;
        suffix = "M";
    }
    else
    {
        numStr = num/1000000000d;
        suffix = "B";
    }
    return numStr.ToString() + suffix;
}

用途:

GoldDisplay.text = KMBMaker(gold);

更改:

  1. 显式使用double常量
  2. 删除重复
  3. 单独的关注点-此方法无需了解文本框

我不认为有内置的方法,所以我可能只是通过自己的方式重新发明了轮子,但这应该是我可能会做的

using System;
using System.Collections.Generic;
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            for (double i = 500d; i < 5e23; i *= 100d)
            {
                Console.WriteLine(i.ToMyNumber());
            }
            Console.Read();
        }
    }
    public static class helper
    {
        private static readonly  List<string> myNum;
        static helper()
        {
            myNum = new List<string>();
            myNum.Add("");
            myNum.Add("kilo");
            myNum.Add("mill");
            myNum.Add("bill");
            myNum.Add("tril");
            myNum.Add("quad");
            myNum.Add("quin");
            myNum.Add("sext");
            // ....
        }
        public static string ToMyNumber(this double value)
        {
            string initValue = value.ToString();
            int num = 0;
            while (value >= 1000d)
            {
                num++;
                value /= 1000d;
            }
            return string.Format("{0} {1} ({2})", value, myNum[num], initValue);
        }
    }
}

谁打印这个

500  (500)
50 kilo (50000)
5 mill (5000000)
500 mill (500000000)
50 bill (50000000000)
5 tril (5000000000000)
500 tril (500000000000000)
50 quad (5E+16)
5 quin (5E+18)
500 quin (5E+20)
50 sext (5E+22)

我在我的项目中使用这个方法,你也可以使用。也许还有更好的办法,我不知道。

public void KMBMaker( Text txt, double num )
    {
        if( num < 1000 )
        {
            double numStr = num;
            txt.text = numStr.ToString() + "";
        }
        else if( num < 1000000 )
        {
            double numStr = num/1000;
            txt.text = numStr.ToString() + "K";
        }
        else if( num < 1000000000 )
        {
            double numStr = num/1000000;
            txt.text = numStr.ToString() + "M";
        }
        else
        {
            double numStr = num/1000000000;
            txt.text = numStr.ToString() + "B";
        }
    }

并像这样在更新中使用此方法。

void Update()
{
     KMBMaker( GoldDisplay.text, gold );
}

我使用这个:

    private static List<string> nFormat= new List<string>();
        void Awake()
        {
         nFormat.Add("");
         nFormat.Add("K");
         nFormat.Add("M");
         nFormat.Add("B");
        //...
        }
        public static string Double2dec(double value)
        {
             int num = 0;
             while (value >= 1000d)
             {
                 num++;
                 value /= 1000d;
             }
             return value.ToString("F2") + nFormat[num];
        }

我尝试了这里给出的一些解决方案,但由于需要记下从K到NoNod的所有缩写,我被推迟了,所以我写了这篇文章——尽管我还没有尝试它是否会对性能产生很大影响(尽管它似乎像使用科学符号一样流畅)。

using System;
//System.Numerics necessary for us of BigInteger only - alternatively use double (which might be faster, but more inaccurate
using System.Numerics;
namespace WPF_Clicker
{
    public static class NumberFormatter
    {
        
        /*NumberFormat
         * Scientific   => 0.0e0 | example: 1.234e14    -> 123,400,000,000,000
         * Abbreviation  => 0.0xx | example: 123.4T      -> 123,400,000,000,000
        */
        public enum NumberFormat
        {
            Scientific,
            Abbreviation
        }
        
        public static string FormatNumber(BigInteger number, NumberFormat format = NumberFormat.Scientific)
        {
            if (format == NumberFormat.Scientific)
                return ScientificFomat(number);
            else
                return AbbreviationFormat(number);
        }
        public static string ScientificFomat(BigInteger number)
        {
            if (number < 1000)
                //if number smaller than 1,000, don't use special format
                return number.ToString("#.##0");
            else
                //return number as scientific notation with 1 place before and 3 places after decimal point
                return number.ToString("e3");
        }
        public static string AbbreviationFormat(BigInteger number)
        {
            if (number < 1000)
                //if number smaller than 1,000, don't use special format
                return number.ToString("#.##0");
            //get division of number (string length - 1) by 3 and get remainder -> appendix changes with every 4 characters
            int decider = Math.DivRem(number.ToString().Length - 1, 3, out int remainder) - 1;
            //if decider is bigger than 9, looping for every place of the decider number
            int declength = decider.ToString().Length;
            //string is necessary to decide on which appendix to use
            string decstring = decider.ToString();
            //string for the appendix
            string appendix = "";
            if (decider > 99)
                //return "infinity" if decider is greater than 99
                //can be changed if you decide to go over NoNod (decider > 99)
                return "infinity";
            else
            {
                //thousands, millions and billions are special cases
                if (decider < 3)
                {
                    if (decider == 0)
                        appendix = "K";
                    else if (decider == 1)
                        appendix = "M";
                    else if (decider == 2)
                        appendix = "B";
                    else
                        appendix = "";
                }
                else
                    //loop through for decider number string
                    //start at the last place, since these will be definite and it saves the check of whether there is more than 1 place in the decider number string
                    for (int counter = declength - 1; counter >= 0; counter--)
                    {
                        char decchar = decstring[counter];
                        //handle last place of decider number string
                        if (counter == declength - 1)
                            if (decchar == '1')
                                appendix = "U";
                            else if (decchar == '2')
                                appendix = "D";
                            else if (decchar == '3')
                                appendix = "T";
                            else if (decchar == '4')
                                appendix = "Qa";
                            else if (decchar == '5')
                                appendix = "Qi";
                            else if (decchar == '6')
                                appendix = "Sx";
                            else if (decchar == '7')
                                appendix = "Sp";
                            else if (decchar == '8')
                                appendix = "Oc";
                            else if (decchar == '9')
                                appendix = "No";
                            else
                                appendix = "";
                        else
                        //handles second place (or higher) of decider number string
                        {
                            if (decchar == '1')
                                appendix += "Dc";
                            else if (decchar == '2')
                                appendix += "Vg";
                            else if (decchar == '3')
                                appendix += "Td";
                            else if (decchar == '4')
                                appendix += "Qad";
                            else if (decchar == '5')
                                appendix += "Qid";
                            else if (decchar == '6')
                                appendix += "Sxd";
                            else if (decchar == '7')
                                appendix += "Spd";
                            else if (decchar == '8')
                                appendix += "Ocd";
                            else if (decchar == '9')
                                appendix += "Nod";
                        }
                    }
                //since the number string is at this point definitly more than 3 places long, use the remainder to set the decimal point
                string numberstr = number.ToString().Substring(0, 4).Insert(remainder + 1, ",");
                //put the number with decimal point together with the appendix | example: 123,456,789,012,345,678,901,234,567,890,123,456,789,012 -> 123,4DDc
                return numberstr + appendix;
            }
        }
    }
}

希望这能有所帮助。