基于Unity制作一个简易的计算器

 

一、前言

Hello,又见面了,今天分享如何使用Unity制作计算器,难度中等,可以用来学习,或者当成其他项目的小组件导入。

当然,也可以导出来,发布到网页端,来做一个嵌入式工具也可以。

 

二、效果图及源工程

效果图:

源工程

 

三、实现

1.界面搭建

所有的按钮摆放到Background下面。

2.代码实现

首先找到所有的按钮,添加到事件:

		//结果显示
      TextComputeProcess = GameObject.Find("Canvas/Background/Image/TextComputeProcess").GetComponent<Text>();
      TextComputeResult = GameObject.Find("Canvas/Background/Image/TextComputeResult").GetComponent<Text>();
      TextComputeResult.text = "0";
      RUNSTATE = 0;

      //操作
      BtnReset = GameObject.Find("Canvas/Background/重置").GetComponent<Button>();
      BtnReset.onClick.AddListener(() => OperationDispose("CE"));
      BtnDelete = GameObject.Find("Canvas/Background/删除").GetComponent<Button>();
      BtnDelete.onClick.AddListener(() => OperationDispose("Del"));

      //加减乘除
      BtnAdd = GameObject.Find("Canvas/Background/加").GetComponent<Button>();
      BtnAdd.onClick.AddListener(() => OperationDispose("+"));
      BtnSub = GameObject.Find("Canvas/Background/减").GetComponent<Button>();
      BtnSub.onClick.AddListener(() => OperationDispose("-"));
      BtnMul = GameObject.Find("Canvas/Background/乘").GetComponent<Button>();
      BtnMul.onClick.AddListener(() => OperationDispose("*"));
      BtnDiv = GameObject.Find("Canvas/Background/除").GetComponent<Button>();
      BtnDiv.onClick.AddListener(() => OperationDispose("/"));
      BtnEqual = GameObject.Find("Canvas/Background/等于").GetComponent<Button>();
      BtnEqual.onClick.AddListener(() => OperationDispose("="));

      //数字
      Btn0 = GameObject.Find("Canvas/Background/0").GetComponent<Button>();
      Btn0.onClick.AddListener(() => NumDispose("0"));
      Btn1 = GameObject.Find("Canvas/Background/1").GetComponent<Button>();
      Btn1.onClick.AddListener(() => NumDispose("1"));
      Btn2 = GameObject.Find("Canvas/Background/2").GetComponent<Button>();
      Btn2.onClick.AddListener(() => NumDispose("2"));
      Btn3 = GameObject.Find("Canvas/Background/3").GetComponent<Button>();
      Btn3.onClick.AddListener(() => NumDispose("3"));
      Btn4 = GameObject.Find("Canvas/Background/4").GetComponent<Button>();
      Btn4.onClick.AddListener(() => NumDispose("4"));
      Btn5 = GameObject.Find("Canvas/Background/5").GetComponent<Button>();
      Btn5.onClick.AddListener(() => NumDispose("5"));
      Btn6 = GameObject.Find("Canvas/Background/6").GetComponent<Button>();
      Btn6.onClick.AddListener(() => NumDispose("6"));
      Btn7 = GameObject.Find("Canvas/Background/7").GetComponent<Button>();
      Btn7.onClick.AddListener(() => NumDispose("7"));
      Btn8 = GameObject.Find("Canvas/Background/8").GetComponent<Button>();
      Btn8.onClick.AddListener(() => NumDispose("8"));
      Btn9 = GameObject.Find("Canvas/Background/9").GetComponent<Button>();
      Btn9.onClick.AddListener(() => NumDispose("9"));
      BtnPoint = GameObject.Find("Canvas/Background/点").GetComponent<Button>();
      BtnPoint.onClick.AddListener(() => NumDispose("."));
      BtnPm = GameObject.Find("Canvas/Background/正负").GetComponent<Button>();
      BtnPm.onClick.AddListener(() => NumDispose("-"));

按钮操作:

	//操作点击处理
  private void OperationDispose(string operation)
  {
      switch (operation)
      {
          case "+":
              if (RUNSTATE == 0)
                  TextComputeProcess.text = "0 + ";
              else
              {
                  TextComputeProcess.text = TextComputeResult.text + " + ";
                  m_operation = "+";
                  RUNSTATE = 2;
              }
              break;
          case "-":
              if (RUNSTATE == 0)
                  TextComputeProcess.text = "0 - ";
              else
              {
                  TextComputeProcess.text = TextComputeResult.text + " - ";
                  m_operation = "-";
                  RUNSTATE = 2;
              }
              break;
          case "*":
              if (RUNSTATE == 0)
                  TextComputeProcess.text = "0 * ";
              else
              {
                  TextComputeProcess.text = TextComputeResult.text + " * ";
                  m_operation = "*";
                  RUNSTATE = 2;
              }
              break;
          case "/":
              if (RUNSTATE == 0)
                  TextComputeProcess.text = "0 / ";
              else
              {
                  TextComputeProcess.text = TextComputeResult.text + " / ";
                  m_operation = "/";
                  RUNSTATE = 2;
              }
              break;
          case "=":
              if (RUNSTATE == 0)
                  TextComputeProcess.text = "0 = ";
              else
              {
                  if (RUNSTATE == 3)
                  {
                      double result;
                      switch (m_operation)
                      {
                          case "+":
                              result = double.Parse(calculateString) + double.Parse(TextComputeResult.text);
                              TextComputeProcess.text = calculateString + " + " + TextComputeResult.text + " = ";
                              TextComputeResult.text = result.ToString();
                              RUNSTATE = 4;
                              break;
                          case "-":
                              result = double.Parse(calculateString) - double.Parse(TextComputeResult.text);
                              TextComputeProcess.text = calculateString + " - " + TextComputeResult.text + " = ";
                              TextComputeResult.text = result.ToString();
                              RUNSTATE = 4;
                              break;
                          case "*":
                              result = double.Parse(calculateString) * double.Parse(TextComputeResult.text);
                              TextComputeProcess.text = calculateString + " * " + TextComputeResult.text + " = ";
                              TextComputeResult.text = result.ToString();
                              RUNSTATE = 4;
                              break;
                          case "/":
                              result = double.Parse(calculateString) / double.Parse(TextComputeResult.text);
                              TextComputeProcess.text = calculateString + " / " + TextComputeResult.text + " = ";
                              TextComputeResult.text = result.ToString();
                              RUNSTATE = 4;
                              break;
                          default:
                              break;
                      }
                  }
                  else
                  {
                      TextComputeProcess.text = TextComputeResult.text + " = ";
                  }
              }
              break;
          case "CE":
              TextComputeProcess.text = "";
              TextComputeResult.text = "0";
              RUNSTATE = 0;
              break;
          case "Del":
              if (RUNSTATE == 0)
                  return;
              else
              {
                  if (TextComputeResult.text.Length == 1)
                  {
                      TextComputeResult.text = "0";
                  }
                  else
                  {
                      TextComputeResult.text = TextComputeResult.text.Remove(TextComputeResult.text.Length - 1, 1);
                  }
              }
              break;
          default:
              break;
      }
  }

数字点击处理:

	//数字点击处理
  private void NumDispose(string num)
  {
      switch (num)
      {
          case ".":
              if (RUNSTATE == 0)
                  TextComputeResult.text = "0";
              else
                  TextComputeResult.text += num;
              break;
          case "-":
              if (RUNSTATE == 0)
                  TextComputeResult.text = "0";
              else
              {
                  if (RUNSTATE == 1)
                  {
                      if (pmState)
                      {
                          TextComputeResult.text = TextComputeResult.text.Remove(0, 1);
                          pmState = false;
                      }
                      else
                      {
                          TextComputeResult.text = num + TextComputeResult.text;
                          pmState = true;
                      }
                  }
                  else if (RUNSTATE == 2)
                  {
                      pmState = false;
                  }
                  else if (RUNSTATE == 3)
                  {
                      if (pmState)
                      {
                          TextComputeResult.text = TextComputeResult.text.Remove(0, 1);
                          pmState = false;
                      }
                      else
                      {
                          TextComputeResult.text = num + TextComputeResult.text;
                          pmState = true;
                      }
                  }
                  else if (RUNSTATE == 4)
                  {
                      pmState = false;
                      OperationDispose("CE");
                  }
              }
              break;
          default:
              if (RUNSTATE == 0)
              {
                  TextComputeResult.text = num;
                  RUNSTATE = 1;
              }
              else if (RUNSTATE == 1)
              {
                  pmState = false;
                  TextComputeResult.text += num;
              }
              else if (RUNSTATE == 2)
              {
                  calculateString = TextComputeResult.text;
                  TextComputeResult.text = "";
                  TextComputeResult.text += num;
                  RUNSTATE = 3;
              }
              else if (RUNSTATE == 3)
              {
                  TextComputeResult.text += num;
              }
              else if (RUNSTATE == 4)
              {
                  OperationDispose("CE");
                  TextComputeResult.text = num;
                  RUNSTATE = 1;
              }
              break;
      }
  }

完整代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class CalculatorControl : MonoBehaviour
{
  private Text TextComputeProcess;//计算过程
  private Text TextComputeResult;//计算结果

  private Button BtnReset;
  private Button BtnDelete;
  private Button BtnAdd;
  private Button BtnSub;
  private Button BtnMul;
  private Button BtnDiv;
  private Button BtnEqual;

  private Button Btn0, Btn1, Btn2, Btn3, Btn4, Btn5, Btn6, Btn7, Btn8, Btn9;
  private Button BtnPoint, BtnPm;

  private string calculateString = "";//计算数
  private string m_operation = "";//操作数
  private bool pmState = false;//正负状态
  private int RUNSTATE = 0;//0 默认 1 输入数字 2 输入操作符 3 输入操作符再输入数字 4 计算结果后

  void Start()
  {
      //结果显示
      TextComputeProcess = GameObject.Find("Canvas/Background/Image/TextComputeProcess").GetComponent<Text>();
      TextComputeResult = GameObject.Find("Canvas/Background/Image/TextComputeResult").GetComponent<Text>();
      TextComputeResult.text = "0";
      RUNSTATE = 0;

      //操作
      BtnReset = GameObject.Find("Canvas/Background/重置").GetComponent<Button>();
      BtnReset.onClick.AddListener(() => OperationDispose("CE"));
      BtnDelete = GameObject.Find("Canvas/Background/删除").GetComponent<Button>();
      BtnDelete.onClick.AddListener(() => OperationDispose("Del"));

      //加减乘除
      BtnAdd = GameObject.Find("Canvas/Background/加").GetComponent<Button>();
      BtnAdd.onClick.AddListener(() => OperationDispose("+"));
      BtnSub = GameObject.Find("Canvas/Background/减").GetComponent<Button>();
      BtnSub.onClick.AddListener(() => OperationDispose("-"));
      BtnMul = GameObject.Find("Canvas/Background/乘").GetComponent<Button>();
      BtnMul.onClick.AddListener(() => OperationDispose("*"));
      BtnDiv = GameObject.Find("Canvas/Background/除").GetComponent<Button>();
      BtnDiv.onClick.AddListener(() => OperationDispose("/"));
      BtnEqual = GameObject.Find("Canvas/Background/等于").GetComponent<Button>();
      BtnEqual.onClick.AddListener(() => OperationDispose("="));

      //数字
      Btn0 = GameObject.Find("Canvas/Background/0").GetComponent<Button>();
      Btn0.onClick.AddListener(() => NumDispose("0"));
      Btn1 = GameObject.Find("Canvas/Background/1").GetComponent<Button>();
      Btn1.onClick.AddListener(() => NumDispose("1"));
      Btn2 = GameObject.Find("Canvas/Background/2").GetComponent<Button>();
      Btn2.onClick.AddListener(() => NumDispose("2"));
      Btn3 = GameObject.Find("Canvas/Background/3").GetComponent<Button>();
      Btn3.onClick.AddListener(() => NumDispose("3"));
      Btn4 = GameObject.Find("Canvas/Background/4").GetComponent<Button>();
      Btn4.onClick.AddListener(() => NumDispose("4"));
      Btn5 = GameObject.Find("Canvas/Background/5").GetComponent<Button>();
      Btn5.onClick.AddListener(() => NumDispose("5"));
      Btn6 = GameObject.Find("Canvas/Background/6").GetComponent<Button>();
      Btn6.onClick.AddListener(() => NumDispose("6"));
      Btn7 = GameObject.Find("Canvas/Background/7").GetComponent<Button>();
      Btn7.onClick.AddListener(() => NumDispose("7"));
      Btn8 = GameObject.Find("Canvas/Background/8").GetComponent<Button>();
      Btn8.onClick.AddListener(() => NumDispose("8"));
      Btn9 = GameObject.Find("Canvas/Background/9").GetComponent<Button>();
      Btn9.onClick.AddListener(() => NumDispose("9"));
      BtnPoint = GameObject.Find("Canvas/Background/点").GetComponent<Button>();
      BtnPoint.onClick.AddListener(() => NumDispose("."));
      BtnPm = GameObject.Find("Canvas/Background/正负").GetComponent<Button>();
      BtnPm.onClick.AddListener(() => NumDispose("-"));
  }

  //操作点击处理
  private void OperationDispose(string operation)
  {
      switch (operation)
      {
          case "+":
              if (RUNSTATE == 0)
                  TextComputeProcess.text = "0 + ";
              else
              {
                  TextComputeProcess.text = TextComputeResult.text + " + ";
                  m_operation = "+";
                  RUNSTATE = 2;
              }
              break;
          case "-":
              if (RUNSTATE == 0)
                  TextComputeProcess.text = "0 - ";
              else
              {
                  TextComputeProcess.text = TextComputeResult.text + " - ";
                  m_operation = "-";
                  RUNSTATE = 2;
              }
              break;
          case "*":
              if (RUNSTATE == 0)
                  TextComputeProcess.text = "0 * ";
              else
              {
                  TextComputeProcess.text = TextComputeResult.text + " * ";
                  m_operation = "*";
                  RUNSTATE = 2;
              }
              break;
          case "/":
              if (RUNSTATE == 0)
                  TextComputeProcess.text = "0 / ";
              else
              {
                  TextComputeProcess.text = TextComputeResult.text + " / ";
                  m_operation = "/";
                  RUNSTATE = 2;
              }
              break;
          case "=":
              if (RUNSTATE == 0)
                  TextComputeProcess.text = "0 = ";
              else
              {
                  if (RUNSTATE == 3)
                  {
                      double result;
                      switch (m_operation)
                      {
                          case "+":
                              result = double.Parse(calculateString) + double.Parse(TextComputeResult.text);
                              TextComputeProcess.text = calculateString + " + " + TextComputeResult.text + " = ";
                              TextComputeResult.text = result.ToString();
                              RUNSTATE = 4;
                              break;
                          case "-":
                              result = double.Parse(calculateString) - double.Parse(TextComputeResult.text);
                              TextComputeProcess.text = calculateString + " - " + TextComputeResult.text + " = ";
                              TextComputeResult.text = result.ToString();
                              RUNSTATE = 4;
                              break;
                          case "*":
                              result = double.Parse(calculateString) * double.Parse(TextComputeResult.text);
                              TextComputeProcess.text = calculateString + " * " + TextComputeResult.text + " = ";
                              TextComputeResult.text = result.ToString();
                              RUNSTATE = 4;
                              break;
                          case "/":
                              result = double.Parse(calculateString) / double.Parse(TextComputeResult.text);
                              TextComputeProcess.text = calculateString + " / " + TextComputeResult.text + " = ";
                              TextComputeResult.text = result.ToString();
                              RUNSTATE = 4;
                              break;
                          default:
                              break;
                      }
                  }
                  else
                  {
                      TextComputeProcess.text = TextComputeResult.text + " = ";
                  }
              }
              break;
          case "CE":
              TextComputeProcess.text = "";
              TextComputeResult.text = "0";
              RUNSTATE = 0;
              break;
          case "Del":
              if (RUNSTATE == 0)
                  return;
              else
              {
                  if (TextComputeResult.text.Length == 1)
                  {
                      TextComputeResult.text = "0";
                  }
                  else
                  {
                      TextComputeResult.text = TextComputeResult.text.Remove(TextComputeResult.text.Length - 1, 1);
                  }
              }
              break;
          default:
              break;
      }
  }

  //数字点击处理
  private void NumDispose(string num)
  {
      switch (num)
      {
          case ".":
              if (RUNSTATE == 0)
                  TextComputeResult.text = "0";
              else
                  TextComputeResult.text += num;
              break;
          case "-":
              if (RUNSTATE == 0)
                  TextComputeResult.text = "0";
              else
              {
                  if (RUNSTATE == 1)
                  {
                      if (pmState)
                      {
                          TextComputeResult.text = TextComputeResult.text.Remove(0, 1);
                          pmState = false;
                      }
                      else
                      {
                          TextComputeResult.text = num + TextComputeResult.text;
                          pmState = true;
                      }
                  }
                  else if (RUNSTATE == 2)
                  {
                      pmState = false;
                  }
                  else if (RUNSTATE == 3)
                  {
                      if (pmState)
                      {
                          TextComputeResult.text = TextComputeResult.text.Remove(0, 1);
                          pmState = false;
                      }
                      else
                      {
                          TextComputeResult.text = num + TextComputeResult.text;
                          pmState = true;
                      }
                  }
                  else if (RUNSTATE == 4)
                  {
                      pmState = false;
                      OperationDispose("CE");
                  }
              }
              break;
          default:
              if (RUNSTATE == 0)
              {
                  TextComputeResult.text = num;
                  RUNSTATE = 1;
              }
              else if (RUNSTATE == 1)
              {
                  pmState = false;
                  TextComputeResult.text += num;
              }
              else if (RUNSTATE == 2)
              {
                  calculateString = TextComputeResult.text;
                  TextComputeResult.text = "";
                  TextComputeResult.text += num;
                  RUNSTATE = 3;
              }
              else if (RUNSTATE == 3)
              {
                  TextComputeResult.text += num;
              }
              else if (RUNSTATE == 4)
              {
                  OperationDispose("CE");
                  TextComputeResult.text = num;
                  RUNSTATE = 1;
              }
              break;
      }
  }
}

效果图如下:

 

四、后记

完整代码278行,还是依旧那么简练,整体代码难度不大,主要是状态之间的切换:

1、输入数字的状态

2、输入操作符状态

3、输入操作符后再输入数字状态

4、计算结果后状态

理解这些状态后,代码就容易理解了。

最后,拓展一下,将其他大佬写的代码给大家看一下,大家如果觉得上面的代码太简单,可以看一下:

代码使用OnGUI搭建界面,直接拖到任意对象上就可以看到效果了:

using UnityEngine;
using System.Text.RegularExpressions;
using System;

public class Calculator2 : MonoBehaviour
{
  public static bool IsNumeric(string value)
  {
      return Regex.IsMatch(value, @"^[+-]?\d*[.]?\d*$");
  }
  
  public string result = "";//用来显示结果
  public static string str1 = "";//第一个操作数
  public static bool haveDot = false;//第二个操作数
  public static bool isCaclutate = false;


  void OnGUI()
  {
      //对数字进行处理
      if (GUI.Button(new Rect(100, 100, 100, 60), "CE"))
      {
          result = "";
          str1 = "";
          haveDot = false;
      }
      if (GUI.Button(new Rect(210, 100, 100, 60), "×") && str1.Substring(str1.Length - 1, 1) != "-" && str1.Substring(str1.Length - 1, 1) != "+" && str1.Substring(str1.Length - 1, 1) != ".")
      {
          if (IsNumeric(str1.Substring(str1.Length - 1, 1)))
          {
              Debug.Log(str1.Substring(str1.Length - 1, 1));
              str1 += "*";
              haveDot = false;
              isCaclutate = false;
          }
          result = str1;
      }
      if (GUI.Button(new Rect(320, 100, 100, 60), "÷") && str1.Substring(str1.Length - 1, 1) != "-" && str1.Substring(str1.Length - 1, 1) != "+" && str1.Substring(str1.Length - 1, 1) != ".")
      {
          if (IsNumeric(str1.Substring(str1.Length - 1, 1)))
          {
              str1 += "/";
              haveDot = false;
              isCaclutate = false;
          }
          result = str1;
      }
      if (GUI.Button(new Rect(430, 100, 100, 60), "←"))
      {
          if (isCaclutate == true)
          {
              str1 = "";
              isCaclutate = false;
          }
          else if (result.Length != 0)
          {
              str1 = str1.Substring(0, str1.Length - 1);
          }
          result = str1;
      }
      if (GUI.Button(new Rect(100, 170, 100, 60), "1"))
      {
          if (isCaclutate == true)
          {
              str1 = "";
              isCaclutate = false;
              haveDot = false;
          }
          str1 += "1";
          result = str1;
      }
      if (GUI.Button(new Rect(210, 170, 100, 60), "2"))
      {
          if (isCaclutate == true)
          {
              str1 = "";
              isCaclutate = false;
              haveDot = false;
          }
          str1 += "2";
          result = str1;
      }
      if (GUI.Button(new Rect(320, 170, 100, 60), "3"))
      {
          if (isCaclutate == true)
          {
              str1 = "";
              isCaclutate = false;
              haveDot = false;
          }
          str1 += "3";
          result = str1;
      }
      if (GUI.Button(new Rect(430, 170, 100, 60), "-"))
      {
          if (IsNumeric(str1.Substring(str1.Length - 1, 1)) && str1.Substring(str1.Length - 1, 1) != "-" && str1.Substring(str1.Length - 1, 1) != "+" && str1.Substring(str1.Length - 1, 1) != ".")
          {
              str1 += "-";
              haveDot = false;
              isCaclutate = false;
          }
          result = str1;
      }
      if (GUI.Button(new Rect(100, 240, 100, 60), "4"))
      {
          if (isCaclutate == true)
          {
              str1 = "";
              isCaclutate = false;
              haveDot = false;
          }
          str1 += "4";
          result = str1;
      }
      if (GUI.Button(new Rect(210, 240, 100, 60), "5"))
      {
          if (isCaclutate == true)
          {
              str1 = "";
              isCaclutate = false;
              haveDot = false;
          }
          str1 += "5";
          result = str1;
      }
      if (GUI.Button(new Rect(320, 240, 100, 60), "6"))
      {
          if (isCaclutate == true)
          {
              str1 = "";
              isCaclutate = false;
              haveDot = false;
          }
          str1 += "6";
          result = str1;
      }
      if (GUI.Button(new Rect(430, 240, 100, 60), "+") && str1.Substring(str1.Length - 1, 1) != "+" && str1.Substring(str1.Length - 1, 1) != "-" && str1.Substring(str1.Length - 1, 1) != ".")
      {
          if (IsNumeric(str1.Substring(str1.Length - 1, 1)))
          {
              str1 += "+";
              haveDot = false;
              isCaclutate = false;
          }
          result = str1;
      }
      if (GUI.Button(new Rect(100, 310, 100, 60), "7"))
      {
          if (isCaclutate == true)
          {
              str1 = "";
              isCaclutate = false;
              haveDot = false;
          }
          str1 += "7";
          result = str1;
      }
      if (GUI.Button(new Rect(210, 310, 100, 60), "8"))
      {
          if (isCaclutate == true)
          {
              str1 = "";
              isCaclutate = false;
              haveDot = false;
          }
          str1 += "8";
          result = str1;
      }
      if (GUI.Button(new Rect(320, 310, 100, 60), "9"))
      {
          if (isCaclutate == true)
          {
              str1 = "";
              isCaclutate = false;
              haveDot = false;
          }
          str1 += "9";
          result = str1;
      }
      if (GUI.Button(new Rect(430, 310, 100, 130), "="))
      {

          var tmp = Evaluator.Eval(result);
          Debug.Log(tmp.ToString());
          result = tmp.ToString();
          str1 = result;
          isCaclutate = true;
          if (result.Contains("."))
          {
              haveDot = true;
          }
      }
      if (GUI.Button(new Rect(100, 380, 210, 60), "0"))
      {
          if (isCaclutate == true)
          {
              str1 = "";
              isCaclutate = false;
              haveDot = false;
          }
          str1 += "0";
          result = str1;
      }

      if (GUI.Button(new Rect(320, 380, 100, 60), "."))
      {
          if (isCaclutate == true)
          {
              str1 = "0.";
              isCaclutate = false;
          }
          if (IsNumeric(str1.Substring(str1.Length - 1, 1)) && str1.Substring(str1.Length - 1, 1) != "." && haveDot == false)
          {
              Debug.Log(str1.Substring(str1.Length - 1, 1));
              str1 += ".";
              haveDot = true;
              isCaclutate = false;
          }
          result = str1;
      }
      GUI.TextArea(new Rect(100, 20, 430, 60), result);
  }

  /**/
  /// <summary>
  /// 动态求值
  /// </summary>
  public class Evaluator
  {
      /**/
      /// <summary>
      /// 计算结果,如果表达式出错则抛出异常
      /// </summary>
      /// <param name="statement">表达式,如"1+2+3+4"</param>
      /// <returns>结果</returns>
      public static object Eval(string statement)
      {
          if (statement.Trim() != string.Empty)
          {
              Evaluator evaluator = new Evaluator();
              return evaluator.GetFormulaResult(statement);
          }
          else
          {
              return null;
          }
      }


      private object GetFormulaResult(string s)
      {
          if (s == "")
          {
              return null;
          }
          string S = BuildingRPN(s);

          string tmp = "";
          System.Collections.Stack sk = new System.Collections.Stack();

          char c = ' ';
          System.Text.StringBuilder Operand = new System.Text.StringBuilder();
          double x, y;
          for (int i = 0; i < S.Length; i++)
          {
              c = S[i];
              //added c==',' for germany culture
              if (char.IsDigit(c) || c == '.' || c == ',')
              {
                  //数据值收集.
                  Operand.Append(c);
              }
              else if (c == ' ' && Operand.Length > 0)
              {
                  #region 运算数转换
                  try
                  {
                      tmp = Operand.ToString();
                      if (tmp.StartsWith("-"))//负数的转换一定要小心...它不被直接支持.
                      {
                          //现在我的算法里这个分支可能永远不会被执行.
                          sk.Push(-((double)Convert.ToDouble(tmp.Substring(1, tmp.Length - 1))));
                      }
                      else
                      {
                          sk.Push(Convert.ToDouble(tmp));
                      }
                  }
                  catch
                  {
                      return null; //
                  }
                  Operand = new System.Text.StringBuilder();
                  #endregion
              }
              else if (c == '+'//运算符处理.双目运算处理.
                  || c == '-'
                  || c == '*'
                  || c == '/'
                  || c == '%'
                  || c == '^')
              {
                  #region 双目运算
                  if (sk.Count > 0)/*如果输入的表达式根本没有包含运算符.或是根本就是空串.这里的逻辑就有意义了.*/
                  {
                      y = (double)sk.Pop();
                  }
                  else
                  {
                      sk.Push(0);
                      break;
                  }
                  if (sk.Count > 0)
                      x = (double)sk.Pop();
                  else
                  {
                      sk.Push(y);
                      break;
                  }
                  switch (c)
                  {
                      case '+':
                          sk.Push(x + y);
                          break;
                      case '-':
                          sk.Push(x - y);
                          break;
                      case '*':
                          if (y == 0)
                          {
                              sk.Push(x * 1);
                          }
                          else
                          {
                              sk.Push(x * y);
                          }
                          break;
                      case '/':
                          if (y == 0)
                          {
                              sk.Push(x / 0);
                          }
                          else
                          {
                              sk.Push(x / y);
                          }
                          break;
                      case '%':
                          sk.Push(x % y);
                          break;
                      case '^'://
                          if (x > 0)//
                          {
                              //我原本还想,如果被计算的数是负数,又要开真分数次方时如何处理的问题.后来我想还是算了吧.
                              sk.Push(System.Math.Pow(x, y));
                              //
                          }
                          //
                          else//
                          {
                              //
                              double t = y;
                              //
                              string ts = "";
                              //
                              t = 1 / (2 * t);
                              //
                              ts = t.ToString();
                              //
                              if (ts.ToUpper().LastIndexOf('E') > 0)//
                              {
                                  //
                                  ;
                                  //
                              }
                              //
                          }
                          break;
                  }
                  #endregion
              }
              else if (c == '!')//单目取反. )
              {
                  sk.Push(-((double)sk.Pop()));
              }
          }
          if (sk.Count > 1)
          {
              return null;//;
          }
          if (sk.Count == 0)
          {
              return null;//;
          }
          return sk.Pop();
      }
      /**/
      /// <summary>
      /// 
      /// </summary>
      private string BuildingRPN(string s)
      {
          System.Text.StringBuilder sb = new System.Text.StringBuilder(s);
          System.Collections.Stack sk = new System.Collections.Stack();
          System.Text.StringBuilder re = new System.Text.StringBuilder();

          char c = ' ';
          //sb.Replace( " ","" );
          //一开始,我只去掉了空格.后来我不想不支持函数和常量能滤掉的全OUT掉.
          for (int i = 0; i < sb.Length; i++)
          {
              c = sb[i];
              //added c==',' for german culture
              if (char.IsDigit(c) || c == ',')//数字当然要了.
                  re.Append(c);
              //if( char.IsWhiteSpace( c )||
              char.IsLetter(c);//如果是空白,那么不要.现在字母也不要.
              //continue;
              switch (c)//如果是其它字符...列出的要,没有列出的不要.
              {
                  case '+':
                  case '-':
                  case '*':
                  case '/':
                  case '%':
                  case '^':
                  case '!':
                  case '(':
                  case ')':
                  case '.':
                      re.Append(c);
                      break;
                  default:
                      continue;
              }
          }
          sb = new System.Text.StringBuilder(re.ToString());
          #region 对负号进行预转义处理.负号变单目运算符求反.
          for (int i = 0; i < sb.Length - 1; i++)
              if (sb[i] == '-' && (i == 0 || sb[i - 1] == '('))
                  sb[i] = '!';
          //字符转义.
          #endregion
          #region 将中缀表达式变为后缀表达式.
          re = new System.Text.StringBuilder();
          for (int i = 0;
              i < sb.Length;
              i++)
          {
              if (char.IsDigit(sb[i]) || sb[i] == '.')//如果是数值.
              {
                  re.Append(sb[i]);
                  //加入后缀式
              }
              else if (sb[i] == '+'
                  || sb[i] == '-'
                  || sb[i] == '*'
                  || sb[i] == '/'
                  || sb[i] == '%'
                  || sb[i] == '^'
                  || sb[i] == '!')//.
              {
                  #region 运算符处理
                  while (sk.Count > 0) //栈不为空时
                  {
                      c = (char)sk.Pop();
                      //将栈中的操作符弹出.
                      if (c == '(') //如果发现左括号.停.
                      {
                          sk.Push(c);
                          //将弹出的左括号压回.因为还有右括号要和它匹配.
                          break;
                          //中断.
                      }
                      else
                      {
                          if (Power(c) < Power(sb[i]))//如果优先级比上次的高,则压栈.
                          {
                              sk.Push(c);
                              break;
                          }
                          else
                          {
                              re.Append(' ');
                              re.Append(c);
                          }
                          //如果不是左括号,那么将操作符加入后缀式中.
                      }
                  }
                  sk.Push(sb[i]);
                  //把新操作符入栈.
                  re.Append(' ');
                  #endregion
              }
              else if (sb[i] == '(')//基本优先级提升
              {
                  sk.Push('(');
                  re.Append(' ');
              }
              else if (sb[i] == ')')//基本优先级下调
              {
                  while (sk.Count > 0) //栈不为空时
                  {
                      c = (char)sk.Pop();
                      //pop Operator
                      if (c != '(')
                      {
                          re.Append(' ');
                          re.Append(c);
                          //加入空格主要是为了防止不相干的数据相临产生解析错误.
                          re.Append(' ');
                      }
                      else
                          break;
                  }
              }
              else
                  re.Append(sb[i]);
          }
          while (sk.Count > 0)//这是最后一个弹栈啦.
          {
              re.Append(' ');
              re.Append(sk.Pop());
          }
          #endregion
          re.Append(' ');
          return FormatSpace(re.ToString());
          //在这里进行一次表达式格式化.这里就是后缀式了.  
      }

      /// <summary>  
      /// 优先级别测试函数.  
      /// </summary>  
      /// <param name="opr"></param>  
      /// <returns></returns>  
      private static int Power(char opr)
      {
          switch (opr)
          {
              case '+':
              case '-':
                  return 1;
              case '*':
              case '/':
                  return 2;
              case '%':
              case '^':
              case '!':
                  return 3;
              default:
                  return 0;
          }
      }

      /// <summary>  
      /// 规范化逆波兰表达式.
      /// </summary>  
      /// <param name="s"></param>  
      /// <returns></returns>  
      private static string FormatSpace(string s)
      {
          System.Text.StringBuilder ret = new System.Text.StringBuilder();
          for (int i = 0; i < s.Length; i++)
          {
              if (!(s.Length > i + 1 && s[i] == ' ' && s[i + 1] == ' '))
                  ret.Append(s[i]);
              else
                  ret.Append(s[i]);
          }
          return ret.ToString();
          //.Replace( '!','-' );
      }
  }
}

关于基于Unity制作一个简易的计算器的文章就介绍至此,更多相关Unity计算器内容请搜索编程教程以前的文章,希望以后支持编程教程

 二倍均值法(公平版)发出一个固定金额的红包,由若干个人来抢,需要满足哪些规则?1.所有人抢到金额之和等于红包金额,不能超过,也不能少于。2.每个人至少抢到一分钱。3.要保证所有人抢到金额的几率相等。 ...